Frontend Architecture
React application structure, routing, authentication, and state management.
The AnyaSelf frontend is a React single-page application built with Vite, TypeScript, and React Router v6. It targets responsive web-first with mobile browser support.
Tech Stack
| Layer | Technology |
|---|---|
| Framework | React 18 |
| Build | Vite |
| Language | TypeScript |
| Routing | React Router v6 |
| State | Zustand (auth store), React Query (server state) |
| Styling | Vanilla CSS (no framework) |
| Auth | Firebase Auth SDK + AnyaSelf JWT |
| Deploy | Docker + nginx → Cloud Run |
Project Structure
apps/client-web/
├── src/
│ ├── main.tsx # React entry point
│ ├── styles.css # Global styles (109KB)
│ ├── app/
│ │ ├── app.tsx # App shell
│ │ ├── routes.tsx # React Router configuration
│ │ └── query-client.ts # React Query instance
│ ├── auth/
│ │ └── auth-store.ts # Zustand auth state
│ ├── components/
│ │ └── layout.tsx # AppLayout (sidebar + nav)
│ ├── features/ # Feature modules (13 features)
│ │ └── ...
│ ├── lib/
│ │ ├── api/ # API client functions
│ │ ├── env.ts # Environment config
│ │ ├── firebase/ # Firebase SDK init
│ │ ├── missions/ # Mission state helpers
│ │ ├── sw/ # Service worker registration
│ │ ├── theme/ # Theme management
│ │ ├── utils/ # Shared utilities
│ │ └── wardrobe/ # Wardrobe API helpers
│ └── test/ # Shared test utilities
├── index.html
├── vite.config.ts
├── tsconfig.json
├── Dockerfile
└── nginx.confRouting
All routes are defined in src/app/routes.tsx:
graph TD
ROOT["/"] --> SHELL["GlobalAuraShell<br/>(Aura voice bubble overlay)"]
SHELL --> LANDING["/landing<br/>LandingPage"]
SHELL --> LOGIN["/login<br/>PublicOnlyRoute → LoginPage"]
SHELL --> PROTECTED["/ (ProtectedRoute)"]
PROTECTED --> DASH["/dashboard"]
PROTECTED --> BOUT["/boutique"]
PROTECTED --> MISS["/missions"]
PROTECTED --> REQ["/requests"]
PROTECTED --> BUY["/buyflow"]
PROTECTED --> HB["/hyperbeam"]
PROTECTED --> SET["/settings"]
PROTECTED --> VTO_R["/vto"]
PROTECTED --> WARD["/wardrobe"]
PROTECTED --> ONBOARD["/onboarding"]Route Guards
| Guard | Logic |
|---|---|
ProtectedRoute | Redirects to /login if no session; redirects to /onboarding if not completed |
PublicOnlyRoute | Redirects to /dashboard if already authenticated |
GlobalAuraShell | Wraps all routes with the persistent Aura voice AI bubble |
Preview Mode
When env.previewMode is enabled, auth is bypassed and users go directly to the landing page with limited functionality.
Authentication Flow
sequenceDiagram
participant U as User
participant APP as React App
participant FB as Firebase Auth
participant GW as API Gateway
U->>APP: Click "Sign In"
APP->>FB: signInWithPopup(GoogleProvider)
FB-->>APP: Firebase ID Token
APP->>GW: POST /auth/login { idToken }
GW-->>APP: { accessToken, user }
APP->>APP: authStore.setSession(token, user)
APP->>APP: Navigate to /onboarding or /dashboardState Management
| Store | Library | Scope |
|---|---|---|
Auth state (session, householdId) | Zustand | Global |
| Server data (missions, items, offers) | React Query | Per-component |
| Onboarding progress | Zustand (persistent) | Per-user |
Build & Deploy
Development
cd apps/client-web
npm install
npm run dev # http://localhost:5173Production Build
npm run build # Outputs to dist/Docker Deployment
# Multi-stage: Node build → nginx serve
FROM node:20-slim AS build
WORKDIR /app
COPY . .
RUN npm ci && npm run build
FROM nginx:alpine
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=build /app/dist /usr/share/nginx/html