smart selector
This commit is contained in:
+7
-1
@@ -110,7 +110,13 @@ require __DIR__ . '/header.php';
|
|||||||
|
|
||||||
<div class="fc-month-nav-row">
|
<div class="fc-month-nav-row">
|
||||||
<button id="fc-prev-month" class="fc-nav-button">‹</button>
|
<button id="fc-prev-month" class="fc-nav-button">‹</button>
|
||||||
<h3 id="fc-current-month-year"></h3>
|
|
||||||
|
<div id="fc-smart-date-selector" style="display:flex; align-items:center; justify-content:center; flex-grow:1; gap:6px;">
|
||||||
|
<select id="fc-select-month" class="fc-smart-select"></select>
|
||||||
|
<select id="fc-select-year" class="fc-smart-select"></select>
|
||||||
|
<span id="fc-multi-month-suffix" style="display:none; font-size:1.3rem; font-weight:800; color:#0f172a; margin-left:4px;"></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<button id="fc-next-month" class="fc-nav-button">›</button>
|
<button id="fc-next-month" class="fc-nav-button">›</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -795,6 +795,45 @@ td.col-laia-sub {
|
|||||||
color: #ef4444; /* Devient rouge au survol */
|
color: #ef4444; /* Devient rouge au survol */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* =========================================================
|
||||||
|
SMART DATE SELECTOR (Comportement natif calqué sur .pf-input)
|
||||||
|
========================================================= */
|
||||||
|
.fc-smart-select {
|
||||||
|
background: #ffffff;
|
||||||
|
border: 1px solid #cbd5e1;
|
||||||
|
border-radius: 8px;
|
||||||
|
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-main);
|
||||||
|
|
||||||
|
/* Padding standard */
|
||||||
|
padding: 8px 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
text-transform: capitalize;
|
||||||
|
box-shadow: var(--pf-shadow-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-smart-select:hover {
|
||||||
|
border-color: #94a3b8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-smart-select:focus {
|
||||||
|
background: #ffffff;
|
||||||
|
border-color: var(--primary);
|
||||||
|
outline: none;
|
||||||
|
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.fc-smart-select {
|
||||||
|
font-size: 1rem;
|
||||||
|
padding: 6px 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Mobile */
|
/* Mobile */
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.pf-family-calendar .pf-container {
|
.pf-family-calendar .pf-container {
|
||||||
|
|||||||
@@ -96,7 +96,8 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
now.getMonth() >= 8 ? now.getFullYear() : now.getFullYear() - 1;
|
now.getMonth() >= 8 ? now.getFullYear() : now.getFullYear() - 1;
|
||||||
this.modalSelectedYear = this.currentSchoolYearStart;
|
this.modalSelectedYear = this.currentSchoolYearStart;
|
||||||
|
|
||||||
this.setupModalUI(); // Prépare le selecteur d'année dans la modale
|
this.setupModalUI();
|
||||||
|
this.initSmartSelectors();
|
||||||
await this.refreshAllData();
|
await this.refreshAllData();
|
||||||
this.updateSchoolYearLabel();
|
this.updateSchoolYearLabel();
|
||||||
|
|
||||||
@@ -132,6 +133,40 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initSmartSelectors() {
|
||||||
|
const selectMonth = document.getElementById("fc-select-month");
|
||||||
|
const selectYear = document.getElementById("fc-select-year");
|
||||||
|
if (!selectMonth || !selectYear) return;
|
||||||
|
|
||||||
|
const lang = window.appLang || "fr-FR";
|
||||||
|
|
||||||
|
// 1. Remplir les mois en tenant compte de la langue locale
|
||||||
|
for (let i = 0; i < 12; i++) {
|
||||||
|
const d = new Date(2000, i, 1);
|
||||||
|
const monthName = new Intl.DateTimeFormat(lang, {
|
||||||
|
month: "long",
|
||||||
|
}).format(d);
|
||||||
|
selectMonth.add(new Option(monthName, i));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Remplir les années (de l'année actuelle -2 à +5)
|
||||||
|
const currentY = new Date().getFullYear();
|
||||||
|
for (let y = currentY - 2; y <= currentY + 5; y++) {
|
||||||
|
selectYear.add(new Option(y, y));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Écouteurs d'événements pour le rechargement en direct
|
||||||
|
const handleChange = () => {
|
||||||
|
const m = parseInt(selectMonth.value);
|
||||||
|
const y = parseInt(selectYear.value);
|
||||||
|
this.currentMonth = new Date(y, m, 1);
|
||||||
|
this.renderMonthCalendar();
|
||||||
|
};
|
||||||
|
|
||||||
|
selectMonth.addEventListener("change", handleChange);
|
||||||
|
selectYear.addEventListener("change", handleChange);
|
||||||
|
}
|
||||||
|
|
||||||
async refreshAllData() {
|
async refreshAllData() {
|
||||||
try {
|
try {
|
||||||
const weeksData = await this.fetchApi(
|
const weeksData = await this.fetchApi(
|
||||||
@@ -714,37 +749,22 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
|
|
||||||
const y = this.currentMonth.getFullYear();
|
const y = this.currentMonth.getFullYear();
|
||||||
const m = this.currentMonth.getMonth();
|
const m = this.currentMonth.getMonth();
|
||||||
const lang = window.I18N_LANG || "fr-FR";
|
|
||||||
const titleEl = document.querySelector("#fc-current-month-year");
|
|
||||||
|
|
||||||
if (titleEl) {
|
const selectMonth = document.getElementById("fc-select-month");
|
||||||
|
const selectYear = document.getElementById("fc-select-year");
|
||||||
|
// On masque définitivement le suffixe encombrant
|
||||||
|
const suffixEl = document.getElementById("fc-multi-month-suffix");
|
||||||
|
|
||||||
|
if (selectMonth && selectYear) {
|
||||||
|
selectMonth.value = m;
|
||||||
|
selectYear.value = y;
|
||||||
|
if (suffixEl) suffixEl.style.display = "none";
|
||||||
|
|
||||||
if (this.viewMode === "3months") {
|
if (this.viewMode === "3months") {
|
||||||
const nextM2 = new Date(y, m + 2, 1);
|
|
||||||
const m1 = new Intl.DateTimeFormat(lang, { month: "short" }).format(
|
|
||||||
this.currentMonth,
|
|
||||||
);
|
|
||||||
const m2 = new Intl.DateTimeFormat(lang, {
|
|
||||||
month: "short",
|
|
||||||
year: "numeric",
|
|
||||||
}).format(nextM2);
|
|
||||||
titleEl.textContent = `${m1} - ${m2}`;
|
|
||||||
this.renderThreeMonthsView();
|
this.renderThreeMonthsView();
|
||||||
} else if (this.viewMode === "2months") {
|
} else if (this.viewMode === "2months") {
|
||||||
const nextM = new Date(y, m + 1, 1);
|
|
||||||
const m1 = new Intl.DateTimeFormat(lang, { month: "short" }).format(
|
|
||||||
this.currentMonth,
|
|
||||||
);
|
|
||||||
const m2 = new Intl.DateTimeFormat(lang, {
|
|
||||||
month: "short",
|
|
||||||
year: "numeric",
|
|
||||||
}).format(nextM);
|
|
||||||
titleEl.textContent = `${m1} - ${m2}`;
|
|
||||||
this.renderTwoMonthsView();
|
this.renderTwoMonthsView();
|
||||||
} else {
|
} else {
|
||||||
titleEl.textContent = new Intl.DateTimeFormat(lang, {
|
|
||||||
month: "long",
|
|
||||||
year: "numeric",
|
|
||||||
}).format(this.currentMonth);
|
|
||||||
this.monthCalendar.innerHTML = this.generateMonthHTML(y, m);
|
this.monthCalendar.innerHTML = this.generateMonthHTML(y, m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+84
-55
@@ -1,6 +1,6 @@
|
|||||||
# 🦙 Source Code PachaFamily
|
# 🦙 Source Code PachaFamily
|
||||||
|
|
||||||
> *Généré le 2026-05-06 13:00:43*
|
> *Généré le 2026-05-06 17:19:12*
|
||||||
|
|
||||||
### 📄 Fichier : `budget.php`
|
### 📄 Fichier : `budget.php`
|
||||||
```php
|
```php
|
||||||
@@ -7400,10 +7400,11 @@ $monthName = $monthNames[(int)$viewM] . ' ' . $viewY;
|
|||||||
|
|
||||||
<div id="snapshotModal" class="pf-modal">
|
<div id="snapshotModal" class="pf-modal">
|
||||||
<div class="pf-modal-content" style="max-width:350px;">
|
<div class="pf-modal-content" style="max-width:350px;">
|
||||||
<div class="pf-modal-header">
|
<div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:20px;">
|
||||||
<h3 class="pf-modal-title">🏦 <?= tr('bud_update_balance') ?></h3>
|
<h3 class="pf-modal-title" style="margin:0; border:none; padding:0;">🏦 <?= tr('bud_update_balance') ?></h3>
|
||||||
<button type="button" onclick="closeSuiviModal('snapshotModal')" class="pf-modal-close">×</button>
|
<button type="button" onclick="closeSuiviModal('snapshotModal')" style="background:none; border:none; font-size:1.8rem; cursor:pointer; color:#94a3b8; line-height:1;">×</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="pf-modal-body">
|
<div class="pf-modal-body">
|
||||||
<form id="snapshotForm" method="POST">
|
<form id="snapshotForm" method="POST">
|
||||||
<input type="hidden" name="action" value="save_snapshot">
|
<input type="hidden" name="action" value="save_snapshot">
|
||||||
@@ -7415,9 +7416,10 @@ $monthName = $monthNames[(int)$viewM] . ' ' . $viewY;
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="pf-modal-footer">
|
|
||||||
<button type="button" onclick="closeSuiviModal('snapshotModal')" class="pf-btn pf-btn-secondary"><?= tr('btn_cancel') ?></button>
|
<div class="modal-footer">
|
||||||
<button type="submit" form="snapshotForm" class="pf-btn pf-btn-primary"><?= tr('btn_save') ?></button>
|
<button type="button" onclick="closeSuiviModal('snapshotModal')" class="pf-btn btn-secondary"><?= tr('btn_cancel') ?></button>
|
||||||
|
<button type="submit" form="snapshotForm" class="pf-btn"><?= tr('btn_save') ?></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -7527,7 +7529,9 @@ window.I18N = {
|
|||||||
'bud_confirm_delete': <?= json_encode(tr('bud_confirm_delete')) ?>,
|
'bud_confirm_delete': <?= json_encode(tr('bud_confirm_delete')) ?>,
|
||||||
'bud_to_define_js': <?= json_encode(tr('bud_to_define_js')) ?>,
|
'bud_to_define_js': <?= json_encode(tr('bud_to_define_js')) ?>,
|
||||||
'error_occured': <?= json_encode(tr('error_occured')) ?>,
|
'error_occured': <?= json_encode(tr('error_occured')) ?>,
|
||||||
'bud_err_tech': <?= json_encode(tr('bud_err_tech')) ?>
|
'bud_err_tech': <?= json_encode(tr('bud_err_tech')) ?>,
|
||||||
|
'btn_cancel': <?= json_encode(tr('btn_cancel')) ?>,
|
||||||
|
'btn_delete': <?= json_encode(tr('btn_delete')) ?>,
|
||||||
};
|
};
|
||||||
|
|
||||||
const activeViewMonth = '<?= substr($viewMonthDate, 0, 7) ?>';
|
const activeViewMonth = '<?= substr($viewMonthDate, 0, 7) ?>';
|
||||||
@@ -7853,11 +7857,17 @@ try {
|
|||||||
|
|
||||||
:root {
|
:root {
|
||||||
/* Couleurs sémantiques Calendrier */
|
/* Couleurs sémantiques Calendrier */
|
||||||
--c-school-holiday: #e5d9f2;
|
--c-school-holiday: #ede9fe;
|
||||||
--c-public-holiday: #e2e8f0; /* Plus marqué que l'original */
|
--c-public-holiday: repeating-linear-gradient(
|
||||||
--c-off-carole: #ffedd5;
|
45deg,
|
||||||
|
#f8fafc,
|
||||||
|
#f8fafc 8px,
|
||||||
|
#f1f5f9 8px,
|
||||||
|
#f1f5f9 16px
|
||||||
|
);
|
||||||
|
--c-off-carole: #fef3c7;
|
||||||
--c-extra-off: #fee2e2;
|
--c-extra-off: #fee2e2;
|
||||||
--c-selected: #bfdbfe;
|
--c-selected: #dbeafe;
|
||||||
|
|
||||||
/* Thèmes Parents (Sync Budget) */
|
/* Thèmes Parents (Sync Budget) */
|
||||||
--bg-alex: #ecfeff;
|
--bg-alex: #ecfeff;
|
||||||
@@ -8811,14 +8821,22 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
|
|
||||||
// Modifie dynamiquement le titre de la modale pour y insérer le selecteur d'année
|
// Modifie dynamiquement le titre de la modale pour y insérer le selecteur d'année
|
||||||
setupModalUI() {
|
setupModalUI() {
|
||||||
const headerH2 = document.querySelector(".fc-modal-header h2");
|
const headerTitle = document.querySelector(
|
||||||
if (headerH2 && !document.getElementById("holidayYearSelect")) {
|
"#modalHolidays .pf-modal-title",
|
||||||
headerH2.innerHTML = `${tr("fc_modal_holidays_title")}
|
);
|
||||||
<select id="holidayYearSelect" style="margin-left:15px; font-size:1rem; padding:4px; border-radius:4px; border:1px solid #cbd5e1;">
|
|
||||||
<option value="${this.currentSchoolYearStart - 1}">${this.currentSchoolYearStart - 1} - ${this.currentSchoolYearStart}</option>
|
if (headerTitle && !document.getElementById("holidayYearSelect")) {
|
||||||
<option value="${this.currentSchoolYearStart}" selected>${this.currentSchoolYearStart} - ${this.currentSchoolYearStart + 1}</option>
|
let options = "";
|
||||||
<option value="${this.currentSchoolYearStart + 1}">${this.currentSchoolYearStart + 1} - ${this.currentSchoolYearStart + 2}</option>
|
const currentY = new Date().getFullYear();
|
||||||
<option value="${this.currentSchoolYearStart + 2}">${this.currentSchoolYearStart + 2} - ${this.currentSchoolYearStart + 3}</option>
|
// On affiche de N-2 à N+3 pour avoir un bel historique/futur
|
||||||
|
for (let y = currentY - 2; y <= currentY + 3; y++) {
|
||||||
|
const selected = y === this.currentSchoolYearStart ? "selected" : "";
|
||||||
|
options += `<option value="${y}" ${selected}>${y} - ${y + 1}</option>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
headerTitle.innerHTML = `🏖️ ${tr("fc_modal_holidays_title")}
|
||||||
|
<select id="holidayYearSelect" class="pf-input" style="width:auto; display:inline-block; margin-left:10px; padding:4px 10px; height:auto;">
|
||||||
|
${options}
|
||||||
</select>`;
|
</select>`;
|
||||||
|
|
||||||
document
|
document
|
||||||
@@ -8908,7 +8926,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
renderModalHolidays() {
|
renderModalHolidays() {
|
||||||
if (!this.schoolHolidaysTableBody) return;
|
if (!this.schoolHolidaysTableBody) return;
|
||||||
|
|
||||||
// Filtrer les événements de type VACANCES_SCOLAIRES pour l'année scolaire sélectionnée
|
// On utilise bien l'année de la modale, indépendamment du planning de fond
|
||||||
const startDate = `${this.modalSelectedYear}-09-01`;
|
const startDate = `${this.modalSelectedYear}-09-01`;
|
||||||
const endDate = `${this.modalSelectedYear + 1}-08-31`;
|
const endDate = `${this.modalSelectedYear + 1}-08-31`;
|
||||||
|
|
||||||
@@ -8919,61 +8937,50 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
e.date <= endDate,
|
e.date <= endDate,
|
||||||
);
|
);
|
||||||
|
|
||||||
// S'il n'y a pas de vacances en base pour cette année, on affiche le bouton "Générer"
|
|
||||||
if (yearHolidays.length === 0) {
|
if (yearHolidays.length === 0) {
|
||||||
this.schoolHolidaysTableBody.innerHTML = `
|
this.schoolHolidaysTableBody.innerHTML = `
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="3" style="text-align:center; padding: 30px;">
|
<td colspan="3" style="text-align:center; padding: 30px;">
|
||||||
<p style="color:#64748b; margin-bottom:15px;">Les vacances de cette année ne sont pas encore enregistrées.</p>
|
<p style="color:#64748b; margin-bottom:15px;">${tr("fc_err_no_data_gov")}</p>
|
||||||
<button id="btnFetchGovHolidays" class="pf-btn">Importer depuis l'API Gouvernement</button>
|
<button id="btnFetchGovHolidays" class="pf-btn">${tr("btn_import")}</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
document
|
document
|
||||||
.getElementById("btnFetchGovHolidays")
|
.getElementById("btnFetchGovHolidays")
|
||||||
.addEventListener("click", (e) => {
|
?.addEventListener("click", (e) => {
|
||||||
e.target.innerText = "Téléchargement en cours...";
|
e.target.innerText = "...";
|
||||||
e.target.disabled = true;
|
e.target.disabled = true;
|
||||||
this.fetchAndSaveGovHolidays(this.modalSelectedYear);
|
this.fetchAndSaveGovHolidays(this.modalSelectedYear);
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. Tri chronologique strict des jours
|
|
||||||
yearHolidays.sort((a, b) => new Date(a.date) - new Date(b.date));
|
yearHolidays.sort((a, b) => new Date(a.date) - new Date(b.date));
|
||||||
|
|
||||||
// 2. Regroupement par blocs de jours consécutifs
|
|
||||||
const blocks = [];
|
const blocks = [];
|
||||||
let currentBlock = null;
|
let currentBlock = null;
|
||||||
|
|
||||||
yearHolidays.forEach((e) => {
|
yearHolidays.forEach((e) => {
|
||||||
const d = new Date(e.date + "T00:00:00"); // Force locale
|
const d = new Date(e.date + "T00:00:00");
|
||||||
|
|
||||||
if (!currentBlock) {
|
if (!currentBlock) {
|
||||||
currentBlock = { start: d, end: d };
|
currentBlock = { start: d, end: d };
|
||||||
blocks.push(currentBlock);
|
blocks.push(currentBlock);
|
||||||
} else {
|
} else {
|
||||||
// Calcul de l'écart en jours entre la date actuelle et la fin du bloc en cours
|
const diffDays = Math.round(
|
||||||
const diffTime = d.getTime() - currentBlock.end.getTime();
|
(d.getTime() - currentBlock.end.getTime()) / (1000 * 60 * 60 * 24),
|
||||||
const diffDays = Math.round(diffTime / (1000 * 60 * 60 * 24));
|
);
|
||||||
|
|
||||||
// Si l'écart est minime (<= 4 jours, pour absorber un éventuel week-end non stocké)
|
|
||||||
// on considère qu'on est toujours dans la même période de vacances.
|
|
||||||
if (diffDays <= 4) {
|
if (diffDays <= 4) {
|
||||||
currentBlock.end = d;
|
currentBlock.end = d;
|
||||||
} else {
|
} else {
|
||||||
// Sinon, l'écart est grand : c'est une NOUVELLE période de vacances
|
|
||||||
currentBlock = { start: d, end: d };
|
currentBlock = { start: d, end: d };
|
||||||
blocks.push(currentBlock);
|
blocks.push(currentBlock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 3. Rendu HTML et déduction des noms
|
|
||||||
let html = "";
|
let html = "";
|
||||||
blocks.forEach((block) => {
|
blocks.forEach((block) => {
|
||||||
// Déduction intelligente du nom selon le mois de départ ET la durée
|
|
||||||
const m = block.start.getMonth() + 1;
|
const m = block.start.getMonth() + 1;
|
||||||
const durationDays =
|
const durationDays =
|
||||||
Math.round(
|
Math.round(
|
||||||
@@ -8982,26 +8989,19 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
) + 1;
|
) + 1;
|
||||||
|
|
||||||
let name = tr("leg_school_holidays");
|
let name = tr("leg_school_holidays");
|
||||||
|
if (m === 10 || m === 11) name = tr("vac_toussaint");
|
||||||
if (m === 10 || m === 11) {
|
else if (m === 12 || m === 1) name = tr("vac_noel");
|
||||||
name = tr("vac_toussaint");
|
else if (m === 2 || m === 3) name = tr("vac_hiver");
|
||||||
} else if (m === 12 || m === 1) {
|
else if (m === 4 || (m === 5 && durationDays > 6))
|
||||||
name = tr("vac_noel");
|
|
||||||
} else if (m === 2 || m === 3) {
|
|
||||||
name = tr("vac_hiver");
|
|
||||||
} else if (m === 4 || (m === 5 && durationDays > 6)) {
|
|
||||||
name = tr("vac_printemps");
|
name = tr("vac_printemps");
|
||||||
} else if (m === 5 && durationDays <= 6) {
|
else if (m === 5 && durationDays <= 6) name = tr("vac_ascension");
|
||||||
name = tr("vac_ascension");
|
else if (m === 7 || m === 8) name = tr("vac_ete");
|
||||||
} else if (m === 7 || m === 8) {
|
|
||||||
name = tr("vac_ete");
|
|
||||||
}
|
|
||||||
|
|
||||||
html += `
|
html += `
|
||||||
<tr>
|
<tr>
|
||||||
<td><strong>${name}</strong></td>
|
<td><strong>${name}</strong></td>
|
||||||
<td>${block.start.toLocaleDateString("fr-FR")}</td>
|
<td>${block.start.toLocaleDateString(window.appLang || "fr-FR")}</td>
|
||||||
<td>${block.end.toLocaleDateString("fr-FR")}</td>
|
<td>${block.end.toLocaleDateString(window.appLang || "fr-FR")}</td>
|
||||||
</tr>
|
</tr>
|
||||||
`;
|
`;
|
||||||
});
|
});
|
||||||
@@ -9894,6 +9894,35 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
});
|
});
|
||||||
document.addEventListener("touchend", (e) => this.handleTouchEnd(e));
|
document.addEventListener("touchend", (e) => this.handleTouchEnd(e));
|
||||||
}
|
}
|
||||||
|
const scrollWrapper = document.getElementById("planningTable-wrapper");
|
||||||
|
if (scrollWrapper) {
|
||||||
|
scrollWrapper.addEventListener("scroll", async () => {
|
||||||
|
// Bloquer si on est déjà en train de charger
|
||||||
|
if (this._isAutoLoading) return;
|
||||||
|
|
||||||
|
// Détection du bas (On descend dans le temps : passage à l'année suivante)
|
||||||
|
// On met une tolérance de 5px pour les calculs de pixels décimaux
|
||||||
|
if (
|
||||||
|
scrollWrapper.scrollTop + scrollWrapper.clientHeight >=
|
||||||
|
scrollWrapper.scrollHeight - 5
|
||||||
|
) {
|
||||||
|
this._isAutoLoading = true;
|
||||||
|
await this.changeSchoolYear(1);
|
||||||
|
// On replace le scroll tout en haut pour la continuité visuelle
|
||||||
|
scrollWrapper.scrollTop = 5;
|
||||||
|
setTimeout(() => (this._isAutoLoading = false), 500);
|
||||||
|
}
|
||||||
|
// Détection du haut (On remonte le temps : passage à l'année précédente)
|
||||||
|
else if (scrollWrapper.scrollTop === 0) {
|
||||||
|
this._isAutoLoading = true;
|
||||||
|
await this.changeSchoolYear(-1);
|
||||||
|
// On replace le scroll tout en bas pour la continuité visuelle
|
||||||
|
scrollWrapper.scrollTop =
|
||||||
|
scrollWrapper.scrollHeight - scrollWrapper.clientHeight - 5;
|
||||||
|
setTimeout(() => (this._isAutoLoading = false), 500);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// --- GESTION MODALE VACANCES SCOLAIRES ---
|
// --- GESTION MODALE VACANCES SCOLAIRES ---
|
||||||
const btnOpen = document.getElementById("btnOpenHolidays");
|
const btnOpen = document.getElementById("btnOpenHolidays");
|
||||||
|
|||||||
Reference in New Issue
Block a user