Skip to content

← Back to DWS Receipts

Employees access /employee to submit receipts via mobile-first interface with camera integration and OCR auto-fill.

Employee Dashboard

Mobile: “Take Photo” button triggers native camera or photo library

Desktop: “Upload Receipt” button opens file picker

Supported formats: JPEG, PNG, WebP, HEIC, PDF

Selected → Validated → Uploaded to temp → OCR called

Size limits:

  • Mobile: 50 MB
  • Desktop: 10 MB

AI extracts:

  • Date: Purchase date in YYYY-MM-DD format
  • Amount: Total including tax/tip
  • Category: Parking, Gas, Meals & Entertainment, Office Supplies, Other

If ALL conditions met:

  • ✅ Date extracted
  • ✅ Amount extracted
  • ✅ Category resolved to ID
  • ✅ No duplicate found

→ Auto-submits with success toast (includes “Tap to edit” link)

Otherwise → Opens confirmation form for manual entry.

User reviews and can edit:

  • Date (native date picker on mobile, calendar on desktop)
  • Amount
  • Category (dropdown)
  • Notes/Description
Edit Receipt Form

Duplicate warning if matching date+amount exists.

// Combines screen size + user agent
const isMobile = window.innerWidth < 768 || /iPhone|iPad|Android/.test(userAgent);

Mobile file input includes HEIC for iOS:

<input type="file" accept="image/heic,image/jpeg,image/png,..." />
ComponentMobileDesktop
Receipt formBottom drawerCenter dialog
Date pickerNative <input type="date">Calendar popover
Table texttext-xstext-sm
Icons14px16px

Distinguishes camera capture vs file selection:

  • “Photo captured successfully” - recent file (< 30 sec) with camera name pattern
  • “File selected successfully” - older file
ColumnMobileDesktop
DateM/D/YYFull date
Amount$XX.XX$XX.XX
StatusBadgeBadge
ActionsView, EditView, Edit
StatusColor
PendingYellow
ApprovedGreen
RejectedRed
ReimbursedBlue

Dropdown with options: All, Pending, Approved, Rejected, Reimbursed

  • 10 items per page
  • Smart ellipsis (shows first, last, current ± 1)

Employees can only edit their own pending receipts.

Attempting to edit processed receipt shows:

“This receipt has been [status]. Please contact a system administrator.”

FilePurpose
app/employee/page.tsxEmployee portal
components/receipt-uploader.tsxUpload + OCR flow
components/employee-receipt-table.tsxReceipt list
components/receipt-details-card.tsxEdit form
hooks/use-mobile.tsxMobile detection
lib/phone.tsPhone formatting
  • File too large → Toast with size limit
  • Invalid type → Platform-specific guidance (camera/library vs camera/gallery)
  • Upload failed → Shows error, clears state
  • Extraction fails → Opens form for manual entry
  • Partial extraction → Shows form with available fields pre-filled
  • Update failed → Toast with error message
  • 403 error → Shows “Contact Admin” dialog

On form submit:

  1. Checks for existing receipt with same date + amount
  2. If found, compares notes/description
  3. If description matches or both empty → Blocks with warning
  4. If description differs → Allows submission

First login without profile creates default:

{
user_id: session.user.id,
role: 'employee',
full_name: session.user.phone // Placeholder
}