// Bellia — Module RH : planning visuel hebdomadaire avec drag & drop
const EMPLOYEES = [
{ id: 'e1', name: 'Aïcha Benamar', role: 'Chef de cuisine', dept: 'cuisine', initials: 'AB', c: '#C97849', contractH: 39 },
{ id: 'e2', name: 'Pierre Dubois', role: 'Second de cuisine', dept: 'cuisine', initials: 'PD', c: '#7FB069', contractH: 39 },
{ id: 'e3', name: 'Léa Moreau', role: 'Cheffe de partie', dept: 'cuisine', initials: 'LM', c: '#D9923B', contractH: 35 },
{ id: 'e4', name: 'Karim Bensalem', role: 'Cuisinier', dept: 'cuisine', initials: 'KB', c: '#5B8DEF', contractH: 35 },
{ id: 'e5', name: 'Sofia Lopez', role: 'Commis', dept: 'cuisine', initials: 'SL', c: '#A87AC9', contractH: 35 },
{ id: 'e6', name: 'Marc Chevalier', role: 'Plongeur', dept: 'cuisine', initials: 'MC', c: '#7BA6B5', contractH: 24 },
{ id: 'e7', name: 'Clara Bertin', role: 'Cheffe de rang', dept: 'salle', initials: 'CB', c: '#C97849', contractH: 39 },
{ id: 'e8', name: 'Tom Lefèvre', role: 'Serveur', dept: 'salle', initials: 'TL', c: '#7FB069', contractH: 35 },
{ id: 'e9', name: 'Yasmine Ferrand', role: 'Serveuse', dept: 'salle', initials: 'YF', c: '#D9923B', contractH: 35 },
{ id: 'e10', name: 'Hugo Martin', role: 'Runner', dept: 'salle', initials: 'HM', c: '#5B8DEF', contractH: 24 },
];
const DAYS = ['Lun. 11', 'Mar. 12', 'Mer. 13', 'Jeu. 14', 'Ven. 15', 'Sam. 16', 'Dim. 17'];
const SHIFT_TYPES = {
midi: { l: 'Midi', start: '11:00', end: '15:00', hours: 4, bg: C.orangeWh, fg: C.orangeDp, bar: C.orange },
soir: { l: 'Soir', start: '18:30', end: '23:00', hours: 4.5, bg: '#F1E7D5', fg: C.ink2, bar: C.ink2 },
continu: { l: 'Continu', start: '11:00', end: '23:00', hours: 9, bg: '#FBE9D5', fg: C.warn, bar: C.warn },
prep: { l: 'Prep.', start: '08:00', end: '12:00', hours: 4, bg: C.okSft, fg: C.ok, bar: C.ok },
off: { l: 'Repos', start: '', end: '', hours: 0, bg: 'transparent', fg: C.mute, bar: C.line },
};
// Génère un planning de base
const initShifts = () => {
const out = {};
EMPLOYEES.forEach(e => {
out[e.id] = DAYS.map((_, di) => {
const isWeekend = di >= 5;
const isMonday = di === 0;
if (isMonday && e.id === 'e6') return 'off';
if (isMonday && (e.id === 'e3' || e.id === 'e8')) return 'off';
if (di === 2 && e.id === 'e5') return 'off';
if (di === 3 && e.id === 'e10') return 'off';
if (di === 4 && e.id === 'e2') return 'off';
if (e.dept === 'cuisine') {
if (e.id === 'e1' || e.id === 'e2') return isWeekend ? 'continu' : (di % 2 === 0 ? 'midi' : 'soir');
if (e.id === 'e6') return isWeekend ? 'soir' : 'midi';
return isWeekend ? 'continu' : (di % 2 === 1 ? 'soir' : 'midi');
} else {
if (e.id === 'e7') return isWeekend ? 'continu' : (di % 2 === 0 ? 'soir' : 'midi');
return isWeekend ? 'continu' : (di % 2 === 1 ? 'midi' : 'soir');
}
});
});
return out;
};
const RhScreen = ({ onNav }) => {
const [shifts, setShifts] = React.useState(initShifts);
const [dept, setDept] = React.useState('tous');
const [dragging, setDragging] = React.useState(null); // { type, fromEmp?, fromDay? }
const [hover, setHover] = React.useState(null); // { emp, day }
const [selectedShift, setSelectedShift] = React.useState(null); // { emp, day }
const employees = EMPLOYEES.filter(e => dept === 'tous' || e.dept === dept);
// Compute totals
const empHours = React.useMemo(() => {
const out = {};
EMPLOYEES.forEach(e => {
out[e.id] = (shifts[e.id] || []).reduce((a, s) => a + SHIFT_TYPES[s].hours, 0);
});
return out;
}, [shifts]);
const dayCoverage = React.useMemo(() => DAYS.map((_, di) => {
let midi = 0, soir = 0;
EMPLOYEES.forEach(e => {
const s = shifts[e.id]?.[di];
if (s === 'midi' || s === 'continu' || s === 'prep') midi++;
if (s === 'soir' || s === 'continu') soir++;
});
return { midi, soir };
}), [shifts]);
const totalHours = Object.values(empHours).reduce((a, b) => a + b, 0);
const totalMass = totalHours * 16.5; // taux moyen indicatif
// DnD handlers
const handleDrop = (toEmp, toDay) => {
if (!dragging) return;
setShifts(prev => {
const next = { ...prev, [toEmp]: [...prev[toEmp]] };
if (dragging.fromEmp != null && dragging.fromDay != null) {
// swap
const fromShift = next[dragging.fromEmp]?.[dragging.fromDay];
const toShift = next[toEmp]?.[toDay];
next[dragging.fromEmp] = [...next[dragging.fromEmp]];
next[dragging.fromEmp][dragging.fromDay] = toShift;
next[toEmp][toDay] = fromShift;
} else {
next[toEmp][toDay] = dragging.type;
}
return next;
});
setDragging(null);
setHover(null);
};
return (