Import bénévoles : couche API (analyse + exécution) et mock CSV

- `PlanningApi.imports.analyze/execute` : envoi `multipart/form-data`
  (le client HTTP laisse le navigateur poser le Content-Type).
- Types miroir des schémas back-end (`ImportAnalyzeResponse`,
  `ImportMapping`, `ImportReport`, `ImportRowReport`, `ImportIssue`…).
- Hooks `useAnalyzeImport` / `useExecuteImport` ; l'exécution réelle
  invalide les bénévoles et le planning.
- Implémentation mock (mode démo) : lecture CSV, suggestion de mapping,
  simulation/exécution avec rapport ligne par ligne. Excel renvoie
  `import.error.xlsx_demo_only`.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017uUsRg7XzopkCPWimwg9ZM
This commit is contained in:
AdamThomas
2026-09-10 21:55:50 +02:00
co-authored by Claude Sonnet 5
parent 06f8736c33
commit df8d6733db
5 changed files with 505 additions and 1 deletions
+23
View File
@@ -13,6 +13,7 @@ import type {
DayPartCreate,
DayPartUpdate,
EditionUpdate,
ImportMapping,
PlanningNotificationRequest,
PositionCreate,
PositionUpdate,
@@ -197,6 +198,28 @@ export function useDeleteVolunteer() {
});
}
/** Import de bénévoles — phase 1 : analyse du fichier. */
export function useAnalyzeImport() {
return useMutation({
mutationFn: (file: File) => api.imports.analyze(edition, file),
});
}
/** Import de bénévoles — phase 2 : simulation ou exécution réelle. */
export function useExecuteImport() {
const invalidate = useInvalidate();
return useMutation({
mutationFn: ({ file, mapping }: { file: File; mapping: ImportMapping }) =>
api.imports.execute(edition, file, mapping),
onSuccess: (report) => {
if (!report.dry_run) {
invalidate.volunteers();
invalidate.planning();
}
},
});
}
export function useCreatePosition() {
const invalidate = useInvalidate();
return useMutation({