xpeditis2.0/docs/architecture/frontend.md
2026-05-14 21:11:54 +02:00

158 lines
4.8 KiB
Markdown

# Architecture Frontend — Next.js 14
---
## Structure
```
apps/frontend/
├── app/ # Next.js App Router
│ ├── [locale]/ # i18n wrapper (fr, en) — next-intl
│ │ ├── about/
│ │ ├── blog/
│ │ ├── booking/ # Flux de réservation
│ │ ├── careers/
│ │ ├── carrier/ # Portail carrier (magic link)
│ │ ├── compliance/
│ │ ├── contact/
│ │ ├── dashboard/ # Application protégée
│ │ │ ├── bookings/
│ │ │ ├── csv-bookings/
│ │ │ ├── search/
│ │ │ ├── settings/
│ │ │ ├── admin/
│ │ │ └── wiki/
│ │ ├── docs/
│ │ ├── forgot-password/
│ │ ├── login/
│ │ ├── pricing/
│ │ ├── register/
│ │ ├── reset-password/
│ │ └── verify-email/
│ └── api/v1/ # API routes Next.js (proxy)
├── src/
│ ├── components/ # Composants React
│ │ ├── admin/
│ │ ├── blog/
│ │ ├── bookings/
│ │ ├── docs/
│ │ ├── layout/
│ │ ├── organization/
│ │ ├── rate-search/
│ │ └── ui/ # Composants shadcn/ui (Radix UI)
│ ├── hooks/ # Custom hooks (TanStack Query)
│ ├── lib/
│ │ ├── api/ # Client fetch avec auto-refresh JWT
│ │ │ ├── client.ts # get/post/patch/del/upload/download
│ │ │ ├── auth.ts
│ │ │ ├── bookings.ts
│ │ │ ├── rates.ts
│ │ │ └── ...
│ │ ├── context/ # AuthContext, CookieContext
│ │ └── providers/ # QueryProvider (TanStack Query)
│ ├── types/ # Types TypeScript
│ └── utils/ # Export Excel, PDF
├── i18n/ # Config next-intl
├── messages/
│ ├── fr.json # Traductions français
│ └── en.json # Traductions anglais
└── middleware.ts # Auth + i18n routing
```
---
## i18n (Internationalisation)
Le frontend supporte **français** (par défaut) et **anglais** via `next-intl`.
Routes : `/fr/login`, `/en/login`, etc.
```typescript
// i18n/routing.ts
export const routing = defineRouting({
locales: ['fr', 'en'],
defaultLocale: 'fr',
});
```
Le middleware `middleware.ts` combine la protection d'auth **et** le routing i18n.
---
## Client API
`src/lib/api/client.ts` — wrapper fetch avec auto-refresh JWT :
```typescript
// Toutes les requêtes passent par ces fonctions
export const get = <T>(url: string): Promise<T>
export const post = <T>(url: string, body: unknown): Promise<T>
export const patch = <T>(url: string, body: unknown): Promise<T>
export const del = <T>(url: string): Promise<T>
export const upload = <T>(url: string, formData: FormData): Promise<T>
export const download = (url: string): Promise<Blob>
```
- Sur 401 : refresh automatique du token, retry de la requête
- Tokens : localStorage ET cookie `accessToken` (pour le middleware Next.js)
---
## State management
- **Données serveur** : TanStack Query v5 (`@tanstack/react-query`)
- **État global UI** : zustand (minimal)
- **Formulaires** : react-hook-form + zod
```typescript
// Pattern hook standard
export function useBookings(filters?: BookingFilters) {
return useQuery({
queryKey: ['bookings', filters],
queryFn: () => bookingsApi.list(filters),
});
}
```
---
## Protection des routes
`middleware.ts` vérifie le cookie `accessToken` avant chaque route.
**Routes publiques exactes** : `/fr`, `/en`, `/`
**Routes publiques par préfixe** :
`/login`, `/register`, `/forgot-password`, `/reset-password`, `/verify-email`,
`/about`, `/blog`, `/pricing`, `/contact`, `/careers`, `/press`, `/security`,
`/privacy`, `/terms`, `/cookies`, `/compliance`, `/carrier`
Toutes les autres routes → redirection `/login?redirect=<pathname>`
---
## Design system
| Élément | Valeur |
|---------|--------|
| Couleur primaire | Navy `#10183A` |
| Couleur accent | Turquoise `#34CCCD` |
| Succès | Green `#067224` |
| Fond neutre | Gray `#F2F2F2` |
| Font headings | Manrope |
| Font body | Montserrat |
| UI components | shadcn/ui (Radix UI) |
| Icônes | lucide-react |
---
## Conventions
- Pas de fetch direct — toujours via `src/lib/api/*.ts`
- Les hooks wrappent TanStack Query, pas de `useEffect` pour les données
- `strict: false` en frontend (contrairement au backend)
- Alias `@/*``./src/*`
- La landing page est en **français**