Frontend Architecture

React 19 SPA with Vite 8, Tailwind CSS v4, TanStack React Query v5. 30+ pages across Resident, Official, and Guard modes. Social-media UX for residents, enterprise ERP for officials.

Stack

DependencyVersionPurpose
react + react-dom19.2UI framework
vite8.1Build tool, dev server (port 8888)
tailwindcss4.3Utility CSS (@tailwindcss/vite plugin)
typescript6.0Type safety
@tanstack/react-query5.101Server state, caching, mutations
react-router-dom7.18Client routing with nested layouts
react-hook-form7.81Form state management
zod4.4Form validation (via @hookform/resolvers)
motion12.42Animations (NOT framer-motion)
lucide-react1.23Icon library
class-variance-authority0.7Component variant styling
clsx + tailwind-merge2.1 / 3.6Conditional class merging
react-qr-code2.2QR code generation (UPI, visitor passes)

Theme System

/* index.css — Tailwind v4 theme */
@import "tailwindcss";

@theme {
  --font-heading: 'Outfit', sans-serif;
  --font-body: 'Inter', sans-serif;
  --color-brand: #10b981;        /* emerald-500 */
  --color-brand-dark: #059669;   /* emerald-600 */
  --color-brand-light: #d1fae5;  /* emerald-100 */
  --color-surface: #ffffff;
  --color-surface-dark: #18181b;
}

/* Dark mode via .dark class on  */
@custom-variant dark (&:where(.dark, .dark *));

Theme persisted in localStorage('societee_theme') with prefers-color-scheme system detection. ThemeContext provides theme, setTheme(), resolvedTheme.

Context Providers

ContextPurpose
AuthContextUser, mode (resident/official), roles, permissions, persona, switchMode()
ThemeContextTheme (light/dark/system), resolvedTheme, setTheme()
QueryClientTanStack React Query provider (staleTime: 5min, retry: 2)

Custom Hooks

HookPurpose
useAuth()Login, logout, user, mode, roles, isCommittee, hasPermission()
useLogin()Mutation hook for POST /auth/login
useMe()Query hook for GET /auth/me
useSwitchPersona()Mutation hook for POST /auth/switch-persona
useLogout()Mutation hook for POST /auth/logout

Layout System

DashboardLayout
3-panel layout (sidebar + main + optional right panel). Role-based navigation. PersonaSwitcher (Resident ↔ Official pill toggle). Mobile bottom tabs. 11 official nav items.
GuardLayout
Lightweight top bar + 5-tab bottom nav (Gate, Visitors, Vehicles, SOS, Log). Minimal chrome, large touch targets. Separate from DashboardLayout.

Route Map

Public

/                   → Landing (hero, features, pricing)
/login              → Login (email + password)
/register           → Register (society + admin details)

Resident Mode

/feed               → Home Feed (posts, stories, quick stats)
/my-bills           → My Bills (invoices, pay, history)
/my-complaints      → My Complaints (create, track, chat)
/visitors           → Visitors (pre-approve QR, history)
/community          → Community (forum, events, marketplace)
/amenities          → Amenity Booking (calendar, slots)
/letters            → Letters & NOC (request, track)
/safety             → Safety (alerts, emergency contacts)
/notifications      → Notifications
/my-vehicles        → My Vehicles (register, list)
/my-ledger          → My Ledger (statement, balance)
/profile            → Profile (sessions, password, MFA)

Official Mode

/official/dashboard  → Dashboard (KPIs, charts, alerts)
/official/billing    → Billing (invoices, defaulters, generate)
/official/accounting → Accounting (COA, journal, GST, TDS)
/official/payments   → Payments (collection, reconciliation)
/official/reports    → Reports (financial, operational, compliance)
/official/documents  → Documents (vault, registers, letters)
/official/vendors    → Vendors (directory, bills, approve)
/official/members    → Members (directory, roles)
/official/facilities → Facilities (bookings, maintenance)
/official/security   → Security (guards, blacklist, gate)
/official/settings   → Settings (society, features, admin)

Guard Mode (nested under GuardLayout)

/guard/gate          → GuardGate (shift, check-in/out, quick actions)
/guard/visitors      → GuardVisitors (active list, entry form)
/guard/vehicles      → GuardVehicles (read-only, exit)
/guard/sos           → GuardSOS (emergency type, big red button)
/guard/log           → GuardLog (shift timeline)

API Client

// frontend/src/lib/api.ts
class ApiClient {
  private baseUrl = '/v1';  // Proxied to backend in dev

  async get<T>(path: string): Promise<T>
  async post<T>(path: string, body?: unknown): Promise<T>
  async put<T>(path: string, body?: unknown): Promise<T>
  async delete<T>(path: string): Promise<T>
  async upload<T>(path: string, file: File, metadata?: Record<string, string>): Promise<T>
}

// Auth token injected via interceptor from localStorage
// Tenant ID injected from AuthContext

Vite Config

// frontend/vite.config.ts
export default defineConfig({
  plugins: [react(), tailwindcss()],
  server: {
    port: 8888,
    strictPort: true,
    proxy: {
      '/v1': { target: 'http://localhost:8787', changeOrigin: true }
    }
  }
})

Mode Switching

Frontend stores mode in localStorage('societee_mode') as 'resident' | 'official'. useAuth().switchMode() auto-selects the appropriate persona based on user roles. PersonaSwitcher renders a pill toggle in the sidebar header.

Design System