Build and Push Docker Images / Build and Push Docker Images (push) Failing after 8s
7.2 KiB
7.2 KiB
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 thesigninflow.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 untilisAuthenticated()passes; else redirects to signin withcallbackUrl. Replaces old next-auth middleware.account-popver.tsx(client) — header account menu. ReadsuserAtom; 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 inNuqsAdapter.
Devices
devices-table.tsx(server) — desktop table + mobile cards of the user's devices; pagination; respectsparentalControland admin flags; fetchesgetDevices().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 indeviceCartAtom; 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 vianuqs.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. CallsblockDeviceAction.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 onmismatch_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).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 → URLqueryparam.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
useActionStatewith a{ message, success, fieldErrors }shape; client validation viareact-hook-form+zod. - Data: reads currently go through server components/queries; mutations through server actions. React Query provider is mounted but no
useQuery/useMutationyet — the port will move reads/mutations onto React Query + the clientapi-client. - State: global UI state via Jotai atoms (see user-flows-and-state.md).