Composants Frontend¶
Guide des composants React de Primatch : organisation, conventions et patterns.
Catégories de composants¶
1. UI Primitives (components/ui/)¶
Composants sans logique métier, purement visuels et réutilisables partout.
components/ui/
├── Button.tsx # Bouton avec variants (primary, secondary, danger)
├── Input.tsx # Input avec label, error, aide
├── Card.tsx # Conteneur avec shadow/border
├── Drawer.tsx # Bottom sheet (z-[60], au-dessus du footer nav z-50)
├── Modal.tsx # Dialog/Overlay
├── Badge.tsx # Label coloré (statut, type)
├── LoadingSpinner.tsx # Indicateur de chargement
└── Avatar.tsx # Photo de profil
Règle : Les composants UI ne font aucun appel API et n'utilisent aucun hook métier.
Drawer — z-index et safe area
Drawer.tsx utilise z-[60] pour être au-dessus de la barre de navigation mobile (PlayerBottomNav, z-50). Le contenu inclut un padding bottom tenant compte de env(safe-area-inset-bottom) pour éviter l'overlap sur les appareils avec encoche/home indicator.
2. Feature Components (components/features/)¶
Composants spécifiques à un domaine métier.
components/features/
├── game/
│ ├── GameCard.tsx # Carte d'aperçu d'une partie
│ ├── GameStatusBadge.tsx
│ └── ScoreForm.tsx # Formulaire de saisie de score
3. Layout (components/layout/)¶
Composants structurels de la page.
components/layout/
├── Header.tsx
├── Sidebar.tsx
├── Footer.tsx
└── PageWrapper.tsx # Wrapper standard avec title, breadcrumb
Pattern : Composant avec état de chargement¶
export const GameCard = ({ gameId }: { gameId: number }) => {
const { data: game, isLoading, isError } = useGame(gameId);
if (isLoading) return <Card><LoadingSpinner /></Card>;
if (isError) return <Card><ErrorMessage /></Card>;
if (!game) return null;
return (
<Card>
<h3>{game.players.join(' vs ')}</h3>
<GameStatusBadge status={game.status} />
<time>{formatDate(game.scheduledAt)}</time>
</Card>
);
};