Frontend (React)
The frontend is a React + TypeScript single-page application that consumes the backend API. Built with Vite, styled with Tailwind CSS + Shadcn UI.
Directory Structure
frontend/src/
├── components/ # Reusable components
│ ├── ui/ # Shadcn UI primitives
│ └── icons/ # Custom icon components
├── pages/ # Route pages
│ ├── auth/ # Authentication pages
│ ├── org/ # Organization pages
│ ├── admin/ # Admin panel pages
│ └── custom/ # Your custom pages
├── hooks/ # Custom React hooks
├── stores/ # Zustand state stores
├── lib/ # Utilities (axios, helpers)
├── types/ # TypeScript type definitions
├── config/ # Navigation, theme presets
├── custom/ # Your routes & nav items
├── assets/ # Static assets
├── App.tsx # Main router
├── main.tsx # Entry point
└── index.css # Tailwind base styles
Layouts
Three layout wrappers that define the app shell for different sections:
components/
├── AppLayout.tsx # Main app layout (sidebar + topbar + content)
├── AdminLayout.tsx # Admin panel layout (admin sidebar + content)
├── AppSidebar.tsx # App sidebar navigation
└── AppTopbar.tsx # Top navigation bar
- AppLayout — wraps all authenticated pages. Renders the sidebar (or topbar based on
style.navigationsetting), org switcher, notifications, and user menu - AdminLayout — wraps
/admin/*pages. Shows admin-specific sidebar with user/org/plan management links
Route Guards
Components that protect routes based on auth state, roles, and permissions:
components/
├── ProtectedRoute.tsx # Requires authenticated user
├── AdminProtectedRoute.tsx # Requires super_admin or support_agent role
├── GuestRoute.tsx # Redirects to dashboard if already logged in
├── Can.tsx # Renders children only if user has org permission
└── PermissionGate.tsx # Renders children only if feature is enabled
Usage in templates:
// Protect a route
<Route element={<ProtectedRoute />}>
<Route path="/dashboard" element={<DashboardPage />} />
</Route>
// Check permission in JSX
<Can permission="manage_members">
<Button>Invite Member</Button>
</Can>
App Components
Shared components used across the application:
components/
├── OrgSwitcher.tsx # Organization dropdown switcher
├── NotificationsDropdown.tsx # Bell icon + notification list
├── UserAvatar.tsx # Avatar with signed URL support
└── ImpersonationBanner.tsx # Banner shown when admin impersonates a user
UI Components (Shadcn)
Pre-installed Shadcn UI primitives — fully customizable, accessible, and typed:
components/ui/
├── avatar.tsx # User/org avatar
├── badge.tsx # Status badges
├── button.tsx # Button variants (default, outline, ghost, etc.)
├── card.tsx # Card container with header/content/footer
├── combobox.tsx # Searchable select
├── dialog.tsx # Modal dialogs
├── dropdown-menu.tsx # Dropdown menus
├── input.tsx # Text input
├── input-otp.tsx # OTP code input (MFA)
├── label.tsx # Form labels
├── select.tsx # Select dropdown
├── separator.tsx # Visual separator
├── switch.tsx # Toggle switch
└── toaster.tsx # Toast notifications
Icon Components
components/icons/
├── OAuthIcons.tsx # Google, GitHub, Microsoft, Apple SVG icons
└── IntegrationIcons.tsx # Platform integration icons
Pages
Auth Pages
pages/auth/
├── LoginPage.tsx # Email/password + OAuth + magic link
├── RegisterPage.tsx # Registration form
├── ForgotPasswordPage.tsx # Request password reset
├── ResetPasswordPage.tsx # Reset with token
├── MfaChallengePage.tsx # 6-digit TOTP or recovery code
└── OAuthCallbackPage.tsx # OAuth provider callback handler
Organization Pages
pages/org/
├── BillingPage.tsx # Subscription, plan selector, invoices
├── MembersPage.tsx # Team members + invitations
├── OrgSettingsPage.tsx # Org name, logo, MFA enforcement
├── ApiKeysPage.tsx # Create/revoke API keys
├── WebhooksPage.tsx # Webhook endpoints + delivery log
├── UsagePage.tsx # Usage metrics & charts
├── CreateOrgPage.tsx # New organization form
└── AcceptInvitationPage.tsx # Accept invite flow
Admin Pages
pages/admin/
├── AdminOverviewPage.tsx # Dashboard with metrics & charts
├── AdminUsersPage.tsx # User management (suspend, impersonate, roles)
├── AdminOrganizationsPage.tsx # Org management
├── AdminSettingsPage.tsx # 150+ settings (branding, auth, billing, mail, etc.)
├── AdminRolesPage.tsx # Global + org role management
├── AdminEmailTemplatesPage.tsx # Edit email subjects/body, preview, test
├── AdminFeatureFlagsPage.tsx # Create flags with targeting rules
├── AdminAuditLogsPage.tsx # Audit event viewer with filters
├── AdminQueuesPage.tsx # Queue monitoring, retry/purge
├── AdminHealthPage.tsx # System health checks
├── AdminUsagePage.tsx # Platform-wide usage analytics
└── AdminApiDocsPage.tsx # OpenAPI documentation viewer
Custom Pages (Your Features)
pages/custom/
├── .gitkeep
├── ProjectsPage.tsx # Example: project list (CRUD)
└── ProjectDetailPage.tsx # Example: single project with comments
Hooks
Custom React hooks for data fetching and business logic:
hooks/
├── useAuth.ts # Login, register, logout, current user
├── useOrganization.ts # Org CRUD, switching, members
├── useEntitlements.ts # Feature access & resource limits
├── useFeatureFlags.ts # Evaluated feature flags
├── usePermission.ts # Org-level permission checks
├── useOrgRoles.ts # Available org roles for assignment
├── useNotifications.ts # Notification list, mark read, delete
├── useSignedUrl.ts # Signed URL generation for private files
├── useLayoutStyle.ts # Navigation mode, theme, content width
├── useTenantMode.ts # Organization vs personal mode
└── useTheme.ts # Dark/light theme toggle
State Management
Zustand stores for global client state:
stores/
├── authStore.ts # Current user, token, clearAuth()
└── orgStore.ts # Active organization ID
The auth store persists the token to localStorage. The org store tracks which organization is currently active (sent as X-Organization-Id header on every API request).
Lib
lib/
├── axios.ts # Configured Axios instance (base URL, interceptors, 401 handling)
├── echo.ts # Laravel Echo setup (WebSocket — optional)
└── utils.ts # Utility functions (cn class merger, etc.)
Config
config/
├── navigation.ts # Sidebar nav structure (dashboard, org sections, admin)
└── theme-presets.ts # Theme color presets, border radius, sidebar styles
Custom Extension Points
custom/
├── routes.tsx # Your page routes (auto-loaded into AppLayout)
└── navItems.ts # Your sidebar items (auto-added to "Modules" section)
Example — adding a custom page:
// custom/routes.tsx
import ProjectsPage from '@/pages/custom/ProjectsPage'
export const customRoutes: CustomRoute[] = [
{
path: '/org/projects',
element: <ProjectsPage />,
permission: 'view_projects',
feature: 'projects',
},
]
// custom/navItems.ts
import { FolderKanban } from 'lucide-react'
export const customNavItems: CustomNavItem[] = [
{
label: 'Projects',
icon: FolderKanban,
href: '/org/projects',
requires: 'org:member',
feature: 'projects',
permission: 'view_projects',
},
]