Auto-commit for deploy to production - 2025-12-11 15:21:23

This commit is contained in:
Cedric
2025-12-11 15:21:23 +01:00
parent 0de792781a
commit a08dc62ba6
3 changed files with 265 additions and 2 deletions
+70
View File
@@ -375,6 +375,13 @@ input[type="number"] {
border: 1px solid #d9e2ec; border: 1px solid #d9e2ec;
} }
.fc-calendar-and-summary {
display: grid;
grid-template-columns: 1fr auto;
gap: 24px;
align-items: start;
}
.fc-month-header { .fc-month-header {
display: flex; display: flex;
align-items: center; align-items: center;
@@ -548,6 +555,69 @@ input[type="number"] {
cursor: pointer; cursor: pointer;
} }
/* === TABLEAU RÉCAPITULATIF === */
.fc-month-summary {
min-width: 300px;
}
.fc-summary-table-wrapper {
background: #f8fafc;
border-radius: 6px;
padding: 12px;
border: 1px solid #d9e2ec;
}
.fc-summary-table {
width: 100%;
border-collapse: collapse;
font-size: 13px;
}
.fc-summary-table thead th {
background: #f0f4f8;
padding: 8px 6px;
text-align: center;
font-weight: 600;
color: #243b53;
border: 1px solid #d9e2ec;
white-space: nowrap;
}
.fc-summary-table tbody td {
border: 1px solid #d9e2ec;
padding: 6px 8px;
text-align: center;
background: #fff;
}
.fc-summary-table tbody td:first-child {
text-align: left;
font-weight: 500;
color: #243b53;
}
.fc-summary-total-row {
background: #f0f4f8 !important;
border-top: 2px solid #243b53;
}
.fc-summary-total-row td {
background: #f0f4f8 !important;
font-weight: 600;
color: #243b53;
}
/* Responsive pour le calendrier et le récapitulatif */
@media (max-width: 1200px) {
.fc-calendar-and-summary {
grid-template-columns: 1fr;
}
.fc-month-summary {
min-width: 100%;
}
}
/* === VUE 2 MOIS === */ /* === VUE 2 MOIS === */
.fc-two-months-container { .fc-two-months-container {
display: grid; display: grid;
+188
View File
@@ -910,6 +910,9 @@ document.addEventListener("DOMContentLoaded", () => {
} else { } else {
this.renderSingleMonthView(); this.renderSingleMonthView();
} }
// Afficher le tableau récapitulatif
this.renderMonthSummary();
} }
renderSingleMonthView() { renderSingleMonthView() {
@@ -918,6 +921,191 @@ document.addEventListener("DOMContentLoaded", () => {
this.monthCalendar.innerHTML = this.generateMonthHTML(year, month); this.monthCalendar.innerHTML = this.generateMonthHTML(year, month);
} }
calculateMonthTotals(year, month) {
// Calculer le premier et dernier jour du mois (uniquement jours de semaine)
const firstDay = new Date(year, month, 1);
const lastDay = new Date(year, month + 1, 0);
const totals = {
offCarole: 0,
extraOffCarole: 0,
centre: 0,
avis: 0,
};
// Parcourir tous les jours du mois
for (let day = 1; day <= lastDay.getDate(); day++) {
const date = new Date(year, month, day);
const dayOfWeek = date.getDay();
// Ignorer les samedi (6) et dimanche (0)
if (dayOfWeek === 0 || dayOfWeek === 6) {
continue;
}
const isoDate = `${year}-${String(month + 1).padStart(2, "0")}-${String(
day
).padStart(2, "0")}`;
// Trouver les événements pour ce jour
const dayEvents = this.dbEvents.filter((evt) => evt.date === isoDate);
dayEvents.forEach((evt) => {
const dur = parseFloat(evt.duration) || 1;
switch (evt.type) {
case "OFF_CAROLE":
totals.offCarole += dur;
break;
case "EXTRA_OFF_CAROLE":
totals.extraOffCarole += dur;
break;
case "CENTRE":
totals.centre += dur;
break;
case "AVIS":
totals.avis += dur;
break;
}
});
}
return totals;
}
renderMonthSummary() {
const summaryDiv = document.getElementById("fc-month-summary");
if (!summaryDiv) return;
let html = '<div class="fc-summary-table-wrapper">';
html += '<table class="fc-summary-table">';
html += "<thead><tr>";
html += "<th>Mois</th>";
html += "<th># Off Carole</th>";
html += "<th># Extra off Carole</th>";
html += "<th># Centre</th>";
html += "<th># Avis</th>";
html += "</tr></thead><tbody>";
const formatTotal = (total) =>
total > 0 ? (Number.isInteger(total) ? total : total.toFixed(1)) : "";
if (this.viewMode === "year") {
// Afficher tous les mois de l'année scolaire
const year = this.currentMonth.getFullYear();
const schoolYearMonths = [];
for (let month = 8; month < 12; month++) {
schoolYearMonths.push({ year, month });
}
for (let month = 0; month < 8; month++) {
schoolYearMonths.push({ year: year + 1, month });
}
schoolYearMonths.forEach(({ year: monthYear, month }) => {
const totals = this.calculateMonthTotals(monthYear, month);
html += "<tr>";
html += `<td>${getMonthNameFr(month)} ${monthYear}</td>`;
html += `<td>${formatTotal(totals.offCarole)}</td>`;
html += `<td>${formatTotal(totals.extraOffCarole)}</td>`;
html += `<td>${formatTotal(totals.centre)}</td>`;
html += `<td>${formatTotal(totals.avis)}</td>`;
html += "</tr>";
});
// Ligne de total
const yearTotals = schoolYearMonths.reduce(
(acc, { year: monthYear, month }) => {
const totals = this.calculateMonthTotals(monthYear, month);
acc.offCarole += totals.offCarole;
acc.extraOffCarole += totals.extraOffCarole;
acc.centre += totals.centre;
acc.avis += totals.avis;
return acc;
},
{ offCarole: 0, extraOffCarole: 0, centre: 0, avis: 0 }
);
html += '<tr class="fc-summary-total-row">';
html += `<td><strong>Total ${year}-${year + 1}</strong></td>`;
html += `<td><strong>${formatTotal(
yearTotals.offCarole
)}</strong></td>`;
html += `<td><strong>${formatTotal(
yearTotals.extraOffCarole
)}</strong></td>`;
html += `<td><strong>${formatTotal(yearTotals.centre)}</strong></td>`;
html += `<td><strong>${formatTotal(yearTotals.avis)}</strong></td>`;
html += "</tr>";
} else if (this.viewMode === "2months") {
// Afficher les 2 mois
const year = this.currentMonth.getFullYear();
const month = this.currentMonth.getMonth();
const nextMonth = month + 1;
const nextYear = nextMonth > 11 ? year + 1 : year;
const nextMonthIndex = nextMonth > 11 ? 0 : nextMonth;
// Premier mois
const totals1 = this.calculateMonthTotals(year, month);
html += "<tr>";
html += `<td>${getMonthNameFr(month)} ${
month >= 8 ? year : year + 1
}</td>`;
html += `<td>${formatTotal(totals1.offCarole)}</td>`;
html += `<td>${formatTotal(totals1.extraOffCarole)}</td>`;
html += `<td>${formatTotal(totals1.centre)}</td>`;
html += `<td>${formatTotal(totals1.avis)}</td>`;
html += "</tr>";
// Deuxième mois
const totals2 = this.calculateMonthTotals(nextYear, nextMonthIndex);
html += "<tr>";
html += `<td>${getMonthNameFr(nextMonthIndex)} ${
nextMonthIndex >= 8 ? nextYear : nextYear + 1
}</td>`;
html += `<td>${formatTotal(totals2.offCarole)}</td>`;
html += `<td>${formatTotal(totals2.extraOffCarole)}</td>`;
html += `<td>${formatTotal(totals2.centre)}</td>`;
html += `<td>${formatTotal(totals2.avis)}</td>`;
html += "</tr>";
// Ligne de total
const combinedTotals = {
offCarole: totals1.offCarole + totals2.offCarole,
extraOffCarole: totals1.extraOffCarole + totals2.extraOffCarole,
centre: totals1.centre + totals2.centre,
avis: totals1.avis + totals2.avis,
};
html += '<tr class="fc-summary-total-row">';
html += "<td><strong>Total</strong></td>";
html += `<td><strong>${formatTotal(
combinedTotals.offCarole
)}</strong></td>`;
html += `<td><strong>${formatTotal(
combinedTotals.extraOffCarole
)}</strong></td>`;
html += `<td><strong>${formatTotal(
combinedTotals.centre
)}</strong></td>`;
html += `<td><strong>${formatTotal(combinedTotals.avis)}</strong></td>`;
html += "</tr>";
} else {
// Afficher 1 mois
const year = this.currentMonth.getFullYear();
const month = this.currentMonth.getMonth();
const totals = this.calculateMonthTotals(year, month);
html += "<tr>";
html += `<td>${getMonthNameFr(month)} ${
month >= 8 ? year : year + 1
}</td>`;
html += `<td>${formatTotal(totals.offCarole)}</td>`;
html += `<td>${formatTotal(totals.extraOffCarole)}</td>`;
html += `<td>${formatTotal(totals.centre)}</td>`;
html += `<td>${formatTotal(totals.avis)}</td>`;
html += "</tr>";
}
html += "</tbody></table>";
html += "</div>";
summaryDiv.innerHTML = html;
}
renderTwoMonthsView() { renderTwoMonthsView() {
const year = this.currentMonth.getFullYear(); const year = this.currentMonth.getFullYear();
const month = this.currentMonth.getMonth(); const month = this.currentMonth.getMonth();
+7 -2
View File
@@ -108,8 +108,13 @@ require __DIR__ . '/header.php';
<button id="fc-next-month" class="fc-nav-button"></button> <button id="fc-next-month" class="fc-nav-button"></button>
</div> </div>
</div> </div>
<div id="fc-month-calendar" class="fc-month-calendar"> <div class="fc-calendar-and-summary">
<!-- Le calendrier mensuel sera généré par JavaScript --> <div id="fc-month-calendar" class="fc-month-calendar">
<!-- Le calendrier mensuel sera généré par JavaScript -->
</div>
<div id="fc-month-summary" class="fc-month-summary">
<!-- Le tableau récapitulatif sera généré par JavaScript -->
</div>
</div> </div>
<!-- Le menu contextuel pour le calendrier mensuel --> <!-- Le menu contextuel pour le calendrier mensuel -->
<div id="fc-month-selectionMenu" class="fc-selection-menu"></div> <div id="fc-month-selectionMenu" class="fc-selection-menu"></div>