# UI / UX Rules

These rules freeze the approved UI behavior for ALLA OS and CRM-facing work.

Future UI should reuse existing dashboard patterns rather than introducing a parallel visual system.

## UX.1 Thai CRM Terminology

- `docs/business/crm-terminology.md` is the source of truth for CRM business labels.
- Use `src/features/crm/shared/terminology.ts` when CRM UI needs shared stage or role labels.
- Keep `CRM` and `Dashboard` in English where the existing product already does so.
- Do not rename schema fields, API routes, or internal codes just to match UI wording.

## Dashboard Layout Standards

- Use `PageContainer` for dashboard page framing and page headers.
- Keep pages inside the existing dashboard shell; do not build a separate CRM shell.
- Prefer small, composable sections instead of one oversized page component.
- Use cards, tables, and filter bars consistent with existing CRM dashboard and report pages.

Reference files:

- `src/components/layout/page-container.tsx`
- `src/features/crm/dashboard/components/crm-dashboard.tsx`
- `src/features/crm/reports/components/pipeline-report-view.tsx`

## Bento Grid Guidelines

- Reuse the existing dashboard-card rhythm: summary cards first, then charts/tables/detail sections.
- Keep KPI modules visually scannable with clear grouping and limited density per row.
- Avoid creating a radically different grid language inside CRM pages.
- Match existing spacing, border radius, and card hierarchy from current dashboard/report pages.

## Form Standards

- Use TanStack Form via `@/components/ui/tanstack-form`.
- Use Zod for submit validation.
- Reuse field components from `@/components/forms/fields`.
- Keep labels and helper text business-readable.
- Use `<Button isLoading={isPending}>` for submit/loading actions.
- Close sheets/dialogs only after successful mutation completion and cache invalidation.

Reference docs and files:

- `docs/forms.md`
- `src/features/crm/customers/components/customer-form-sheet.tsx`
- `src/features/crm/opportunities/components/opportunity-form-sheet.tsx`
- `src/features/crm/quotations/components/quotation-form-sheet.tsx`

## Table Standards

- Use `DataTable`, `DataTableToolbar`, and `useDataTable`.
- Define columns close to the feature component tree.
- Keep filters URL-driven when the list page is shareable/bookmarkable.
- Use `useSuspenseQuery()` for table data that is prefetched on the server.

Reference files:

- `src/components/ui/table/data-table.tsx`
- `src/features/users/components/users-table/index.tsx`
- `src/features/crm/customers/components/customers-table.tsx`
- `src/features/crm/opportunities/components/opportunities-table.tsx`

## Filter Standards

- Reuse shared filter metadata and existing select/date input patterns.
- Prefer `nuqs` query-state filters for reports and list pages.
- Keep "clear filters" behavior explicit.
- Report exports must use the same filter contract as on-screen data.

Reference files:

- `src/features/crm/reports/components/report-filter-bar.tsx`
- `src/features/crm/reports/server/filters/shared.ts`

## Empty State Standards

- Empty states should explain what is missing and what the next action is.
- Prefer existing placeholder/skeleton components before inventing one-off empty-state systems.
- Keep empty states within the same page shell and card layout as loaded content.

## Loading State Standards

- Use skeletons or suspense-friendly loading states for lists, charts, and dashboard panels.
- Preserve layout stability while loading.
- Keep button loading width stable with the existing button loading pattern.

Reference files:

- `src/components/ui/table/data-table-skeleton.tsx`
- `src/features/overview/components/*-skeleton.tsx`
- `src/components/ui/button.tsx`

## Error State Standards

- Use existing route-level `error.tsx` boundaries where available.
- Return actionable copy for recoverable failures.
- Do not expose raw backend or SQL detail in business-facing UI.
- Security denials should remain server-enforced even if the UI also hides the surface.

Reference files:

- `src/app/dashboard/overview/error.tsx`
- `src/app/global-error.tsx`

## Reuse Rules

- Do not create a new CRM design language.
- Do not create a second terminology registry.
- Do not create report-specific filter widgets when shared report filters already fit.
- Do not introduce UI-level permission checks as the only enforcement layer.
