mirror of
https://github.com/MaksTinyWorkshop/_Assistant_Lead_Tech
synced 2026-04-06 21:41:42 +02:00
Refonte Structure
This commit is contained in:
130
knowledge/frontend/patterns/forms.md
Normal file
130
knowledge/frontend/patterns/forms.md
Normal file
@@ -0,0 +1,130 @@
|
||||
# Frontend — Patterns : Forms
|
||||
|
||||
> Extrait de la base de connaissance Lead_tech. Voir `knowledge/frontend/patterns/README.md` pour l'index complet.
|
||||
|
||||
---
|
||||
|
||||
<a id="pattern-formulaire-robuste"></a>
|
||||
## Pattern : Formulaire robuste avec validation et erreurs explicites
|
||||
|
||||
### Synthèse
|
||||
|
||||
- **Objectif** : garantir des formulaires fiables, compréhensibles et maintenables.
|
||||
- **Contexte** : toute interface avec saisie utilisateur et règles métier.
|
||||
- **Quand l'utiliser** : dès qu'un formulaire dépasse un simple champ isolé.
|
||||
- **Quand l'éviter** : formulaires ultra-simples sans validation réelle.
|
||||
|
||||
### Analyse
|
||||
|
||||
- **Avantages** :
|
||||
- UX claire (l'utilisateur sait quoi corriger)
|
||||
- Moins d'erreurs silencieuses
|
||||
- Base saine pour tests et accessibilité
|
||||
- **Limites / vigilance** :
|
||||
- Peut sembler verbeux sans discipline
|
||||
- Risque de duplication si mal factorisé
|
||||
|
||||
### Validation
|
||||
|
||||
- Validé le : 25-01-2026
|
||||
- Contexte technique : Front-end agnostique, API HTTP
|
||||
|
||||
### Implémentation (exemple minimal)
|
||||
|
||||
```txt
|
||||
- Validation côté client (format, champs requis)
|
||||
- Validation côté serveur (règles métier)
|
||||
- Mapping explicite des erreurs serveur → champs UI
|
||||
- Aucun submit silencieux
|
||||
```
|
||||
|
||||
### Checklist
|
||||
|
||||
- [ ] Messages d'erreur compréhensibles et localisés
|
||||
- [ ] Validation client + serveur cohérente
|
||||
- [ ] Focus automatique sur le champ en erreur
|
||||
- [ ] États loading / disabled gérés
|
||||
- [ ] Tests sur cas valides et invalides
|
||||
|
||||
---
|
||||
|
||||
<a id="pattern-toggle-optimiste-rollback"></a>
|
||||
## Pattern : Toggle optimiste avec rollback (React Server Action)
|
||||
|
||||
### Synthèse
|
||||
|
||||
- **Objectif** : masquer la latence serveur sur un toggle boolean en mettant à jour l'UI immédiatement, avec rollback en cas d'erreur.
|
||||
- **Contexte** : toggles boolean (visibilité, disponibilité, settings) où la latence doit être masquée.
|
||||
- **Quand l'utiliser** : toggles sans besoin de re-fetcher l'entité entière après mutation.
|
||||
- **Quand l'éviter** : mutations qui retournent des données complexes → préférer le pattern "Server Action retournant l'entité".
|
||||
|
||||
### Validation
|
||||
|
||||
- Validé le : 21-03-2026
|
||||
- Contexte technique : React / Next.js App Router — app-template-resto
|
||||
|
||||
### Implémentation
|
||||
|
||||
```tsx
|
||||
const [optimistic, setOptimistic] = useState(initialValue);
|
||||
|
||||
async function handleToggle() {
|
||||
const prev = optimistic;
|
||||
setOptimistic(!prev); // update immédiat
|
||||
try {
|
||||
await toggleAction(!prev);
|
||||
router.refresh(); // synchronise le Server Component parent
|
||||
} catch {
|
||||
setOptimistic(prev); // rollback si erreur
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
<a id="pattern-server-action-retourne-entite"></a>
|
||||
## Pattern : Server Action retournant l'entité — élimination de `router.refresh()` sur create/edit
|
||||
|
||||
### Synthèse
|
||||
|
||||
- **Objectif** : mettre à jour l'état local directement avec les données réelles retournées par le serveur, sans round-trip SSR supplémentaire.
|
||||
- **Contexte** : liste d'items managée côté client (`useState`) avec création et modification via Server Actions.
|
||||
- **Quand l'utiliser** : create et edit d'entités dans une liste. Plus performant que toggle optimiste + `router.refresh()`.
|
||||
- **Quand l'éviter** : simples toggles boolean → le pattern optimiste avec rollback suffit.
|
||||
|
||||
### Analyse
|
||||
|
||||
- **Avantages vs toggle optimiste + `router.refresh()` :**
|
||||
- Zéro aller-retour SSR supplémentaire (~500ms–2s économisés sur mobile)
|
||||
- État local garanti cohérent avec la DB (données réelles, pas calculées localement)
|
||||
- Pas de flash de rechargement
|
||||
- **Limites / vigilance** :
|
||||
- `revalidatePath` reste nécessaire pour invalider le cache des pages publiques
|
||||
|
||||
### Validation
|
||||
|
||||
- Validé le : 22-03-2026
|
||||
- Contexte technique : React / Next.js App Router — app-template-resto story 3.8
|
||||
|
||||
### Implémentation
|
||||
|
||||
```typescript
|
||||
// Repository — retourne l'entité complète
|
||||
export async function createItem(tenantId: string, data: Input): Promise<ItemRow> {
|
||||
return prisma.item.create({ data: { tenantId, ...data }, select: { ...fullSelect } });
|
||||
}
|
||||
|
||||
// Action — retourne la donnée au client
|
||||
export async function createItemAction(formData: FormData): Promise<ItemRow> {
|
||||
const actor = await requireOwner();
|
||||
const item = await createItem(actor.tenantId, input);
|
||||
revalidatePath("/dashboard/..."); // invalider cache pages publiques
|
||||
return item; // ← clé : retourner l'entité
|
||||
}
|
||||
|
||||
// Client — mise à jour locale sans round-trip SSR
|
||||
const created = await createItemAction(formData);
|
||||
setItems((prev) => [...prev, created]); // pas de router.refresh()
|
||||
```
|
||||
|
||||
**Pour les entités avec relations :** utiliser un helper `findItemById(tenantId, id)` appelé après la mutation pour retourner la forme complète avec les relations résolues.
|
||||
Reference in New Issue
Block a user