Extract admin dashboard from ghabilee-frontend2 into a dedicated Next.js app for backoffice.ghabilee.ir (no SEO indexing / Clarity).
4.3 KiB
Admin UI guidelines
The admin panel uses HeroUI v3 through compatibility adapters and shared admin primitives. Page code should prefer these shared layers over importing HeroUI directly, unless a compound component has no adapter yet.
Theme boundary
DashboardShell owns the data-theme="ghabilee-admin" boundary. Admin
semantic colors, fields, overlays, focus rings, radius, elevation, and
scrollbars are defined under that selector in styles/globals.css.
Use semantic utilities inside admin UI:
bg-surface,bg-surface-secondary, andtext-foregroundtext-muted,border-border, andborder-separatortext-link,ring-focus, and theaccent,success,warning, anddangerfamilies
Avoid adding new hard-coded Slate colors or !important overrides. If a
visual rule should apply to multiple components, add or adjust a semantic
token at the admin theme boundary.
Consumer app overlays and layout rules are separate — see
consumer-ui-guidelines.md (ConsumerModal
only; mobile excellence; desktop polish is a non-goal).
Shared primitives
- Use
components/formElements/Buttonfor actions and links. - Use
components/formElements/Inputfor existing React Hook Form forms. New focused controls may compose the adapters incomponents/heroui. - Use
components/modals/Modalfor forms, previews, and record review that stay on the list page. Do not use Drawer /AdminDetailDrawerin admin UI. - Use
useAlertModalfor confirmations. It renders a WAI-ARIAAlertDialogand prevents duplicate async confirmation. - Use
lib/toastinstead of importing HeroUI's toast queue in business code. - Use
AdminStateand the exports fromLoadingStatefor empty, error, and loading states.
Paginated admin lists
PaginatedList is the default list surface. It includes:
- server pagination and sorting;
- responsive table/card rendering;
- desktop column filters and a mobile filter dialog;
- active-filter chips;
- column visibility;
- optional quick search via
searchFieldandsearchPlaceholder; - optional row selection and
bulkActions; - refresh, error, empty, and loading states.
Only connect searchField to a filter supported by the endpoint. Bulk action
renderers receive the current HeroUI Selection; they must handle the
special "all" value.
Sensitive workflows
Destructive or irreversible actions must:
- open
useAlertModalwithdangerAccept: true; - use
useAdminActionor an equivalent pending state; - disable competing actions while the request is pending;
- show success or localized failure feedback through
lib/toast; - refresh the affected list after success.
Use a Modal for review and data entry. Do not place a full edit form in a table cell. Never introduce a side drawer in the admin panel.
RTL and accessibility
- Keep the document and admin shell RTL; use logical
start/endutilities. - Add an accessible name to icon-only buttons.
- Preserve visible focus rings; do not remove outlines without a
focus-visiblereplacement. - Use
role="status"/aria-livefor non-critical updates androle="alert"for errors. - Confirm keyboard and focus behavior when changing dialogs, modals, dropdowns, tables, or search fields.
Prefer compact spacing utilities (p-2 not px-2 py-2). Do not add
breakpoint padding that only changes by one Tailwind step (p-4 md:p-5).
Keep text-xs at every breakpoint; do not add sm:text-sm.
Use integer spacing only (py-3 not py-2.5).
HeroUI MCP workflow
Before using or changing a HeroUI component:
- retrieve the current quick-start requirements;
- list available v3 components;
- retrieve the component documentation;
- consult source styles only when semantic tokens or documented classes are insufficient;
- validate against the installed package types.
The repository currently uses HeroUI 3.2.2. MCP version labels may lag the
installed package, so TypeScript, focused tests, and the installed package
types remain mandatory validation gates.
Required checks
For a focused UI change, run:
pnpm typecheck
pnpm exec eslint <changed-files> --max-warnings 0
pnpm exec vitest run <related-tests>
git diff --check
Before release, also run the complete test suite, architecture check, bundle budget check, and relevant Playwright accessibility scenarios.