Front : programmation des artistes et vœux des bénévoles
Aligne le frontend sur le back-end (étape 13). - Types : retrait de `tshirt_size` / `diet` (Volunteer et mapping d'import) ; ajout de `ArtistRead/Create/Update` et des champs `artist_ids` / `wished_position_ids` sur la fiche bénévole. - Surface API `artists` (HTTP + mock) et hooks `useArtists` / `useCreateArtist` / `useUpdateArtist` / `useDeleteArtist`. - Nouvel onglet Configuration « Programmation » : liste d'artistes éditable, colonne par jour de l'édition (création, renommage, suppression ; 409 doublon, 422 nom vide). - Fiche bénévole & formulaire d'ajout manuel : champs t-shirt / régime retirés, sélecteurs « Artistes à voir » et « Postes souhaités » (puces retirables, 422 si id étranger). - Mock : jeu de démo enrichi (2 artistes par jour, vœux aléatoires), cascade sur suppression d'artiste / de poste, import CSV sans t-shirt / régime. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017uUsRg7XzopkCPWimwg9ZM
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
24caece7df
commit
81609eecc5
@@ -7,6 +7,8 @@ import {
|
||||
|
||||
import { EDITION_ID, api } from './index';
|
||||
import type {
|
||||
ArtistCreate,
|
||||
ArtistUpdate,
|
||||
AssignmentCreate,
|
||||
AssignmentUpdate,
|
||||
AssignmentValidateResult,
|
||||
@@ -48,6 +50,10 @@ export function useDayParts() {
|
||||
return useQuery({ queryKey: ['dayParts', edition], queryFn: () => api.dayParts.list(edition) });
|
||||
}
|
||||
|
||||
export function useArtists() {
|
||||
return useQuery({ queryKey: ['artists', edition], queryFn: () => api.artists.list(edition) });
|
||||
}
|
||||
|
||||
export function useVolunteers(options?: { enabled?: boolean }) {
|
||||
return useQuery({
|
||||
queryKey: queryKeys.volunteers,
|
||||
@@ -111,6 +117,7 @@ function useInvalidate() {
|
||||
const client = useQueryClient();
|
||||
return {
|
||||
volunteers: () => client.invalidateQueries({ queryKey: ['volunteers', edition] }),
|
||||
artists: () => client.invalidateQueries({ queryKey: ['artists', edition] }),
|
||||
positions: () => client.invalidateQueries({ queryKey: ['positions', edition] }),
|
||||
shifts: () => client.invalidateQueries({ queryKey: ['shifts', edition] }),
|
||||
planning: () => {
|
||||
@@ -170,6 +177,35 @@ export function useGenerateShifts() {
|
||||
});
|
||||
}
|
||||
|
||||
export function useCreateArtist() {
|
||||
const invalidate = useInvalidate();
|
||||
return useMutation({
|
||||
mutationFn: (body: ArtistCreate) => api.artists.create(edition, body),
|
||||
onSuccess: invalidate.artists,
|
||||
});
|
||||
}
|
||||
|
||||
export function useUpdateArtist() {
|
||||
const invalidate = useInvalidate();
|
||||
return useMutation({
|
||||
mutationFn: ({ id, body }: { id: string; body: ArtistUpdate }) =>
|
||||
api.artists.update(edition, id, body),
|
||||
onSuccess: invalidate.artists,
|
||||
});
|
||||
}
|
||||
|
||||
export function useDeleteArtist() {
|
||||
const invalidate = useInvalidate();
|
||||
return useMutation({
|
||||
mutationFn: (id: string) => api.artists.remove(edition, id),
|
||||
onSuccess: () => {
|
||||
invalidate.artists();
|
||||
// La suppression retire l'artiste des vœux des bénévoles.
|
||||
invalidate.volunteers();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function useCreateVolunteer() {
|
||||
const invalidate = useInvalidate();
|
||||
return useMutation({
|
||||
@@ -252,6 +288,8 @@ export function useDeletePosition() {
|
||||
invalidate.positions();
|
||||
invalidate.shifts();
|
||||
invalidate.planning();
|
||||
// Le poste disparaît des vœux des bénévoles.
|
||||
invalidate.volunteers();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user