diff --git a/assets/js/family-calendar.js b/assets/js/family-calendar.js index 5c8f5d3..f390c0f 100644 --- a/assets/js/family-calendar.js +++ b/assets/js/family-calendar.js @@ -1,48 +1,128 @@ // assets/js/family-calendar.js -const weeks = [ - { - month: "September", - code: "W36", - dates: "01/09 - 07/09", - caroleOffDays: 0, - isSchoolHoliday: false, - isBankHoliday: false, - alex: { cp: 0, rtt: 0, ja: 0 }, - laia: { cp: 0, rtt: 0, ja: 0 }, - }, - { - month: "September", - code: "W38", - dates: "15/09 - 21/09", - caroleOffDays: 2, - isSchoolHoliday: false, - isBankHoliday: false, - alex: { cp: 0, rtt: 0, ja: 0 }, - laia: { cp: 0, rtt: 0, ja: 0 }, - }, - { - month: "October", - code: "W40", - dates: "29/09 - 05/10", - caroleOffDays: 0, - isSchoolHoliday: false, - isBankHoliday: false, - alex: { cp: 0, rtt: 0, ja: 0 }, - laia: { cp: 0, rtt: 0, ja: 0 }, - }, - { - month: "August", - code: "W32", - dates: "03/08 - 09/08", - caroleOffDays: 5, - isSchoolHoliday: true, - isBankHoliday: false, - alex: { cp: 0, rtt: 0, ja: 0 }, - laia: { cp: 0, rtt: 0, ja: 0 }, - }, - // TODO: compléter le reste des semaines W36 → W35 -]; +// === 1. Utilitaires dates === + +/** + * Formate une Date en "dd/mm". + */ +function formatDayMonth(date) { + const d = String(date.getDate()).padStart(2, "0"); + const m = String(date.getMonth() + 1).padStart(2, "0"); + return `${d}/${m}`; +} + +/** + * Retourne le nom de mois en français à partir du monthIndex JS (0..11). + */ +function getMonthNameFr(monthIndex) { + const map = { + 0: "Janvier", + 1: "Fevrier", + 2: "Mars", + 3: "Avril", + 4: "Mai", + 5: "Juin", + 6: "Juillet", + 7: "Aout", + 8: "Septembre", + 9: "Octobre", + 10: "Novembre", + 11: "Decembre", + }; + return map[monthIndex] || ""; +} + +/** + * Genere les semaines de la 1ere semaine de septembre 2025 + * a la derniere semaine d'aout 2026. + * Chaque element contient: + * - monthKey (ex: "2025-09") + * - monthName (ex: "Septembre") + * - weekLabel (W1, W2, ...) + * - days: { mon, tue, wed, thu, fri } en "dd/mm" + * - offCarole, extraOffCarole, centre, avis + * - alex: { total, detail } + * - laia: { total, detail } + */ +function generateWeeks() { + const weeks = []; + + const start = new Date(2025, 8, 1); // 1er septembre 2025 (mois 8 car 0-based) + const end = new Date(2026, 7, 31); // 31 aout 2026 (mois 7) + + let current = new Date(start); + + // se placer sur le premier lundi >= 1er septembre 2025 + while (current.getDay() !== 1) { + // 1 = lundi + current.setDate(current.getDate() + 1); + } + + let weekCount = 1; + + while (current <= end) { + const monday = new Date(current); + const tuesday = new Date(current); + tuesday.setDate(monday.getDate() + 1); + const wednesday = new Date(current); + wednesday.setDate(monday.getDate() + 2); + const thursday = new Date(current); + thursday.setDate(monday.getDate() + 3); + const friday = new Date(current); + friday.setDate(monday.getDate() + 4); + + const monthIndex = monday.getMonth(); + const year = monday.getFullYear(); + const monthKey = `${year}-${String(monthIndex + 1).padStart(2, "0")}`; + const monthName = getMonthNameFr(monthIndex); + + weeks.push({ + monthKey, + monthName, + weekLabel: `W${weekCount}`, + days: { + mon: formatDayMonth(monday), + tue: formatDayMonth(tuesday), + wed: formatDayMonth(wednesday), + thu: formatDayMonth(thursday), + fri: formatDayMonth(friday), + }, + offCarole: 0, + extraOffCarole: 0, + centre: 0, + avis: 0, + alex: { + total: 0, + detail: "", + }, + laia: { + total: 0, + detail: "", + }, + }); + + current.setDate(current.getDate() + 7); + weekCount++; + } + + return weeks; +} + +const weeks = generateWeeks(); + +// === 2. Calcul des rowspans pour la colonne Mois === + +function computeMonthSpans(weeks) { + const counts = {}; + weeks.forEach((w) => { + counts[w.monthKey] = (counts[w.monthKey] || 0) + 1; + }); + return counts; +} + +const monthSpans = computeMonthSpans(weeks); + +// === 3. Rendu du tableau === function renderTable() { const planningBody = document.getElementById("planningBody"); @@ -52,46 +132,81 @@ function renderTable() { const showOnlyCaroleOff = document.getElementById("showOnlyCaroleOff")?.checked; - const showOnlySchoolHoliday = document.getElementById( - "showOnlySchoolHoliday" - )?.checked; + // showOnlySchoolHoliday est ignore pour l'instant + + const monthRowRendered = {}; // monthKey -> bool weeks.forEach((week, index) => { - if (showOnlyCaroleOff && week.caroleOffDays === 0) return; - if (showOnlySchoolHoliday && !week.isSchoolHoliday) return; + if (showOnlyCaroleOff && week.offCarole === 0) return; const tr = document.createElement("tr"); - if (week.caroleOffDays > 0) tr.classList.add("fc-row--carole-off"); - if (week.isSchoolHoliday) tr.classList.add("fc-row--school-holiday"); - if (week.isBankHoliday) tr.classList.add("fc-row--bank-holiday"); + // Colonne Mois avec rowspan uniquement pour la 1ere ligne du mois + if (!monthRowRendered[week.monthKey]) { + monthRowRendered[week.monthKey] = true; + const tdMonth = document.createElement("td"); + tdMonth.rowSpan = monthSpans[week.monthKey] || 1; + tdMonth.textContent = week.monthName; + tr.appendChild(tdMonth); + } - tr.innerHTML = ` -
Alex
- CP utilisés : ${alexCpUsed.toFixed(2)} / ${alexCpInit.toFixed(
+ CP utilises : ${alexCpUsed.toFixed(2)} / ${alexCpInit.toFixed(
2
)} (reste ${alexCpLeft.toFixed(2)})
- RTT utilisés : ${alexRttUsed.toFixed(2)} / ${alexRttInit.toFixed(
+ RTT utilises : ${alexRttUsed.toFixed(2)} / ${alexRttInit.toFixed(
2
)} (reste ${alexRttLeft.toFixed(2)})
- JA utilisés : ${alexJaUsed.toFixed(2)} / ${alexJaInit.toFixed(
+ JA utilises : ${alexJaUsed.toFixed(2)} / ${alexJaInit.toFixed(
2
)} (reste ${alexJaLeft.toFixed(2)})
Laia
- CP utilisés : ${laiaCpUsed.toFixed(2)} / ${laiaCpInit.toFixed(
+ CP utilises : ${laiaCpUsed.toFixed(2)} / ${laiaCpInit.toFixed(
2
)} (reste ${laiaCpLeft.toFixed(2)})
- RTT utilisés : ${laiaRttUsed.toFixed(2)} / ${laiaRttInit.toFixed(
+ RTT utilises : ${laiaRttUsed.toFixed(2)} / ${laiaRttInit.toFixed(
2
)} (reste ${laiaRttLeft.toFixed(2)})
- JA utilisés : ${laiaJaUsed.toFixed(2)} / ${laiaJaInit.toFixed(2)})