Files
planflow/src/app/(app)/reglages/etiquettes/LabelForms.tsx
T
MichaelandClaude Opus 5 527ea2e78a Ouvrir les référentiels au paramétrage
Emplois, étiquettes et types d'absence vivaient en base sans écran : le seed
les posait, et rien ne permettait ensuite d'en ajouter un. Ils s'éditent
désormais depuis les réglages.

Trois choix portent la conformité plutôt que le confort :

- Archiver, jamais supprimer. Un emploi figure au registre du personnel, une
  étiquette colore des semaines closes, un type d'absence justifie des
  écritures de compteur. Supprimer l'un des trois rendrait illisible un dossier
  dont la conservation court encore.
- Le code Silae manquant est signalé. Un type sans code fait échouer l'export
  de la période ; l'écran le dit avant l'échéance de paie plutôt qu'après.
- La convention se réédite, elle ne se modifie pas. Chaque enregistrement crée
  une version datée : une paie de mars doit rester reproductible après un
  changement de seuil en juin. L'origine de chaque valeur — ordre public,
  convention, accord d'entreprise — est affichée, parce que les trois ne se
  corrigent pas de la même main.

Les mutations de types d'absence passent par settings.agreement.manage : le
catalogue §5 ne déclare pas de code dédié, et ces drapeaux relèvent du
paramétrage légal. Inventer une capacité aurait créé un droit sans rien
protéger de neuf.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 12:17:50 +02:00

86 lines
2.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client';
import { useActionState } from 'react';
import { Field, FormError, SubmitButton } from '@/components/ui/Form';
import { PersistentForm } from '@/components/ui/PersistentForm';
import { POSTE_CODES, POSTE_LABELS } from '@/lib/design/postes';
import {
createLabelAction,
updateLabelAction,
type ActionState,
} from '@/server/settings/labels';
const empty: ActionState = {};
function PaletteSelect({ defaultValue }: { defaultValue?: string }) {
return (
<label className="flex flex-col gap-1.5">
<span className="text-sm font-medium">Teinte</span>
<select
name="paletteKey"
defaultValue={defaultValue ?? POSTE_CODES[0]}
className="h-9 rounded-2 border border-line-2 bg-surface px-2 text-sm text-ink-1"
>
{POSTE_CODES.map((code) => (
<option key={code} value={code}>
{POSTE_LABELS[code]}
</option>
))}
</select>
</label>
);
}
export function AddLabelForm() {
const [state, action] = useActionState(createLabelAction, empty);
return (
<PersistentForm
action={action}
resetAfter={state.ok ? state : null}
className="flex flex-col gap-3"
>
<div className="flex flex-wrap items-end gap-3">
<Field
label="Code"
name="code"
required
maxLength={12}
placeholder="cai"
hint="Affiché sur le bloc de planning : la couleur ne porte jamais l’information seule."
/>
<Field label="Libellé" name="name" required maxLength={120} placeholder="Caisse" />
<PaletteSelect />
<SubmitButton>Ajouter l’étiquette</SubmitButton>
</div>
<FormError>{state.error}</FormError>
{state.ok ? (
<p className="text-xs text-ok-soft-ink">Étiquette enregistrée.</p>
) : null}
</PersistentForm>
);
}
export function EditLabelForm({
id,
name,
paletteKey,
}: {
id: string;
name: string;
paletteKey: string;
}) {
const [state, action] = useActionState(updateLabelAction, empty);
return (
<PersistentForm action={action} className="flex flex-1 flex-wrap items-end gap-2">
<input type="hidden" name="id" value={id} />
<Field label="Libellé" name="name" defaultValue={name} required maxLength={120} />
<PaletteSelect defaultValue={paletteKey} />
<SubmitButton size="sm">Enregistrer</SubmitButton>
<FormError>{state.error}</FormError>
</PersistentForm>
);
}