TorbatYar/frontend/docs/shared-components-report.md
Mortezakoohjani 6f4a484051 Migrate Beauty, Healthcare, and Accounting frontend to modular src/modules architecture.
Move business logic out of App Router into module packages, add boundary validation scripts, and keep all routes as thin re-exports without changing URLs or API behavior.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-26 22:28:27 +03:30

12 KiB

TorbatYar Frontend — Shared Components Report

Date: 2026-07-26
Scope: components/ inventory, design system analysis, duplication mapping


1. Component Layer Overview

The frontend operates a three-tier component hierarchy:

Tier 1 — Platform DS       components/ds/          (primary, ~90+ consumers)
Tier 2 — Marketing DS      components/ui/          (legacy, ~10 consumers)
Tier 3 — Module DS         components/{module}/design-system|ui/
         Module pages      components/{module}/pages/
         Module shells     components/{module}/*Shell.tsx

2. Primary Design System (components/ds/)

File inventory

File Exports Role
index.ts Barrel Public API
Button.tsx Button CVA variants, ref forwarding
Input.tsx Input Text input
Card.tsx Card, subcomponents Surface container
Badge.tsx Badge Semantic tones (success/warning/danger/info)
Dialog.tsx Dialog, ConfirmDialog Modal dialogs
Drawer.tsx Drawer Side panel
DatePicker.tsx DatePicker Jalali calendar
FormControls.tsx FormField, Select, Checkbox, MoneyInput, Tabs Form primitives
NavChrome.tsx TableToolbar, Pagination, Breadcrumbs, Skeleton Navigation/table chrome
Page.tsx PageHeader, EmptyState, LoadingState, ErrorState, DataTable, StatCard Page scaffolding

DS export surface (from index.ts)

Button, Input, Card, Badge, Dialog, ConfirmDialog,
PageHeader, EmptyState, LoadingState, ErrorState,
DataTable, StatCard, DatePicker, Drawer, Select,
FormField, Checkbox, MoneyInput, Tabs,
TableToolbar, Breadcrumbs, Skeleton, Pagination

Adoption by module

Consumer Approx. import sites
Accounting 40+
Beauty 30+
Healthcare 25+
Platform (admin, auth, settings) 10+

Boundary compliance: components/ds/ imports nothing from domain modules.

Known DS gap

components/ds/Button.tsx does not expose a loading prop, but accounting routes use <Button loading={...}> — causing the current build failure. The legacy components/ui/Button.tsx does support loading.


3. Legacy Marketing UI (components/ui/)

File inventory

File Exports
Button.tsx Button (with loading prop)
Badge.tsx Badge (variant-based)
Container.tsx Container
SectionTitle.tsx SectionTitle
AppTile.tsx AppTile
index.ts Barrel

Consumers (~10 files)

  • app/page.tsx (platform home)
  • app/login/page.tsx, app/register/page.tsx, app/onboarding/page.tsx
  • app/dashboard/page.tsx
  • components/auth/AuthPanel.tsx
  • components/AppStoreGrid.tsx
  • components/TenantSitePage.tsx

Duplicate components: DS vs UI

Component DS path UI path Key difference
Button ds/Button.tsx ui/Button.tsx UI has loading prop; DS uses CVA + ref
Badge ds/Badge.tsx ui/Badge.tsx DS uses tone; UI uses variant

Recommendation: Deprecate components/ui/Button and Badge; add loading to DS Button; migrate 10 consumer files.


4. Platform Shared Components (root components/)

Component Role Used by
AuthGuard.tsx Redirect unauthenticated users All module layouts
AdminAuthGuard.tsx Admin-specific auth Admin layout
ThemeProvider.tsx White-label theme loader Root layout
SiteHeader.tsx Global navigation bar Root layout (all routes)
TenantSwitcher.tsx Workspace selector SiteHeader
RouteProgress.tsx Navigation progress bar Accounting layout
AppStoreGrid.tsx SuperApp module launcher Dashboard
TenantSitePage.tsx Tenant subdomain landing Platform home
HealthStatus.tsx Service health display UNUSED (dead code)

5. Providers (components/providers/)

Provider Context? Responsibility
AppProviders.tsx No (QueryClient only) TanStack Query + Sonner toaster
ColorModeProvider.tsx Yes Light/dark mode, localStorage persistence

Provider stack in root layout:

ThemeProvider → ColorModeProvider → AppProviders → SiteHeader + main

No auth context — auth state accessed via useMe() hook hitting TanStack Query cache.


6. Module Shells

Side-by-side comparison

Feature AccountingShell BeautyPortalShell HealthcarePortalShell
Sidebar nav
Collapsible groups
Mobile drawer
Tenant display
Nav source lib/accounting-nav.ts lib/beauty-portals.ts lib/healthcare-portals.ts
Portal ID param N/A
Lines of code ~200 ~220 ~220
Similarity ~90% identical structure ~90% identical structure

Portal layout factory

Module File Portal IDs
Beauty components/beauty/createPortalLayout.tsx customer, owner, reception, staff, admin
Healthcare components/healthcare/createPortalLayout.tsx patient, doctor, reception, clinic, hospital, pharmacy, admin

Both factories implement identical gate logic:

  1. AuthGuard
  2. useMe() loading/error/onboarding check
  3. Tenant ID validation
  4. Render domain portal shell

Duplication estimate: ~95% code overlap between the two factory files.


7. Module Design Systems

Beauty (components/beauty/design-system/)

File Exports
tokens.ts Status tone maps, accent constants
BeautyStatusChip.tsx Domain status badges
BeautyCards.tsx CardShell, SalonCard, ServiceCard, TimelineItem, StatWidget
BeautyPrimitives.tsx StatWidget, SearchResultRow
BeautyTablePage.tsx Searchable DataTable wrapper
index.ts Barrel

Healthcare (components/healthcare/ui/)

File Exports
tokens.ts Status tone maps (+ prescriptionStatusTone)
MedicalStatusChip.tsx Domain status badges
HealthcareCards.tsx CardShell, ClinicCard, DoctorCard, TimelineItem, StatWidget
index.ts Barrel

Naming inconsistency: Beauty uses design-system/ folder; healthcare uses ui/ folder for the same concept.

Duplicated module DS components

Concept Beauty Healthcare Similarity
Status chip BeautyStatusChip MedicalStatusChip ~85%
Card shell CardShell in BeautyCards CardShell in HealthcareCards ~95%
Stat widget StatWidget in BeautyPrimitives StatWidget in HealthcareCards ~98%
Timeline item TimelineItem in BeautyCards TimelineItem in HealthcareCards ~90%
Search result row SearchResultRow in BeautyPrimitives (inline in public pages) ~80%
Table page wrapper BeautyTablePage None
Tokens design-system/tokens.ts ui/tokens.ts ~90%

8. Page Bundles

Large co-located page component files serving multiple routes:

File Lines Routes served
beauty/pages/public.tsx 753 ~20 site routes
beauty/pages/owner.tsx ~400+ ~6 owner re-export routes
beauty/pages/customer.tsx 442 ~20 customer routes
beauty/pages/reception.tsx ~350+ ~10 reception routes
healthcare/pages/patient.tsx 552 ~18 patient routes
healthcare/pages/doctor.tsx 537 ~16 doctor routes
healthcare/pages/public.tsx 467 ~15 site routes

Shared page helpers

File Exports
beauty/pages/shared.tsx PageLoader, PageError, ServiceMetaBadges, MetricsGrid, audit helpers
healthcare/pages/shared.tsx Same pattern — near copy-paste

9. Accounting Screen Aggregators

Large reusable components (not route pages):

File Lines Purpose
BusinessDocsPage.tsx 1,328 Document management screens
WorkflowScreens.tsx 1,132 Workflow UI (approvals, compliance)
OperationalDocumentPage.tsx 996 Voucher/document editing
DomainScreens.tsx 652 Domain-specific list screens
SpecializedOpsPage.tsx ~400+ Specialized operations
EntityCombobox.tsx ~200+ Entity picker
CompletionScoreboard.tsx ~150+ Setup progress

These are shared within accounting only — correct boundary, but files are too large.


10. Public Site Layouts

Component Module Unique elements
PublicBeautyLayout.tsx Beauty --beauty-accent, beauty branding
PublicHealthcareLayout.tsx Healthcare --health-accent, healthcare branding

Both provide: hero header, footer, mobile nav, booking CTA. Structure ~90% identical.


11. Deprecated / Dead Components

Component Status Action
BeautyBusinessShell.tsx @deprecated in source Remove after confirming zero imports
HealthStatus.tsx Zero imports Delete
beauty/pages/mobile.tsx (MobilePortalFrame) Zero imports Delete

12. Component Usage Matrix

Component category Accounting Beauty Healthcare Platform
ds/Button (uses ui)
ds/DataTable
ds/FormField
ds/DatePicker
ds/MoneyInput
ui/Button
Module status chip
Module CardShell
Portal shell AccountingShell BeautyPortalShell HealthcarePortalShell AdminShell

13. Consolidation Roadmap

Priority 1 — Unify Button/Badge (Phase 0)

Add loading prop to ds/Button; migrate ui/ consumers; deprecate ui/Button and ui/Badge.

Priority 2 — Extract portal infrastructure (Phase 2)

components/portals/
├── PortalShell.tsx          # Base sidebar shell (parametric nav)
├── createPortalLayout.tsx   # Single factory
├── PublicSiteLayout.tsx     # Parametric public layout
├── PageHelpers.tsx          # Merged shared.tsx helpers
├── DomainCardShell.tsx      # Parametric CardShell + StatWidget
└── DomainStatusChip.tsx     # Parametric status chip

Priority 3 — Split large files (Phase 4)

  • Accounting screen aggregators → one file per screen domain
  • Page bundles → one file per route group (e.g. customer/wallet.tsx)

14. Summary

Metric Value
DS component files 11
UI (legacy) component files 6
Duplicate Button implementations 2
Duplicate Badge implementations 2
Duplicate portal factories 2
Duplicate portal shells 3 (90% similar)
Duplicate shared page helpers 2 (near copy-paste)
Dead components 3
Largest component file 1,328 lines (BusinessDocsPage.tsx)

The shared design system (components/ds/) is the correct foundation. The primary issue is parallel implementations at the module layer (beauty vs healthcare) and legacy UI coexistence at the platform layer.