# Components Catalog of `components/` by feature area. `components/ui/*` are shadcn/ui + Radix primitives (listed last). "Server" = React Server Component today; most will become client components in the static build. ## Auth (`components/auth/`) - **`login-form.tsx`** (client) — phone-number login entry. `PhoneInput` + Login button; drives the `signin` flow. - **`signup-form.tsx`** (client) — full registration form: name, ID card, atoll/island (atolls fetched, islands derived from atoll), address, DOB, account no, phone, terms/policy. Two-column (branding + form). Field-level validation. - **`verify-otp-form.tsx`** (client) — login OTP entry. 6-digit input → `POST /callback/auth/` → `setAuth()` (localStorage) → redirect. Toasts on error. - **`verify-registration-otp-form.tsx`** (client) — registration OTP entry (server action). - **`route-guard.tsx`** (client) — auth gate for the dashboard. Renders nothing until `isAuthenticated()` passes; else redirects to signin with `callbackUrl`. Replaces old next-auth middleware. - **`account-popver.tsx`** (client) — header account menu. Reads `userAtom`; shows name/ID/phone; Logout (backend logout + `clearAuth()`) and View Profile. - **`application-layout.tsx`** (client) — the authenticated app shell: `SidebarProvider` + `AppSidebar` + sticky header (wallet, theme toggle, account popover) + `WelcomeBanner` + `DeviceCartDrawer` + main content in `NuqsAdapter`. ## Devices - **`devices-table.tsx`** (server) — desktop table + mobile cards of the user's devices; pagination; respects `parentalControl` and admin flags; fetches `getDevices()`. - **`device-card.tsx`** (client) — mobile device card: name, MAC/vendor badges, active/inactive, expiry, pending-payment indicator, blocked reason. Toggles cart selection. - **`add-devices-to-cart-button.tsx`** (client) — styled checkbox toggling a device in `deviceCartAtom`; disabled if active/blocked/pending. - **`device-cart.tsx`** (client) — floating sticky "Pay N device(s)" / Cancel banner; hidden when empty or on payment pages; routes to `/devices-to-pay`. - **`devices-to-pay.tsx`** (client) — pick number of months → `createPayment` → redirect to payment detail. Also renders bank details + pay-with-wallet / I-have-paid on the payment page. - **`devices-for-payment.tsx`** (client) — confirm selected devices + months, submit payment. - **`devices/device-filter.tsx`** (client) — advanced device filter drawer (name/MAC/vendor) with active-filter chips via `nuqs`. - **`how-to-get-mac.tsx`** — help accordion: how to find a MAC address per device type; support phone. - **`block-device-dialog.tsx`** (client) — block/unblock. Parental mode = simple block/unblock; admin mode = dialog with reason. Calls `blockDeviceAction`. - **`device-table-skeleton.tsx`** — loading skeleton. ## Payments / billing - **`payments-table.tsx`** (server) — user subscriptions; desktop table + `MobilePaymentDetails`; status/row color coding; device list per row; `getPayments()`. - **`topups-table.tsx`** (server) — user top-ups; table + `MobileTopupDetails`. - **`topup-to-pay.tsx`** (client) — topup detail + bank info + "I have paid" → `verifyTopupPayment`. - **`account-information.tsx`** (client) — bank account name/number with copy-to-clipboard. - **`billing/cancel-payment-button.tsx`** (client) — cancel unpaid payment → `cancelPayment`. - **`billing/cancel-topup-button.tsx`** (client) — cancel unpaid topup → `cancelTopup`. - **`billing/expiry-time-countdown.tsx`** (client) — 1s countdown + progress bar for unpaid items; redirects on expiry. ## Wallet - **`wallet.tsx`** (client) — header wallet-balance button; opens top-up drawer (`NumberInput`, max 5000) → `createTopup` → redirect to topup detail. Hidden on payment pages. - **`wallet-transactions-table.tsx`** (server) — transaction history; Total Debit/Credit summary boxes; table + `MobileTransactionDetails`; links to related payment/topup. ## Admin (`components/admin/`) - **`admin-devices-table.tsx`** (server) — all devices; user column; block/unblock; `getDevices(..., true)`. - **`admin-topup-form.tsx`** (client) — manual wallet credit dialog → `adminUserTopup`. - **`admin-topup-table.tsx`** (server) — all top-ups. - **`user-payments-table.tsx`** (server) — all payments; status/method/MIB ref columns. ## User management (`components/user/`) - **`add-device-dialog.tsx`** (client) — add device (name + MAC) with MAC help accordion → `addDeviceAction`. - **`user-agreement-form.tsx`** (client) — upload/replace agreement PDF → `updateUserAgreement`. - **`user-update-form.tsx`** (client) — edit user info (ID card, name, address, DOB, mobile) → `updateUser`. - **`user-verify-dialog.tsx`** (client) — admin verify; warns on `mismatch_fields` → `verifyUser`. - **`user-reject-dialog.tsx`** (client) — admin reject with reason → `rejectUser`. - **`user-table.tsx`** (server) — all users; verified/unverified badges; Details link. ## Layout / navigation - **`ui/app-sidebar.tsx`** (client) — the sidebar (see [navigation.md](./navigation.md)). - **`welcome-banner.tsx`** (client) — animated greeting, auto-hides after 4s (Framer Motion). - **`theme-toggle.tsx`** (client) — Light/Dark/System (`next-themes`). ## Shared / utility - **`pagination.tsx`** (client) — page controls preserving query params; hidden if ≤1 page. - **`clickable-row.tsx`** (client) — table row with cart toggle + status. - **`search.tsx`** (client) — debounced search → URL `query` param. - **`filter.tsx`** (client) — status select → URL param. - **`generic-filter.tsx`** (client) — reusable filter drawer + chips. - **`number-input.tsx`** — React Aria numeric input with +/- and max. - **`agreement-card.tsx`** — agreement display + View button. - **`price-calculator.tsx`** (client) — pricing formula tool (Jotai-backed inputs). - **`full-page-loader.tsx`** — full-screen spinner. - **`client-error-message.tsx`** — permission/error message with support contact. - **`input-read-only.tsx`**, **`ui/floating-label.tsx`** — read-only/labeled inputs. ## UI primitives (`components/ui/`) shadcn/ui (`new-york`) + Radix. No product logic. Grouped: - **Inputs:** input, textarea, label, form, floating-label, phone-input, input-otp, number-field, select, checkbox, radio-group, switch, toggle(+group), slider, dual-range-slider, calendar, datepicker. - **Layout:** card, separator, scroll-area, sidebar, resizable, aspect-ratio, collapsible. - **Overlays:** dialog, drawer, sheet, alert-dialog, popover, hover-card, tooltip. - **Data display:** table, badge, progress, accordion, tabs, breadcrumb, pagination, avatar, carousel, text-shimmer, skeleton. - **Menus:** dropdown-menu, context-menu, command, navigation-menu, menubar. - **Feedback:** button, alert, sonner (toasts), search-form. ## Conventions - **Forms:** server-action forms use `useActionState` with a `{ message, success, fieldErrors }` shape; client validation via `react-hook-form` + `zod`. - **Data:** reads currently go through server components/queries; mutations through server actions. React Query provider is mounted but **no `useQuery`/`useMutation` yet** — the port will move reads/mutations onto React Query + the client `api-client`. - **State:** global UI state via Jotai atoms (see [user-flows-and-state.md](./user-flows-and-state.md)).