Contexte
Implémente l'étape 1 du funnel repeq : saisie de la date de fin de période de référence via DatePicker DSFR accessible (RGAA N°9, N°36 — format annoncé au lecteur d'écran). Remplace le placeholder posé par le ticket infra. Issue parent #3287. Dépend de #TICKET_ROUTER, #TICKET_INFRA_FUNNEL.
Fichiers impactés
packages/app/src/modules/representation-equilibree/steps/Step1Period.tsx (création)
packages/app/src/modules/representation-equilibree/steps/__tests__/Step1Period.test.tsx (création)
packages/app/src/modules/representation-equilibree/StepPageClient.tsx (modification — brancher Step1Period)
packages/app/src/modules/representation-equilibree/index.ts (modification — export)
Changement attendu
- Composant
Step1Period (client component) :
- Reçoit
initialValue: string | null (date au format ISO YYYY-MM-DD) et declarationYear: number.
- Utilise
useZodForm avec updatePeriodSchema.
- Champ
<input type="date" /> natif DSFR, name="endOfReferencePeriod", id unique, <label> associé, <div className="fr-hint-text"> : "Saisissez la date au format jour/mois/année. Par exemple : 31/12/2026.".
- Bouton secondaire "Sélectionner la fin de l'année civile" qui pré-remplit
${declarationYear - 1}-12-31 via setValue (cohérent avec le mockup).
- Callout DSFR
fr-highlight (bleu) au-dessus, affichant : "Vous déclarez les écarts de représentation pour la période de référence de 12 mois, clos au plus tard le 31/12/${declarationYear - 1}." (copier la structure exacte du mockup).
- Appel
api.representationEquilibree.updateStep1.useMutation à la soumission, puis router.push("/representation-equilibree/etape/2") en cas de succès.
- Intègre
<FormActions primaryLabel="Enregistrer et continuer" /> (pas de "Précédent" à l'étape 1).
- Si la soumission réussit, la période est affichée dans le
fr-highlight avec une formulation "Période sélectionnée : du 01/01/YYYY au DD/MM/YYYY" (N°8 — mise en exergue).
- Tests
__tests__/Step1Period.test.tsx :
- Rendu avec
initialValue=null : le champ est vide, fr-hint-text annonce le format.
- Saisie d'une date invalide via form submit : message d'erreur visible + pas d'appel mutation.
- Saisie d'une date valide :
mutation.mutate appelé avec la bonne valeur.
- Mock next/navigation via
~/test/setup.ts.
- StepPageClient : branche
<Step1Period initialValue={declaration.endOfReferencePeriod} declarationYear={declaration.year} /> à case 1:.
Scénarios de test
- S4 (critique a11y) : le lecteur d'écran annonce le format attendu via
fr-hint-text. Test unitaire vérifie la présence de ce hint + aria-describedby.
- Test unitaire : soumission valide déclenche la mutation + la navigation vers l'étape 2.
- Test unitaire : soumission invalide affiche le message Zod.
Références visuelles
Desktop

Mobile

Annexe pipeline (lecture locale par code-dev / design-validator) :
/tmp/egapro-mocks/epic-3287/screenshots/step-1-periode-desktop.png
/tmp/egapro-mocks/epic-3287/screenshots/step-1-periode-mobile.png
Critères d'acceptation
Contexte
Implémente l'étape 1 du funnel repeq : saisie de la date de fin de période de référence via DatePicker DSFR accessible (RGAA N°9, N°36 — format annoncé au lecteur d'écran). Remplace le placeholder posé par le ticket infra. Issue parent #3287. Dépend de #TICKET_ROUTER, #TICKET_INFRA_FUNNEL.
Fichiers impactés
packages/app/src/modules/representation-equilibree/steps/Step1Period.tsx(création)packages/app/src/modules/representation-equilibree/steps/__tests__/Step1Period.test.tsx(création)packages/app/src/modules/representation-equilibree/StepPageClient.tsx(modification — brancher Step1Period)packages/app/src/modules/representation-equilibree/index.ts(modification — export)Changement attendu
Step1Period(client component) :initialValue: string | null(date au format ISOYYYY-MM-DD) etdeclarationYear: number.useZodFormavecupdatePeriodSchema.<input type="date" />natif DSFR,name="endOfReferencePeriod",idunique,<label>associé,<div className="fr-hint-text">: "Saisissez la date au format jour/mois/année. Par exemple : 31/12/2026.".${declarationYear - 1}-12-31viasetValue(cohérent avec le mockup).fr-highlight(bleu) au-dessus, affichant : "Vous déclarez les écarts de représentation pour la période de référence de 12 mois, clos au plus tard le 31/12/${declarationYear - 1}." (copier la structure exacte du mockup).api.representationEquilibree.updateStep1.useMutationà la soumission, puisrouter.push("/representation-equilibree/etape/2")en cas de succès.<FormActions primaryLabel="Enregistrer et continuer" />(pas de "Précédent" à l'étape 1).fr-highlightavec une formulation "Période sélectionnée : du 01/01/YYYY au DD/MM/YYYY" (N°8 — mise en exergue).__tests__/Step1Period.test.tsx:initialValue=null: le champ est vide,fr-hint-textannonce le format.mutation.mutateappelé avec la bonne valeur.~/test/setup.ts.<Step1Period initialValue={declaration.endOfReferencePeriod} declarationYear={declaration.year} />àcase 1:.Scénarios de test
fr-hint-text. Test unitaire vérifie la présence de ce hint +aria-describedby.Références visuelles
Desktop

Mobile

Annexe pipeline (lecture locale par code-dev / design-validator) :
/tmp/egapro-mocks/epic-3287/screenshots/step-1-periode-desktop.png/tmp/egapro-mocks/epic-3287/screenshots/step-1-periode-mobile.pngCritères d'acceptation
Step1Periodaffiche lefr-highlight, le<label>/fr-hint-textau format demandé, le bouton secondaire d'auto-remplissage etFormActions/representation-equilibree/etape/2pnpm typecheck+pnpm lint:check+pnpm format:check+pnpm testvertsstep-1-periode-*.png