diff --git a/assets/css/style.css b/assets/css/style.css index 6eab59e..2f967eb 100644 --- a/assets/css/style.css +++ b/assets/css/style.css @@ -173,3 +173,32 @@ input[type="number"] { .fc-row--bank-holiday { background: #d9f7be; } + +/* Ligne de semaine contenant au moins un jour de vacances scolaires */ +.fc-row--school-holiday { + background-color: #fff5cc; +} + +/* Jour individuel en vacances scolaires (cellule) */ +.fc-day--school-holiday { + background-color: #ffe9a6; +} + +/* Tableau recap vacances scolaires */ +.fc-holidays-table { + width: 100%; + border-collapse: collapse; + font-size: 12px; + margin-top: 12px; +} + +.fc-holidays-table th, +.fc-holidays-table td { + border: 1px solid #d9e2ec; + padding: 4px 6px; + text-align: left; +} + +.fc-holidays-table th { + background-color: #f0f4f8; +} diff --git a/assets/js/family-calendar.js b/assets/js/family-calendar.js index faea965..5fde820 100644 --- a/assets/js/family-calendar.js +++ b/assets/js/family-calendar.js @@ -27,18 +27,17 @@ function getMonthNameFr(monthIndex) { } /** - * Calcule le numéro de semaine dans l'année (1..52/53), - * en prenant le lundi comme début de semaine. + * Calcule le n° de semaine dans l'année (1..), + * Semaine 1 = semaine contenant le 1er janvier, début au lundi. */ function getWeekOfYear(date) { const year = date.getFullYear(); const startOfYear = new Date(year, 0, 1); - // se placer au lundi de la semaine contenant le 1er janvier - const day = startOfYear.getDay() || 7; // dimanche=0 => 7 - const diffToMonday = day > 1 ? day - 1 : 0; - const firstMonday = new Date(year, 0, 1 - diffToMonday); + const dayOfWeek = startOfYear.getDay() || 7; // dimanche = 0 -> 7 + const diffToMonday = dayOfWeek === 1 ? 0 : dayOfWeek - 1; + const firstWeekMonday = new Date(year, 0, 1 - diffToMonday); - const diffMillis = date - firstMonday; + const diffMillis = date - firstWeekMonday; const diffDays = Math.floor(diffMillis / (1000 * 60 * 60 * 24)); return Math.floor(diffDays / 7) + 1; } @@ -99,12 +98,20 @@ function generateWeeks() { thu: thursday, fri: friday, }, + dayFlags: { + mon: { schoolHoliday: false }, + tue: { schoolHoliday: false }, + wed: { schoolHoliday: false }, + thu: { schoolHoliday: false }, + fri: { schoolHoliday: false }, + }, totals: { offCarole: 0, extraOffCarole: 0, centre: 0, avis: 0, }, + isSchoolHolidayWeek: false, alex: { total: 0, detail: "", @@ -123,68 +130,119 @@ function generateWeeks() { const weeks = generateWeeks(); -// === 3. Événements calendrier (exemple, plus tard ce sera ton UI/DB) === +// === 3. Événements & vacances scolaires === -/** - * Exemple de liste d'événements. Plus tard : - * - tu auras une UI pour ajouter/supprimer ces événements - * - tu les chargeras depuis/vers la DB. - */ -const events = [ - // Exemple : Carole off le 15/09/2025 - { date: "2025-09-15", type: "OFF_CAROLE", duration: 1 }, - // Exemple : Centre le 20/10/2025 - { date: "2025-10-20", type: "CENTRE", duration: 1 }, - // etc. -]; +const events = []; // on pourra y ajouter OFF_CAROLE, CENTRE, etc. plus tard -/** - * Recalcule les totaux par semaine à partir des events. - */ -function recomputeTotalsFromEvents(weeks, events) { - // reset - weeks.forEach((w) => { - w.totals.offCarole = 0; - w.totals.extraOffCarole = 0; - w.totals.centre = 0; - w.totals.avis = 0; +async function fetchSchoolHolidays(anneeScolaire, zoneLabel) { + const baseUrl = + "https://data.education.gouv.fr/api/explore/v2.1/catalog/datasets/fr-en-calendrier-scolaire/records"; + const where = `annee_scolaire='${anneeScolaire}' AND zones LIKE '%${zoneLabel}%'`; + const params = new URLSearchParams({ + where, + limit: "100", + order_by: "start_date", }); - events.forEach((evt) => { - const [y, m, d] = evt.date.split("-").map(Number); - const evtDate = new Date(y, m - 1, d); + const url = `${baseUrl}?${params.toString()}`; - // trouver la semaine qui contient evtDate (entre lundi et vendredi) - const week = weeks.find((w) => { - const md = w.dayDates.mon; - const fd = w.dayDates.fri; - return evtDate >= md && evtDate <= fd; - }); - if (!week) return; + const res = await fetch(url); + if (!res.ok) { + console.error("Erreur API vacances scolaires", res.status, res.statusText); + return []; + } - const dur = evt.duration || 1; + const data = await res.json(); + return data.results || []; +} - switch (evt.type) { - case "OFF_CAROLE": - week.totals.offCarole += dur; - break; - case "EXTRA_OFF_CAROLE": - week.totals.extraOffCarole += dur; - break; - case "CENTRE": - week.totals.centre += dur; - break; - case "AVIS": - week.totals.avis += dur; - break; - default: - break; +/** + * Ajoute les vacances scolaires comme événements de type VACANCES_SCOLAIRES + * ET remplit le tableau recap. + */ +function addSchoolHolidayEventsFromRecords(records, events) { + const tbody = document.querySelector("#schoolHolidaysTable tbody"); + if (tbody) tbody.innerHTML = ""; + + records.forEach((record) => { + const start = new Date(record.start_date); + const end = new Date(record.end_date); + + // Remplir le tableau recap + if (tbody) { + const tr = document.createElement("tr"); + const startStr = formatDayMonth(start) + "/" + start.getFullYear(); + const endStr = formatDayMonth(end) + "/" + end.getFullYear(); + + tr.innerHTML = ` +
Source : data.education.gouv.fr - calendrier officiel.
+| Période | +Du | +Au | +Zones | +Académies | +
|---|