Skip to content

← Back to DWS Receipts

UI built with shadcn/ui (52 components) plus 12 custom app components.

All in components/ui/

ComponentPurpose
button.tsxButtons with variants
input.tsxText input
textarea.tsxMulti-line input
checkbox.tsxCheckbox
switch.tsxToggle switch
select.tsxDropdown select
calendar.tsxDate picker
input-otp.tsxOTP code input
ComponentPurpose
card.tsxCard container
table.tsxData table
tabs.tsxTab navigation
separator.tsxDivider
scroll-area.tsxScrollable area
aspect-ratio.tsxAspect ratio container
ComponentPurpose
dialog.tsxModal dialog (desktop)
drawer.tsxBottom sheet (mobile)
alert-dialog.tsxConfirmation dialog
popover.tsxPopover overlay
tooltip.tsxTooltip
sheet.tsxSide panel
ComponentPurpose
dropdown-menu.tsxDropdown menu
pagination.tsxPagination controls
breadcrumb.tsxBreadcrumb nav
ComponentPurpose
badge.tsxStatus badge
alert.tsxAlert message
sonner.tsxToast notifications
skeleton.tsxLoading skeleton
progress.tsxProgress bar
HookPurpose
use-toast.tsToast state
use-mobile.tsxMobile detection
ComponentPurpose
receipt-dashboard.tsxAdmin dashboard view
receipt-table.tsxAdmin receipt table
employee-receipt-table.tsxEmployee receipt table
receipt-uploader.tsxUpload + OCR flow
receipt-details-card.tsxEdit/confirm form
ComponentPurpose
batch-review-dashboard.tsxBatch approval UI
ComponentPurpose
user-management-dashboard.tsxUser admin view
user-table.tsxUser list table
user-form-modal.tsxCreate/edit user
ban-user-dialog.tsxBan confirmation
ComponentPurpose
date-range-picker.tsxDate range selection
providers/query-provider.tsxReact Query provider

Mobile uses Drawer (bottom sheet), desktop uses Dialog (centered modal).

{isMobile ? (
<Drawer open={open} onOpenChange={setOpen}>
<DrawerContent>
<ReceiptDetailsCard ... />
</DrawerContent>
</Drawer>
) : (
<Dialog open={open} onOpenChange={setOpen}>
<DialogContent>
<ReceiptDetailsCard ... />
</DialogContent>
</Dialog>
)}

Used in: receipt-uploader.tsx, employee-receipt-table.tsx

// Font size
className="text-xs sm:text-sm"
// Padding
className="px-1.5 sm:px-2"
// Icon size
<Icon size={isMobile ? 14 : 16} />

Mobile uses native <input type="date"> for better UX:

{isMobile ? (
<input type="date" value={format(date, 'yyyy-MM-dd')} ... />
) : (
<Popover>
<Calendar ... />
</Popover>
)}

App uses dark theme throughout.

Background: bg-[#222222] Cards: bg-[#2e2e2e] Borders: border-[#444444]

Status badge colors use dark variants:

  • Pending: bg-yellow-900/30 text-yellow-300
  • Approved: bg-green-900/30 text-green-300
  • Rejected: bg-red-900/30 text-red-300
  • Reimbursed: bg-blue-900/30 text-blue-300