diff --git a/assets/js/family-calendar.js b/assets/js/family-calendar.js
index f390c0f..faea965 100644
--- a/assets/js/family-calendar.js
+++ b/assets/js/family-calendar.js
@@ -2,18 +2,12 @@
// === 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",
@@ -33,22 +27,29 @@ function getMonthNameFr(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 }
+ * Calcule le numéro de semaine dans l'année (1..52/53),
+ * en prenant le lundi comme début de semaine.
*/
+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 diffMillis = date - firstMonday;
+ const diffDays = Math.floor(diffMillis / (1000 * 60 * 60 * 24));
+ return Math.floor(diffDays / 7) + 1;
+}
+
+// === 2. Génération des semaines ===
+
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)
+ const start = new Date(2025, 8, 1); // 1er sept 2025
+ const end = new Date(2026, 7, 31); // 31 aout 2026
let current = new Date(start);
@@ -58,8 +59,6 @@ function generateWeeks() {
current.setDate(current.getDate() + 1);
}
- let weekCount = 1;
-
while (current <= end) {
const monday = new Date(current);
const tuesday = new Date(current);
@@ -71,15 +70,21 @@ function generateWeeks() {
const friday = new Date(current);
friday.setDate(monday.getDate() + 4);
- const monthIndex = monday.getMonth();
const year = monday.getFullYear();
+ const weekOfYear = getWeekOfYear(monday);
+ const weekId = `${year}-W${String(weekOfYear).padStart(2, "0")}`;
+
+ const monthIndex = monday.getMonth();
const monthKey = `${year}-${String(monthIndex + 1).padStart(2, "0")}`;
const monthName = getMonthNameFr(monthIndex);
weeks.push({
+ id: weekId,
+ year,
+ weekOfYear,
monthKey,
monthName,
- weekLabel: `W${weekCount}`,
+ weekLabel: `W${weekOfYear}`,
days: {
mon: formatDayMonth(monday),
tue: formatDayMonth(tuesday),
@@ -87,10 +92,19 @@ function generateWeeks() {
thu: formatDayMonth(thursday),
fri: formatDayMonth(friday),
},
- offCarole: 0,
- extraOffCarole: 0,
- centre: 0,
- avis: 0,
+ dayDates: {
+ mon: monday,
+ tue: tuesday,
+ wed: wednesday,
+ thu: thursday,
+ fri: friday,
+ },
+ totals: {
+ offCarole: 0,
+ extraOffCarole: 0,
+ centre: 0,
+ avis: 0,
+ },
alex: {
total: 0,
detail: "",
@@ -102,7 +116,6 @@ function generateWeeks() {
});
current.setDate(current.getDate() + 7);
- weekCount++;
}
return weeks;
@@ -110,7 +123,70 @@ function generateWeeks() {
const weeks = generateWeeks();
-// === 2. Calcul des rowspans pour la colonne Mois ===
+// === 3. Événements calendrier (exemple, plus tard ce sera ton UI/DB) ===
+
+/**
+ * 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.
+];
+
+/**
+ * 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;
+ });
+
+ events.forEach((evt) => {
+ const [y, m, d] = evt.date.split("-").map(Number);
+ const evtDate = new Date(y, m - 1, d);
+
+ // 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 dur = evt.duration || 1;
+
+ 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;
+ }
+ });
+}
+
+// première agrégation
+recomputeTotalsFromEvents(weeks, events);
+
+// === 4. Calcul des rowspans pour la colonne Mois ===
function computeMonthSpans(weeks) {
const counts = {};
@@ -122,7 +198,7 @@ function computeMonthSpans(weeks) {
const monthSpans = computeMonthSpans(weeks);
-// === 3. Rendu du tableau ===
+// === 5. Rendu du tableau ===
function renderTable() {
const planningBody = document.getElementById("planningBody");
@@ -132,16 +208,16 @@ function renderTable() {
const showOnlyCaroleOff =
document.getElementById("showOnlyCaroleOff")?.checked;
- // showOnlySchoolHoliday est ignore pour l'instant
+ // showOnlySchoolHoliday est ignoré pour l'instant
- const monthRowRendered = {}; // monthKey -> bool
+ const monthRowRendered = {};
- weeks.forEach((week, index) => {
- if (showOnlyCaroleOff && week.offCarole === 0) return;
+ weeks.forEach((week) => {
+ if (showOnlyCaroleOff && week.totals.offCarole === 0) return;
const tr = document.createElement("tr");
- // Colonne Mois avec rowspan uniquement pour la 1ere ligne du mois
+ // Colonne Mois (rowspan sur toutes les semaines du mois)
if (!monthRowRendered[week.monthKey]) {
monthRowRendered[week.monthKey] = true;
const tdMonth = document.createElement("td");
@@ -150,108 +226,62 @@ function renderTable() {
tr.appendChild(tdMonth);
}
- // Colonne Semaine
+ // Semaine
const tdWeek = document.createElement("td");
tdWeek.textContent = week.weekLabel;
tr.appendChild(tdWeek);
- // Jours Lundi -> Vendredi
+ // Jours
["mon", "tue", "wed", "thu", "fri"].forEach((dayKey) => {
const td = document.createElement("td");
td.textContent = week.days[dayKey];
tr.appendChild(td);
});
- // # Off Carole
+ // Totaux # Off Carole, # Extra off, #Centre, #Avis
const tdOff = document.createElement("td");
- tdOff.innerHTML = ``;
+ tdOff.textContent = week.totals.offCarole.toFixed(2).replace(/\.00$/, "");
tr.appendChild(tdOff);
- // # Extra off Carole
const tdExtraOff = document.createElement("td");
- tdExtraOff.innerHTML = ``;
+ tdExtraOff.textContent = week.totals.extraOffCarole
+ .toFixed(2)
+ .replace(/\.00$/, "");
tr.appendChild(tdExtraOff);
- // #Centre
const tdCentre = document.createElement("td");
- tdCentre.innerHTML = ``;
+ tdCentre.textContent = week.totals.centre.toFixed(2).replace(/\.00$/, "");
tr.appendChild(tdCentre);
- // #Avis
const tdAvis = document.createElement("td");
- tdAvis.innerHTML = ``;
+ tdAvis.textContent = week.totals.avis.toFixed(2).replace(/\.00$/, "");
tr.appendChild(tdAvis);
- // Alex total & détail
+ // Alex total & détail (pour l'instant, juste placeholders)
const tdAlexTotal = document.createElement("td");
- tdAlexTotal.textContent = week.alex.total.toFixed
- ? week.alex.total.toFixed(2)
- : week.alex.total;
+ tdAlexTotal.textContent = week.alex.total.toFixed(2).replace(/\.00$/, "");
tr.appendChild(tdAlexTotal);
const tdAlexDetail = document.createElement("td");
- tdAlexDetail.innerHTML = ``;
+ tdAlexDetail.textContent = week.alex.detail || "";
tr.appendChild(tdAlexDetail);
// Laia total & détail
const tdLaiaTotal = document.createElement("td");
- tdLaiaTotal.textContent = week.laia.total.toFixed
- ? week.laia.total.toFixed(2)
- : week.laia.total;
+ tdLaiaTotal.textContent = week.laia.total.toFixed(2).replace(/\.00$/, "");
tr.appendChild(tdLaiaTotal);
const tdLaiaDetail = document.createElement("td");
- tdLaiaDetail.innerHTML = ``;
+ tdLaiaDetail.textContent = week.laia.detail || "";
tr.appendChild(tdLaiaDetail);
planningBody.appendChild(tr);
});
- attachInputListeners();
updateSummary();
}
-// === 4. Listeners sur les inputs ===
-
-function attachInputListeners() {
- const planningBody = document.getElementById("planningBody");
- if (!planningBody) return;
-
- planningBody.querySelectorAll("input").forEach((input) => {
- input.addEventListener("change", (e) => {
- const weekIndex = parseInt(e.target.dataset.week, 10);
- const field = e.target.dataset.field;
- const value =
- e.target.type === "number"
- ? parseFloat(e.target.value || "0")
- : e.target.value;
-
- if (Number.isNaN(weekIndex) || !weeks[weekIndex]) return;
-
- if (
- field === "offCarole" ||
- field === "extraOffCarole" ||
- field === "centre" ||
- field === "avis"
- ) {
- weeks[weekIndex][field] = value;
- } else if (field === "alex.detail") {
- weeks[weekIndex].alex.detail = value;
- } else if (field === "laia.detail") {
- weeks[weekIndex].laia.detail = value;
- }
-
- // plus tard : calculer alex.total / laia.total en fonction des CP/RTT/JA
- updateSummary();
- });
- });
-}
-
-// === 5. Résumé (pour l'instant, 0 utilisés) ===
+// === 6. Résumé (encore 0 utilisés pour l’instant) ===
function updateSummary() {
const summaryDiv = document.getElementById("summaryText");
@@ -277,7 +307,6 @@ function updateSummary() {
document.getElementById("laiaJaInit")?.value || "0"
);
- // Pour l'instant, on n'a pas encore branché les CP/RTT/JA par semaine
const alexCpUsed = 0;
const alexRttUsed = 0;
const alexJaUsed = 0;
@@ -319,12 +348,11 @@ function updateSummary() {
`;
}
-// === 6. Init ===
+// === 7. Init ===
function initFamilyCalendar() {
if (!document.getElementById("planningBody")) return;
- // Soldes initiaux
[
"alexCpInit",
"alexRttInit",
@@ -337,7 +365,6 @@ function initFamilyCalendar() {
if (el) el.addEventListener("change", updateSummary);
});
- // Filtres (pour l'instant seul showOnlyCaroleOff a un effet)
const showOnlyCaroleOff = document.getElementById("showOnlyCaroleOff");
if (showOnlyCaroleOff) {
showOnlyCaroleOff.addEventListener("change", renderTable);
diff --git a/family-calendar.php b/family-calendar.php
index e558023..2f1e807 100644
--- a/family-calendar.php
+++ b/family-calendar.php
@@ -111,5 +111,6 @@ require __DIR__ . '/header.php';
+