Front : retrait des compétences, disponibilités en fenêtres horaires
Aligne le frontend sur le back-end (étape 14). - Types : suppression de `skill_codes` / `required_skill_codes` / `AvailabilityStatus` / `MISSING_REQUIRED_SKILL` ; ajout de `AvailabilityRead` / `AvailabilitySet` et de la surface API `availability` (list / replace / listEdition) + hooks associés. - Fiche bénévole : bloc « compétences » remplacé par un éditeur de disponibilités (plages date + heures libres, `PUT` en bloc). - Assistant d'import : plus de colonnes compétences ni disponibilités (mapping réduit à l'identité) ; rapport simplifié. - Grille des besoins : chaque candidat porte un badge de couverture (disponible / partiel / non déclaré) calculé sur ses fenêtres, et la liste est triée « disponibles d'abord ». Nouvel util `availabilityCoverage` / `uncoveredMinutes` dans `lib/planning`, portage du moteur back-end. - Mock : `state.availability` passe à des fenêtres `AvailabilityRead[]`, validation `OUTSIDE_AVAILABILITY` recalculée sur l'union des fenêtres, jeu de démo et import CSV adaptés. typecheck / lint / build / smoke au vert. 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
be51770b51
commit
36d108b47d
@@ -62,15 +62,12 @@
|
||||
"validation.SHIFT_OVERLAP": "Se chevauche avec un autre créneau",
|
||||
"validation.SHIFT_OVERLAP.at": "Déjà affecté sur {position} au même moment",
|
||||
"validation.SHIFT_OVERLAP.rule": "Deux créneaux d'un même bénévole se chevauchent.",
|
||||
"validation.OUTSIDE_AVAILABILITY": "Hors disponibilités déclarées",
|
||||
"validation.OUTSIDE_AVAILABILITY.unavailable": "Déclaré indisponible sur ce créneau",
|
||||
"validation.OUTSIDE_AVAILABILITY.rule": "Une demi-journée du créneau est indisponible ou sans déclaration.",
|
||||
"validation.OUTSIDE_AVAILABILITY": "Hors des disponibilités déclarées ({gap} non couvertes).",
|
||||
"validation.OUTSIDE_AVAILABILITY.rule": "Le créneau n'est pas entièrement couvert par les disponibilités déclarées.",
|
||||
"validation.DAILY_HOURS_EXCEEDED": "Plus de 8 h sur la journée ({hours})",
|
||||
"validation.DAILY_HOURS_EXCEEDED.rule": "Plus de 8 h 00 d'affectations cumulées sur une même journée.",
|
||||
"validation.INSUFFICIENT_REST": "Moins de 8 h de repos entre deux créneaux ({rest})",
|
||||
"validation.INSUFFICIENT_REST.rule": "Moins de 8 h 00 entre la fin d'un créneau et le début du suivant.",
|
||||
"validation.MISSING_REQUIRED_SKILL": "Compétence requise manquante : {skill}",
|
||||
"validation.MISSING_REQUIRED_SKILL.rule": "Le bénévole n'a pas une compétence requise par le créneau.",
|
||||
"grille.filter.day": "JOUR",
|
||||
"grille.filter.position": "POSTE",
|
||||
"grille.legend.critical": "SOUS-EFFECTIF CRITIQUE",
|
||||
@@ -163,15 +160,11 @@
|
||||
"config.vol.colName": "NOM",
|
||||
"config.vol.colPhone": "TÉLÉPHONE",
|
||||
"config.vol.colEmail": "EMAIL",
|
||||
"config.vol.colSkills": "COMPÉTENCES",
|
||||
"config.vol.ficheKicker": "FICHE BÉNÉVOLE",
|
||||
"config.vol.firstName": "PRÉNOM",
|
||||
"config.vol.lastName": "NOM",
|
||||
"config.vol.phone": "TÉLÉPHONE",
|
||||
"config.vol.email": "EMAIL (LIEN MAGIQUE)",
|
||||
"config.vol.skills": "COMPÉTENCES",
|
||||
"config.vol.noSkills": "Aucune compétence déclarée",
|
||||
"config.vol.skillPlaceholder": "Code (ex. CAISSE)",
|
||||
"config.vol.delete": "SUPPRIMER (RGPD — EFFACEMENT COMPLET)",
|
||||
"config.vol.deleteConfirm": "Supprimer définitivement ce bénévole et toutes ses données (disponibilités, affectations) ?",
|
||||
"config.vol.note": "Modifications enregistrées immédiatement via l'API. La suppression est un effacement complet en cascade (RGPD).",
|
||||
@@ -231,7 +224,6 @@
|
||||
"config.vol.field.email": "Email (lien magique)",
|
||||
"config.vol.field.phone": "Téléphone",
|
||||
"config.vol.field.comment": "Commentaire",
|
||||
"config.vol.field.skills": "Compétences",
|
||||
"config.vol.addTitle": "NOUVEAU BÉNÉVOLE",
|
||||
"config.vol.addHint": "Le bénévole reçoit un accès par lien magique uniquement si un email est renseigné.",
|
||||
"config.vol.create": "CRÉER LE BÉNÉVOLE",
|
||||
@@ -248,12 +240,6 @@
|
||||
"config.vol.wiz.mapTitle": "ASSOCIER LES COLONNES",
|
||||
"config.vol.wiz.mapHint": "« Prénom » et « Nom » sont obligatoires. Laissez « — » pour ignorer une colonne.",
|
||||
"config.vol.wiz.ignore": "—",
|
||||
"config.vol.wiz.availTitle": "DISPONIBILITÉS (OPTIONNEL)",
|
||||
"config.vol.wiz.availHint": "Associez une colonne du fichier à une date et une demi-journée pour importer les disponibilités déclarées.",
|
||||
"config.vol.wiz.availAdd": "AJOUTER UNE COLONNE DE DISPONIBILITÉ",
|
||||
"config.vol.wiz.availColumn": "Colonne",
|
||||
"config.vol.wiz.availDate": "Date",
|
||||
"config.vol.wiz.availPart": "Demi-journée",
|
||||
"config.vol.wiz.mapMissing": "Associez au moins les colonnes « Prénom » et « Nom ».",
|
||||
"config.vol.wiz.simulate": "SIMULER",
|
||||
"config.vol.wiz.runImport": "IMPORTER POUR DE VRAI",
|
||||
@@ -264,8 +250,6 @@
|
||||
"config.vol.wiz.created": "{count} créé(s)",
|
||||
"config.vol.wiz.updated": "{count} mis à jour",
|
||||
"config.vol.wiz.skipped": "{count} ignoré(s)",
|
||||
"config.vol.wiz.availWritten": "{count} disponibilité(s)",
|
||||
"config.vol.wiz.skillsCreated": "Compétences créées : {list}",
|
||||
"config.vol.wiz.rowsWithIssues": "LIGNES AVEC REMARQUES",
|
||||
"config.vol.wiz.line": "Ligne {line}",
|
||||
"config.vol.wiz.noIssues": "Aucune remarque : tout est prêt à être importé.",
|
||||
@@ -278,17 +262,12 @@
|
||||
"import.mapping.invalid": "Le paramétrage des colonnes est invalide.",
|
||||
"import.mapping.required_field_missing": "Le champ « {field} » doit être associé à une colonne.",
|
||||
"import.mapping.column_not_found": "La colonne « {column} » est absente du fichier.",
|
||||
"import.mapping.unknown_day_part": "Demi-journée « {day_part_code} » inconnue (colonne « {column} »).",
|
||||
"import.mapping.date_outside_edition": "La date {date} de la colonne « {column} » est hors des dates de l’édition.",
|
||||
"import.mapping.duplicate_availability_column": "La colonne « {column} » est associée plusieurs fois.",
|
||||
"import.row.missing_required_field": "Champ obligatoire manquant : {field}.",
|
||||
"import.row.invalid_email": "Adresse email invalide : {value}.",
|
||||
"import.row.duplicate_email_in_file": "Email déjà présent à la ligne {first_line} du fichier.",
|
||||
"import.row.duplicate_name_in_file": "Nom et prénom déjà présents à la ligne {first_line} du fichier.",
|
||||
"import.row.updated_existing": "Bénévole existant mis à jour.",
|
||||
"import.row.possible_duplicate_name": "Un bénévole portant le même nom existe déjà dans l’édition.",
|
||||
"import.row.skill_created": "Nouvelle compétence créée : {label}.",
|
||||
"import.row.unknown_availability_value": "Valeur de disponibilité non comprise « {value} » (colonne « {column} »).",
|
||||
"config.tab.artists": "PROGRAMMATION",
|
||||
"config.artists.title": "PROGRAMMATION",
|
||||
"config.artists.hint": "La liste des artistes de l'édition, jour par jour. Les bénévoles y choisissent ceux qu'ils veulent voir depuis leur fiche.",
|
||||
@@ -301,5 +280,18 @@
|
||||
"config.vol.noArtists": "Aucun artiste choisi",
|
||||
"config.vol.noPositions": "Aucun poste choisi",
|
||||
"config.vol.pickArtist": "Ajouter un artiste…",
|
||||
"config.vol.pickPosition": "Ajouter un poste…"
|
||||
"config.vol.pickPosition": "Ajouter un poste…",
|
||||
"config.vol.colWishes": "VŒUX",
|
||||
"config.vol.wishesCount": "{count} vœu(x)",
|
||||
"config.vol.addAvailabilityHint": "Les disponibilités se renseignent sur la fiche du bénévole, une fois celui-ci créé.",
|
||||
"config.vol.avail.title": "Disponibilités",
|
||||
"config.vol.avail.hint": "Plages horaires où le bénévole peut venir. Une heure de fin ≤ début signifie que la plage se termine le lendemain.",
|
||||
"config.vol.avail.none": "Aucune disponibilité déclarée",
|
||||
"config.vol.avail.add": "Ajouter une plage",
|
||||
"config.vol.avail.save": "Enregistrer les disponibilités",
|
||||
"grille.panel.coverage.full": "Disponible",
|
||||
"grille.panel.coverage.partial": "Partiellement dispo",
|
||||
"grille.panel.coverage.none": "Dispo non déclarée",
|
||||
"availability.date_outside_edition": "Cette date est hors des dates de l'édition.",
|
||||
"availability.empty_window": "Une plage doit avoir un début et une fin différents."
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user