From 7b5c0be72b34145089e2d92e69eefe4fe7198f7b Mon Sep 17 00:00:00 2001 From: "fefe.clochette" Date: Tue, 5 May 2026 12:13:41 +0200 Subject: [PATCH] calendar display mobile --- family-calendar.php | 51 +- includes/lang/ca.php | 1 + includes/lang/fr.php | 1 + modules/family-calendar/family-calendar.css | 1399 +++++++++---------- modules/family-calendar/family-calendar.js | 145 +- 5 files changed, 782 insertions(+), 815 deletions(-) diff --git a/family-calendar.php b/family-calendar.php index ff9d6d0..bc50397 100644 --- a/family-calendar.php +++ b/family-calendar.php @@ -94,23 +94,30 @@ require __DIR__ . '/header.php';
+
+ +
+ +

+ +
+
- -
-

-
- - +
+
+
+
+
@@ -165,20 +172,6 @@ require __DIR__ . '/header.php';
-
-

-
-
-
-
-
-
-
-
-
-
-
-
@@ -195,6 +188,21 @@ require __DIR__ . '/header.php';
+ +
+

+
+
+
+
+
+
+
+
+
+
+
+
@@ -208,6 +216,9 @@ window.I18N = { 'leg_centre': "", 'leg_avis': "", 'leg_pep_sick': "", + 'leg_off_carole': "", + 'leg_extra_off': "", + 'leg_presence Pep': "", 'fc_menu_kids_leaves': "", 'fc_clear': "", 'fc_unit_days': "", diff --git a/includes/lang/ca.php b/includes/lang/ca.php index 770d475..3d7cd2e 100644 --- a/includes/lang/ca.php +++ b/includes/lang/ca.php @@ -113,6 +113,7 @@ return [ 'fc_btn_save_snap' => 'Desar el correctiu', 'fc_view_1m' => '1 mes', 'fc_view_2m' => '2 mesos', + 'fc_view_3m' => '3 mesos', 'fc_view_year' => 'Any', 'fc_weekly_planning' => 'Planificació setmanal', 'fc_col_month' => 'Mes', diff --git a/includes/lang/fr.php b/includes/lang/fr.php index 6a1cc61..6d4ac10 100644 --- a/includes/lang/fr.php +++ b/includes/lang/fr.php @@ -115,6 +115,7 @@ return [ 'fc_btn_save_snap' => 'Enregistrer le correctif', 'fc_view_1m' => '1 mois', 'fc_view_2m' => '2 mois', + 'fc_view_3m' => '3 mois', 'fc_view_year' => 'Année', 'fc_weekly_planning' => 'Planning hebdomadaire', 'fc_col_month' => 'Mois', diff --git a/modules/family-calendar/family-calendar.css b/modules/family-calendar/family-calendar.css index dee1721..519d38e 100644 --- a/modules/family-calendar/family-calendar.css +++ b/modules/family-calendar/family-calendar.css @@ -1,6 +1,8 @@ /* modules/family-calendar/family-calendar.css */ -/* --- 1. VARIABLES --- */ +/* ========================================================= + 1. VARIABLES & BASE + ========================================================= */ :root { --primary: #3b82f6; --bg-page: #f8fafc; @@ -16,10 +18,9 @@ --c-extra-off: #fee2e2; --c-selected: #bfdbfe; - /* NOUVELLES COULEURS (Neutres) */ + /* Couleurs Personnes */ --bg-alex: #f0fdfa; --text-alex: #0f766e; - --bg-laia: #fffbeb; --text-laia: #b45309; } @@ -30,7 +31,6 @@ box-sizing: border-box; } -/* Base */ .pf-family-calendar { background-color: var(--bg-page); font-family: "Inter", system-ui, sans-serif; @@ -39,7 +39,7 @@ line-height: 1.4; } -/* OVERRIDES STRUCTURAUX */ +/* Overrides Structuraux Globaux */ .pf-family-calendar .pf-container { max-width: 100% !important; padding: 0 20px; @@ -49,7 +49,6 @@ padding-bottom: 40px; } -/* Titres */ .pf-card-title { padding: 12px 16px; margin: 0; @@ -66,7 +65,9 @@ padding: 16px; } -/* --- 2. HEADER PAGE & BOUTON VACANCES --- */ +/* ========================================================= + 2. HEADER GLOBAL & BOUTONS D'ACTION + ========================================================= */ .fc-header-row { display: flex; justify-content: space-between; @@ -89,161 +90,267 @@ transition: all 0.2s; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); } + .pf-btn-icon-text:hover { border-color: var(--primary); color: var(--primary); background: #f0f9ff; transform: translateY(-1px); } + .pf-btn-icon-text .icon { font-size: 1.2em; } -/* --- 3. PLANNING HEBDO --- */ -.fc-week-header { +/* ========================================================= + 3. CALENDRIER MENSUEL (En-tête & Grille) + ========================================================= */ +.fc-month-calendar-wrapper { + background: white; + border: 1px solid var(--border-color); + border-radius: 16px; + padding: 24px; + margin-bottom: 32px; + box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05); +} + +/* En-tête Unifié PC/Mobile */ +.fc-month-header { + display: flex !important; + flex-direction: column !important; + gap: 16px !important; + margin-bottom: 20px !important; +} + +.fc-month-nav-row { + display: flex !important; + align-items: center !important; + justify-content: space-between !important; + width: 100% !important; +} + +.fc-month-nav-row h3 { + margin: 0 !important; + font-size: 1.4rem !important; + font-weight: 800 !important; + color: var(--text-main) !important; + text-transform: capitalize !important; + text-align: center !important; + flex-grow: 1 !important; +} + +.fc-nav-button { + width: 36px; + height: 36px; + border-radius: 50%; + border: 1px solid var(--border-color); + background: white; + color: var(--text-main); + font-size: 18px; display: flex; align-items: center; - justify-content: space-between; - margin-bottom: 16px; - gap: 16px; - flex-wrap: wrap; + justify-content: center; + cursor: pointer; + transition: all 0.2s; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); } -.fc-week-header h2 { - margin: 0; - font-size: 1.25rem; - font-weight: 800; + +.fc-nav-button:hover { + border-color: var(--primary); + color: var(--primary); + transform: translateY(-1px); +} + +/* Sélecteur de vues (1, 2, 3 Mois) */ +.fc-view-controls { + display: flex !important; + width: 100% !important; + background: #e2e8f0 !important; + padding: 4px !important; + border-radius: 8px !important; + order: 0 !important; +} + +.fc-view-button { + flex: 1 !important; + text-align: center !important; + background: transparent; + border: none; + border-radius: 6px; + padding: 6px 16px; + font-size: 0.85rem; + font-weight: 600; + color: var(--text-muted); + cursor: pointer; + transition: all 0.2s; +} + +.fc-view-button:hover { color: var(--text-main); } -/* Contrôles Année Scolaire */ -.fc-week-nav-controls { +.fc-view-button--active { + background: white; + color: var(--primary); + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + font-weight: 700; +} + +/* Grille du Mois */ +.fc-month-calendar { + width: 100%; + display: block; + overflow-x: auto; +} + +.fc-month-table { + min-width: 100% !important; + width: 100% !important; + table-layout: fixed; + border-collapse: collapse !important; +} + +.fc-month-table td { + height: 80px; + padding: 6px !important; + font-size: 0.85rem; + vertical-align: top; + position: relative; + cursor: pointer; + background: transparent !important; + border: 1px solid var(--border-color) !important; +} + +.fc-month-table th { + padding: 10px !important; + font-size: 0.8rem !important; + background: var(--bg-header) !important; + color: var(--text-muted); + text-transform: uppercase; + border: 1px solid var(--border-color) !important; +} + +.fc-day--other-month { + background: #fcfcfc !important; +} + +/* Conteneurs Vues Multi-Mois */ +.fc-two-months-container { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 24px; + width: 100%; + overflow-x: auto; +} + +.fc-three-months-container { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 24px; + width: 100%; + overflow-x: auto; +} + +.fc-month-container { + background: white; +} + +.fc-month-title { + text-align: center; + font-weight: 700; + color: var(--text-main); + margin-bottom: 12px; + padding-bottom: 8px; + border-bottom: 2px solid var(--primary); + text-transform: capitalize; +} + +/* ========================================================= + 4. DÉCOMPTE DES CONGÉS (STYLE ÉPURÉ / PILLS) + ========================================================= */ +.fc-month-balances { + display: flex; + flex-wrap: wrap; + justify-content: center; + gap: 15px; + margin-top: 20px; + padding-top: 15px; + border-top: 1px dashed var(--border-color); +} + +.fc-minimal-balance-card { display: flex; align-items: center; gap: 12px; background: white; - padding: 4px 12px; + padding: 8px 16px; border-radius: 50px; -} -#fc-current-school-year-label { - font-size: 1rem; - font-weight: 800; - color: var(--text-main); - min-width: 120px; - text-align: center; - letter-spacing: -0.02em; + border: 1px solid #e2e8f0; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.02); } -/* WRAPPER OPTIMISÉ POUR LE SCROLL */ -#planningTable-wrapper { - max-height: 80vh; - overflow-x: auto; - overflow-y: auto; - -webkit-overflow-scrolling: touch; /* Scroll fluide sur iOS */ - border: 1px solid var(--border-color); - border-radius: 12px; - background: white; - box-shadow: 0 4px 10px rgba(0, 0, 0, 0.05); - position: relative; +.fc-minimal-balance-card strong { + font-size: 0.85rem; } - -/* Scrollbar personnalisée pour qu'elle soit toujours visible */ -#planningTable-wrapper::-webkit-scrollbar { - height: 8px; - width: 8px; -} -#planningTable-wrapper::-webkit-scrollbar-track { - background: #f1f5f9; - border-radius: 4px; -} -#planningTable-wrapper::-webkit-scrollbar-thumb { - background: #cbd5e1; - border-radius: 4px; -} -#planningTable-wrapper::-webkit-scrollbar-thumb:hover { - background: #94a3b8; -} - -#planningTable { - width: 100%; - min-width: 1000px; - border-collapse: separate; - border-spacing: 0; -} - -/* Sticky Header */ -#planningTable thead { - position: sticky; - top: 0; - z-index: 20; - background: var(--bg-header); -} -#planningTable thead th { - position: sticky; - top: 0; - background: var(--bg-header); - border-bottom: 1px solid var(--border-color); - border-right: 1px solid var(--border-color); - padding: 6px; - font-size: 0.75rem; - color: var(--text-main); - z-index: 20; - box-shadow: 0 1px 0 rgba(0, 0, 0, 0.05); -} - -/* Hauteurs */ -#planningTable thead tr:nth-child(1) th { - top: 0; - height: 32px; -} -#planningTable thead tr:nth-child(2) th { - top: 32px; - height: 28px; - z-index: 19; -} -#planningTable thead tr:nth-child(3) th { - top: 60px; - height: 26px; - z-index: 19; - border-bottom: 2px solid var(--border-color); -} - -/* Couleurs Headers */ -.col-alex.header-group { - background: var(--bg-alex) !important; +.fc-minimal-balance-card strong.alex { color: var(--text-alex); } -.col-laia.header-group { - background: var(--bg-laia) !important; +.fc-minimal-balance-card strong.laia { color: var(--text-laia); } -/* Corps */ -#planningTable tbody td { - border-right: 1px solid #f1f5f9; - border-bottom: 1px solid #f1f5f9; - height: 36px; - padding: 0 4px; - text-align: center; - font-size: 0.85rem; - white-space: nowrap; - overflow: hidden; - cursor: pointer; - position: relative; +.fc-minimal-chips { + display: flex; + gap: 8px; + flex-wrap: wrap; } -/* Couleurs Cellules */ +.fc-min-chip { + display: flex; + align-items: center; + background: #f8fafc; + border-radius: 20px; + padding: 3px 10px; + font-size: 0.75rem; + border: 1px solid #cbd5e1; +} + +.fc-min-chip .type { + font-weight: 700; + color: #64748b; + margin-right: 6px; +} + +.fc-min-chip .val { + font-weight: 800; + color: #0f172a; +} + +.fc-used-badge { + margin-left: 6px; + background: #fee2e2; + color: #ef4444; + padding: 1px 5px; + border-radius: 10px; + font-size: 0.65rem; + font-weight: bold; +} + +/* ========================================================= + 5. STYLES DES ÉVÉNEMENTS (Couleurs & Icônes) + ========================================================= */ .fc-day--school-holiday { - background: var(--c-school-holiday); + background: var(--c-school-holiday) !important; } .fc-day--public-holiday { - background: var(--c-public-holiday); + background: var(--c-public-holiday) !important; font-weight: 700; } .fc-day--off-carole { - background: var(--c-off-carole); + background: var(--c-off-carole) !important; } .fc-day--extra-off-carole { - background: var(--c-extra-off); + background: var(--c-extra-off) !important; } .fc-day--selected { background: var(--c-selected) !important; @@ -251,7 +358,6 @@ z-index: 5; } -/* Icones */ .fc-day--centre::after { content: "🏫"; position: absolute; @@ -279,7 +385,143 @@ font-size: 12px; } -/* Colonnes */ +/* Superpositions de congés sur vacances scolaires */ +.fc-day--off-carole.fc-day--school-holiday, +.fc-day--extra-off-carole.fc-day--school-holiday { + box-shadow: inset 0 -8px 0 0 var(--c-school-holiday) !important; +} +.fc-day--centre.fc-day--school-holiday, +.fc-day--avis.fc-day--school-holiday { + box-shadow: inset 0 -8px 0 0 var(--c-school-holiday) !important; +} + +/* ========================================================= + 6. PLANNING HEBDOMADAIRE (Desktop Uniquement) + ========================================================= */ +.fc-week-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 16px; + gap: 16px; + flex-wrap: wrap; +} + +.fc-week-header h2 { + margin: 0; + font-size: 1.25rem; + font-weight: 800; + color: var(--text-main); +} + +.fc-week-nav-controls { + display: flex; + align-items: center; + gap: 12px; + background: white; + padding: 4px 12px; + border-radius: 50px; +} + +#fc-current-school-year-label { + font-size: 1rem; + font-weight: 800; + color: var(--text-main); + min-width: 120px; + text-align: center; + letter-spacing: -0.02em; +} + +#planningTable-wrapper { + max-height: 80vh; + overflow-x: auto; + overflow-y: auto; + -webkit-overflow-scrolling: touch; + border: 1px solid var(--border-color); + border-radius: 12px; + background: white; + box-shadow: 0 4px 10px rgba(0, 0, 0, 0.05); + position: relative; +} + +#planningTable-wrapper::-webkit-scrollbar { + height: 8px; + width: 8px; +} +#planningTable-wrapper::-webkit-scrollbar-track { + background: #f1f5f9; + border-radius: 4px; +} +#planningTable-wrapper::-webkit-scrollbar-thumb { + background: #cbd5e1; + border-radius: 4px; +} +#planningTable-wrapper::-webkit-scrollbar-thumb:hover { + background: #94a3b8; +} + +#planningTable { + width: 100%; + min-width: 1000px; + border-collapse: separate; + border-spacing: 0; +} + +#planningTable thead { + position: sticky; + top: 0; + z-index: 20; + background: var(--bg-header); +} +#planningTable thead th { + position: sticky; + top: 0; + background: var(--bg-header); + border-bottom: 1px solid var(--border-color); + border-right: 1px solid var(--border-color); + padding: 6px; + font-size: 0.75rem; + color: var(--text-main); + z-index: 20; +} + +#planningTable thead tr:nth-child(1) th { + height: 32px; +} +#planningTable thead tr:nth-child(2) th { + top: 32px; + height: 28px; + z-index: 19; +} +#planningTable thead tr:nth-child(3) th { + top: 60px; + height: 26px; + z-index: 19; + border-bottom: 2px solid var(--border-color); +} + +.col-alex.header-group { + background: var(--bg-alex) !important; + color: var(--text-alex); +} +.col-laia.header-group { + background: var(--bg-laia) !important; + color: var(--text-laia); +} + +#planningTable tbody td { + border-right: 1px solid #f1f5f9; + border-bottom: 1px solid #f1f5f9; + height: 36px; + padding: 0 4px; + text-align: center; + font-size: 0.85rem; + white-space: nowrap; + overflow: hidden; + cursor: pointer; + position: relative; +} + .col-alex-av, .col-laia-av { background: #f8fafc; @@ -292,16 +534,24 @@ .col-laia-sub { background: var(--bg-laia); } + .col-month { - width: 50px; + box-sizing: border-box !important; + width: 54px !important; + min-width: 54px !important; + max-width: 54px !important; background: white; font-weight: 600; border-right: 2px solid var(--border-color) !important; } -.col-day { + +th.col-day, +td.col-day { width: auto !important; + min-width: 35px !important; border-right: 2px solid var(--border-color) !important; } + th.col-total, td.col-total, th.col-alex-sub, @@ -311,18 +561,10 @@ td.col-laia-sub { width: 32px !important; min-width: 32px !important; max-width: 32px !important; - box-sizing: border-box; - padding: 0 2px !important; /* On réduit le padding pour que les chiffres respirent */ + padding: 0 2px !important; overflow: hidden; } -th.col-day, -td.col-day { - width: auto !important; - min-width: 35px !important; - border-right: 2px solid var(--border-color) !important; -} - .rotated-text span { writing-mode: vertical-rl; transform: rotate(180deg); @@ -331,161 +573,49 @@ td.col-day { color: var(--text-muted); } -/* --- 4. CALENDRIER MENSUEL --- */ -.fc-month-calendar-wrapper { - background: white; - border: 1px solid var(--border-color); - border-radius: 16px; - padding: 24px; - margin-bottom: 32px; - box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05); +#planningTable tbody td.col-sticky-mois { + position: sticky !important; + left: 0 !important; + z-index: 15 !important; + background: white !important; +} +#planningTable tbody td.col-sticky-sem { + position: sticky !important; + left: 54px !important; + z-index: 14 !important; + background: white !important; + box-shadow: 4px 0 6px -2px rgba(0, 0, 0, 0.1); +} +#planningTable thead tr th.col-sticky-mois { + position: sticky !important; + top: 0 !important; + left: 0 !important; + z-index: 30 !important; + background: var(--bg-header) !important; +} +#planningTable thead tr th.col-sticky-sem { + position: sticky !important; + top: 0 !important; + left: 54px !important; + z-index: 29 !important; + background: var(--bg-header) !important; + box-shadow: 4px 0 6px -2px rgba(0, 0, 0, 0.1); } -.fc-month-header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 24px; - flex-wrap: wrap; - gap: 16px; -} - -.fc-nav-controls { - display: flex; - align-items: center; - gap: 16px; - order: 2; -} -.fc-nav-button { - width: 36px; - height: 36px; - border-radius: 50%; - border: 1px solid var(--border-color); - background: white; - color: var(--text-main); - font-size: 18px; - display: flex; - align-items: center; - justify-content: center; - cursor: pointer; - transition: all 0.2s; - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); -} -.fc-nav-button:hover { - border-color: var(--primary); - color: var(--primary); - transform: translateY(-1px); -} - -#fc-current-month-year { - margin: 0; - font-size: 1.25rem; - font-weight: 800; - color: var(--text-main); - text-transform: capitalize; - min-width: 180px; - text-align: center; - letter-spacing: -0.02em; -} - -.fc-view-controls { - display: inline-flex; - background: #e2e8f0; - padding: 4px; - border-radius: 8px; - gap: 0; - order: 1; -} -.fc-view-button { - background: transparent; - border: none; - border-radius: 6px; - padding: 6px 16px; - font-size: 0.85rem; - font-weight: 600; - color: var(--text-muted); - cursor: pointer; - transition: all 0.2s; -} -.fc-view-button:hover { - color: var(--text-main); -} -.fc-view-button--active { - background: white; - color: var(--primary); - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); - font-weight: 700; -} - -.fc-month-calendar { - width: 100%; - display: block; - overflow-x: auto; -} -.fc-month-table { - width: 100%; - min-width: 500px; - border-collapse: collapse; - table-layout: fixed; -} -.fc-month-table th { - background: #f8fafc; - padding: 10px; - border: 1px solid var(--border-color); - font-size: 0.8rem; - text-transform: uppercase; - color: var(--text-muted); -} -.fc-month-table td { - border: 1px solid var(--border-color); - height: 80px; - vertical-align: top; - padding: 6px; - position: relative; - cursor: pointer; -} -.fc-day--other-month { - background: #fcfcfc; -} - -.fc-two-months-container { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 24px; - width: 100%; - overflow-x: auto; -} -.fc-year-container { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 20px; - width: 100%; -} -.fc-month-container, -.fc-year-month { - background: white; -} -.fc-month-title, -.fc-year-month-title { - text-align: center; - font-weight: 700; - color: var(--text-main); - margin-bottom: 12px; - padding-bottom: 8px; - border-bottom: 2px solid var(--primary); - text-transform: capitalize; -} - -/* --- 5. NOUVELLE SECTION BASSE (CARTES) --- */ +/* ========================================================= + 7. PANNEAUX DU BAS (Légendes & Récapitulatif) + ========================================================= */ .pf-section--bottom-panels { margin-top: 40px; } + .fc-bottom-grid { display: grid; grid-template-columns: 2fr 1fr; gap: 24px; align-items: start; } + .pf-card { background: white; border: 1px solid var(--border-color); @@ -500,6 +630,7 @@ td.col-day { gap: 8px; justify-content: flex-start; } + .pf-legend-item { display: inline-flex; align-items: center; @@ -511,6 +642,7 @@ td.col-day { border-radius: 6px; color: var(--text-muted); } + .pf-legend-color { width: 16px; height: 16px; @@ -522,6 +654,7 @@ td.col-day { line-height: 1; } +/* Légendes Spécifiques */ .fc-legend-school-holiday { background: var(--c-school-holiday); } @@ -553,42 +686,19 @@ td.col-day { border: none; } -.fc-summary-vertical { - display: flex; - flex-direction: column; - gap: 0; -} -.fc-summary-item { - display: flex; - justify-content: space-between; - align-items: center; - padding: 12px 4px; - border-bottom: 1px solid #f1f5f9; -} -.fc-summary-item:last-child { - border-bottom: none; -} -.fc-summary-label { - font-size: 0.85rem; - color: var(--text-muted); - font-weight: 500; -} -.fc-summary-value { - font-size: 1rem; - font-weight: 700; - color: var(--text-main); -} - +/* Récapitulatif */ .fc-summary-header { display: flex; justify-content: space-between; align-items: center; padding: 8px 16px; } + .fc-summary-controls { display: flex; gap: 8px; } + .fc-summ-select { background: white; border: 1px solid var(--border-color); @@ -600,11 +710,173 @@ td.col-day { outline: none; height: 24px; } + .fc-summ-select:hover { border-color: var(--primary); } -/* --- 6. MODALE VACANCES --- */ +.fc-summary-vertical { + display: flex; + flex-direction: column; + gap: 0; +} + +.fc-summary-item { + display: flex; + justify-content: space-between; + align-items: center; + padding: 12px 4px; + border-bottom: 1px solid #f1f5f9; +} + +.fc-summary-item:last-child { + border-bottom: none; +} + +.fc-summary-label { + font-size: 0.85rem; + color: var(--text-muted); + font-weight: 500; +} + +.fc-summary-value { + font-size: 1rem; + font-weight: 700; + color: var(--text-main); +} + +/* ========================================================= + 8. MENU CONTEXTUEL (Clic case) & MODALE VACANCES + ========================================================= */ + +/* Menu Contextuel */ +.fc-selection-menu { + position: absolute; + z-index: 9999; + background: rgba(255, 255, 255, 0.95); + backdrop-filter: blur(8px); + border: 1px solid rgba(226, 232, 240, 0.8); + box-shadow: + 0 10px 25px -5px rgba(0, 0, 0, 0.1), + 0 8px 10px -6px rgba(0, 0, 0, 0.1); + border-radius: 16px; + padding: 10px 12px; + min-width: 220px; + display: none; + animation: menuPopIn 0.2s cubic-bezier(0.16, 1, 0.3, 1) forwards; + transform-origin: top center; +} + +@keyframes menuPopIn { + from { + opacity: 0; + transform: scale(0.95) translateY(10px); + } + to { + opacity: 1; + transform: scale(1) translateY(0); + } +} + +.fc-menu-section { + padding: 6px 0; + border-bottom: 1px dashed #cbd5e1; +} +.fc-menu-section:first-child { + padding-top: 0; +} +.fc-menu-section:last-child { + border: none; + padding-bottom: 0; +} + +.fc-menu-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 6px; +} +.fc-menu-section strong { + display: block; + font-size: 0.7rem; + text-transform: uppercase; + letter-spacing: 0.05em; + font-weight: 700; + color: #64748b; + margin-bottom: 0 !important; +} +.fc-menu-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 4px; +} + +.fc-menu-btn { + background: white; + border: 1px solid #e2e8f0; + color: #1e293b; + padding: 6px 8px; + border-radius: 8px; + font-size: 0.8rem; + font-weight: 600; + cursor: pointer; + width: 100%; + transition: all 0.2s ease; + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); +} +.fc-menu-btn:hover { + background: #f8fafc; + border-color: #3b82f6; + color: #2563eb; + transform: translateY(-1px); + box-shadow: 0 4px 6px -1px rgba(59, 130, 246, 0.15); +} + +.fc-menu-clear-icon { + background: transparent; + border: none; + color: #94a3b8; + cursor: pointer; + padding: 4px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 6px; + transition: all 0.2s ease; +} +.fc-menu-clear-icon svg { + width: 14px; + height: 14px; +} +.fc-menu-clear-icon:hover { + background: #fef2f2; + color: #dc2626; +} + +.fc-menu-leaves-table table { + width: 100%; + border-spacing: 2px; + border-collapse: separate; +} +.fc-menu-leaves-table th { + font-size: 0.7rem; + font-weight: 700; + color: #64748b; + padding-bottom: 2px; + text-align: center; +} +.fc-menu-leaves-table td { + padding: 0; +} +.fc-th-inline { + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + gap: 4px; +} + +/* Modale Vacances */ .fc-modal-overlay { position: fixed; top: 0; @@ -709,197 +981,18 @@ td.col-day { } } -/* --- MENU CONTEXTUEL COMPACT --- */ -.fc-selection-menu { - position: absolute; - z-index: 9999; - background: rgba(255, 255, 255, 0.95); - backdrop-filter: blur(8px); - border: 1px solid rgba(226, 232, 240, 0.8); - box-shadow: - 0 10px 25px -5px rgba(0, 0, 0, 0.1), - 0 8px 10px -6px rgba(0, 0, 0, 0.1); - border-radius: 16px; - padding: 10px 12px; - min-width: 220px; - display: none; - animation: menuPopIn 0.2s cubic-bezier(0.16, 1, 0.3, 1) forwards; - transform-origin: top center; -} - -@keyframes menuPopIn { - from { - opacity: 0; - transform: scale(0.95) translateY(10px); - } - to { - opacity: 1; - transform: scale(1) translateY(0); - } -} - -.fc-menu-section { - padding: 6px 0; - border-bottom: 1px dashed #cbd5e1; -} -.fc-menu-section:first-child { - padding-top: 0; -} -.fc-menu-section:last-child { - border: none; - padding-bottom: 0; -} -.fc-menu-header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 6px; -} -.fc-menu-section strong { - display: block; - font-size: 0.7rem; - text-transform: uppercase; - letter-spacing: 0.05em; - font-weight: 700; - color: #64748b; - margin-bottom: 0 !important; -} -.fc-menu-grid { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 4px; -} -.fc-menu-btn { - background: white; - border: 1px solid #e2e8f0; - color: #1e293b; - padding: 6px 8px; - border-radius: 8px; - font-size: 0.8rem; - font-weight: 600; - cursor: pointer; - width: 100%; - transition: all 0.2s ease; - box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); -} -.fc-menu-btn:hover { - background: #f8fafc; - border-color: #3b82f6; - color: #2563eb; - transform: translateY(-1px); - box-shadow: 0 4px 6px -1px rgba(59, 130, 246, 0.15); -} -.fc-menu-clear-icon { - background: transparent; - border: none; - color: #94a3b8; - cursor: pointer; - padding: 4px; - display: flex; - align-items: center; - justify-content: center; - border-radius: 6px; - transition: all 0.2s ease; -} -.fc-menu-clear-icon svg { - width: 14px; - height: 14px; -} -.fc-menu-clear-icon:hover { - background: #fef2f2; - color: #dc2626; -} - -.fc-menu-leaves-table table { - width: 100%; - border-spacing: 2px; - border-collapse: separate; -} -.fc-menu-leaves-table th { - font-size: 0.7rem; - font-weight: 700; - color: #64748b; - padding-bottom: 2px; - text-align: center; -} -.fc-menu-leaves-table td { - padding: 0; -} -.fc-th-inline { - display: flex; - flex-direction: row; - align-items: center; - justify-content: center; - gap: 4px; -} - -/* --- SUPERPOSITION : GARDE/CONGÉS + VACANCES SCOLAIRES --- */ -.fc-day--off-carole.fc-day--school-holiday { - background: var(--c-off-carole) !important; - box-shadow: inset 0 -8px 0 0 var(--c-school-holiday) !important; -} -.fc-day--extra-off-carole.fc-day--school-holiday { - background: var(--c-extra-off) !important; - box-shadow: inset 0 -8px 0 0 var(--c-school-holiday) !important; -} -.fc-day--centre.fc-day--school-holiday, -.fc-day--avis.fc-day--school-holiday { - box-shadow: inset 0 -8px 0 0 var(--c-school-holiday) !important; -} - /* ========================================================= - 8. FIXATION DES COLONNES (STICKY) POUR SCROLL FLUIDE + 9. MEDIA QUERIES (Tablettes & Mobiles) ========================================================= */ -.col-month { - box-sizing: border-box !important; - width: 54px !important; - min-width: 54px !important; - max-width: 54px !important; +@media (max-width: 1000px) { + .fc-three-months-container { + grid-template-columns: 1fr; + } } -#planningTable tbody td.col-sticky-mois { - position: -webkit-sticky !important; - position: sticky !important; - left: 0 !important; - z-index: 15 !important; - background: white !important; -} - -#planningTable tbody td.col-sticky-sem { - position: -webkit-sticky !important; - position: sticky !important; - left: 54px !important; - z-index: 14 !important; - background: white !important; - box-shadow: 4px 0 6px -2px rgba(0, 0, 0, 0.1); /* Ombre renforcée pour montrer le scroll */ -} - -#planningTable thead tr th.col-sticky-mois { - position: -webkit-sticky !important; - position: sticky !important; - top: 0 !important; - left: 0 !important; - z-index: 30 !important; - background: var(--bg-header) !important; -} - -#planningTable thead tr th.col-sticky-sem { - position: -webkit-sticky !important; - position: sticky !important; - top: 0 !important; - left: 54px !important; - z-index: 29 !important; - background: var(--bg-header) !important; - box-shadow: 4px 0 6px -2px rgba(0, 0, 0, 0.1); /* Ombre renforcée */ -} - -/* ========================================================= - 9. OPTIMISATIONS MOBILES STRICTES (max-width: 768px) - ========================================================= */ - @media (max-width: 768px) { - /* 1. PLEIN ÉCRAN POUR GAGNER DE L'ESPACE */ + /* Espacements Globaux */ .pf-family-calendar .pf-container { padding: 0 !important; } @@ -907,16 +1000,16 @@ td.col-day { padding-top: 10px; } - /* 2. EN-TÊTES ET BOUTONS GLOBAUX (Empilement propre) */ + /* En-tête Global */ .fc-header-row { flex-direction: column; align-items: stretch; gap: 15px; - padding: 0 10px; /* On remet un peu de padding juste pour les textes */ + padding: 0 10px; } .fc-header-row > div { display: flex; - flex-direction: column; /* Les boutons s'empilent */ + flex-direction: column; width: 100%; gap: 10px; } @@ -925,242 +1018,42 @@ td.col-day { width: 100%; } - /* 3. CONTRÔLES DU CALENDRIER MENSUEL */ - .fc-month-header { - flex-direction: column; - gap: 15px; - align-items: stretch; - } - .fc-view-controls { - width: 100%; - display: flex; - order: 1; - } - .fc-view-button { - flex: 1; /* Les onglets 1 Mois / 2 Mois se partagent l'espace */ - text-align: center; - padding: 8px 4px; - font-size: 0.8rem; - } - #fc-current-month-year { - order: 2; - } - .fc-nav-controls { - width: 100%; - justify-content: space-between; /* Les flèches de chaque côté */ - order: 3; - } - - /* 4. CONTRÔLES DU PLANNING HEBDO */ - .fc-week-header { - flex-direction: column; - align-items: stretch; - padding: 0 10px; - } - .fc-week-nav-controls { - justify-content: space-between; - } - - /* 5. LE GRAND TABLEAU (Suppression des bordures extérieures) */ - #planningTable-wrapper { - border-radius: 0; - border-left: none; - border-right: none; - margin-bottom: 0; - max-height: 75vh; /* Ajusté pour laisser voir un peu le bas */ - } - - /* Ajustements pour que les colonnes figées (Mois + Semaine) ne prennent pas tout l'écran */ - .col-month { - width: 40px !important; - min-width: 40px !important; - max-width: 40px !important; - font-size: 0.75rem; /* On réduit le texte "Avril" etc. */ - } - #planningTable tbody td.col-sticky-sem { - left: 40px !important; /* Adapté à la nouvelle largeur de la 1ère colonne */ - } - #planningTable thead tr th.col-sticky-sem { - left: 40px !important; - } - - /* 6. PANNEAUX DU BAS (Légendes et Résumés) */ - .fc-bottom-grid { - grid-template-columns: 1fr; - padding: 0 10px; - } - .fc-two-months-container, - .fc-year-container { - grid-template-columns: 1fr; - } - .fc-summary-header { - flex-direction: column; - align-items: flex-start; - gap: 12px; - } - .fc-summary-controls { - width: 100%; - justify-content: space-between; - } - - /* 7. MODALE BOTTOM SHEET (SÉCURITÉ Z-INDEX) */ - .fc-selection-menu { - position: fixed !important; - top: auto !important; - left: 0 !important; - bottom: 0 !important; - width: 100% !important; - border-radius: 24px 24px 0 0; - box-shadow: 0 -10px 40px rgba(0, 0, 0, 0.3); - padding: 24px 20px; - padding-bottom: env(safe-area-inset-bottom, 24px); - transform: translateY(100%); - animation: slideUpSheet 0.3s cubic-bezier(0.16, 1, 0.3, 1) forwards; - max-height: 85vh; - overflow-y: auto; - z-index: 999999 !important; /* Doit passer AU-DESSUS des colonnes figées du tableau ! */ - } - - @keyframes slideUpSheet { - to { - transform: translateY(0); - } - } - - .fc-selection-menu::before { - content: ""; - display: block; - width: 40px; - height: 5px; - background: #cbd5e1; - border-radius: 10px; - margin: 0 auto 15px auto; - } - - .fc-menu-btn { - padding: 12px 10px; - font-size: 0.95rem; - } - - /* Réduction des icônes pour le tableau hyper dense */ - .fc-day--centre::after { - font-size: 9px !important; - top: 1px !important; - right: 1px !important; - } - .fc-day--avis::after { - width: 10px !important; - height: 10px !important; - top: 1px !important; - right: 1px !important; - } - .fc-pep-sick-emoji { - font-size: 9px !important; - bottom: 1px !important; - right: 1px !important; - } -} - -/* ========================================================= - 10. DÉCOMPTE DES CONGÉS (VUE MENSUELLE) - ========================================================= */ -.fc-month-balances { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 15px; - margin-top: 15px; - padding-top: 15px; - border-top: 1px dashed var(--border-color); -} -.fc-balance-person { - background: white; - border-radius: 8px; - padding: 10px; - border: 1px solid var(--border-color); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05); -} -.fc-balance-name { - font-weight: 800; - font-size: 0.85rem; - margin-bottom: 8px; - text-align: center; - text-transform: uppercase; -} -.fc-balance-name.alex { - color: var(--text-alex); -} -.fc-balance-name.laia { - color: var(--text-laia); -} - -.fc-balance-grid { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 8px; - text-align: center; -} -.fc-balance-col { - display: flex; - flex-direction: column; - background: #f8fafc; - border-radius: 6px; - padding: 6px 4px; - border: 1px solid #e2e8f0; -} -.fc-balance-type { - font-size: 0.7rem; - font-weight: 800; - color: var(--text-muted); - margin-bottom: 4px; -} -.fc-balance-numbers { - font-size: 0.75rem; - font-family: monospace; - display: flex; - flex-direction: column; - gap: 2px; -} -.fc-bal-val { - display: flex; - justify-content: space-between; - align-items: center; -} -.fc-bal-val.start { - color: #64748b; -} -.fc-bal-val.used { - color: #ef4444; -} -.fc-bal-val.end { - color: #10b981; - font-weight: bold; - border-top: 1px solid #cbd5e1; - margin-top: 3px; - padding-top: 3px; -} - -/* ========================================================= - 11. REFONTE MOBILE EXTRÊME (max-width: 768px) - ========================================================= */ -@media (max-width: 768px) { - /* 1. On DÉTRUIT visuellement le planning hebdo sur mobile ! */ + /* Cacher le planning hebdo complet sur mobile */ .fc-week-header, #planningTable-wrapper { display: none !important; } - /* 2. On compresse le calendrier mensuel pour qu'il rentre dans l'écran */ - .fc-month-table td { - height: 48px !important; /* Hauteur très réduite */ - padding: 2px !important; - font-size: 0.75rem; - } - .fc-month-table th { - padding: 4px !important; - font-size: 0.7rem; + /* Boîte et Grille du Mois */ + .fc-month-calendar-wrapper { + padding: 16px !important; + margin-bottom: 20px !important; + overflow: hidden; } - /* On miniaturise les pastilles d'événements */ + .fc-month-table { + min-width: 100% !important; + width: 100% !important; + table-layout: fixed; + border-collapse: collapse !important; + } + + .fc-month-table td { + height: 46px !important; + padding: 2px !important; + font-size: 0.75rem !important; + background: transparent !important; + border: 1px solid var(--border-color) !important; + } + + .fc-month-table th { + padding: 6px 4px !important; + font-size: 0.7rem !important; + background: var(--bg-header) !important; + border: 1px solid var(--border-color) !important; + } + + /* Micro-icônes événements */ .fc-day--centre::after { font-size: 8px !important; top: 1px; @@ -1178,17 +1071,55 @@ td.col-day { right: 1px; } - /* On réduit la marge de la box du mois */ - .fc-month-calendar-wrapper { - padding: 15px !important; - margin-bottom: 15px !important; + /* Panneaux inférieurs */ + .fc-bottom-grid { + grid-template-columns: 1fr; + padding: 0 10px; + } + .fc-summary-header { + flex-direction: column; + align-items: flex-start; + gap: 12px; + } + .fc-summary-controls { + width: 100%; + justify-content: space-between; } - /* 3. Les soldes s'empilent sur mobile */ - .fc-month-balances { - grid-template-columns: 1fr; - gap: 10px; - padding-top: 10px; - margin-top: 10px; + /* Menu Bottom Sheet (Tactile) */ + .fc-selection-menu { + position: fixed !important; + top: auto !important; + left: 0 !important; + bottom: 0 !important; + width: 100% !important; + border-radius: 24px 24px 0 0; + box-shadow: 0 -10px 40px rgba(0, 0, 0, 0.3); + padding: 24px 20px; + padding-bottom: env(safe-area-inset-bottom, 24px); + transform: translateY(100%); + animation: slideUpSheet 0.3s cubic-bezier(0.16, 1, 0.3, 1) forwards; + max-height: 85vh; + overflow-y: auto; + z-index: 999999 !important; + } + @keyframes slideUpSheet { + to { + transform: translateY(0); + } + } + + .fc-selection-menu::before { + content: ""; + display: block; + width: 40px; + height: 5px; + background: #cbd5e1; + border-radius: 10px; + margin: 0 auto 15px auto; + } + .fc-menu-btn { + padding: 12px 10px; + font-size: 0.95rem; } } diff --git a/modules/family-calendar/family-calendar.js b/modules/family-calendar/family-calendar.js index 78f3d14..ae63b2f 100644 --- a/modules/family-calendar/family-calendar.js +++ b/modules/family-calendar/family-calendar.js @@ -689,40 +689,42 @@ document.addEventListener("DOMContentLoaded", () => { const y = this.currentMonth.getFullYear(); const m = this.currentMonth.getMonth(); - const lang = window.I18N_LANG || "fr-FR"; const titleEl = document.querySelector("#fc-current-month-year"); + if (titleEl) { - if (this.viewMode === "year") { - titleEl.textContent = `${tr("fc_school_year")} ${this.currentSchoolYearStart} – ${this.currentSchoolYearStart + 1}`; - } else if (this.viewMode === "2months") { - const nextM = new Date(y, m + 1, 1); - const m1 = new Intl.DateTimeFormat(lang, { month: "long" }).format( + 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: "long", + month: "short", + year: "numeric", + }).format(nextM2); + titleEl.textContent = `${m1} - ${m2}`; + this.renderThreeMonthsView(); + } 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(); } else { titleEl.textContent = new Intl.DateTimeFormat(lang, { month: "long", year: "numeric", }).format(this.currentMonth); + this.monthCalendar.innerHTML = this.generateMonthHTML(y, m); } } - if (this.viewMode === "year") { - this.renderYearView(); - } else if (this.viewMode === "2months") { - this.renderTwoMonthsView(); - } else { - this.monthCalendar.innerHTML = this.generateMonthHTML(y, m); - } - this.renderMonthBalances(); - this.syncSummaryWithMonth(); } @@ -730,86 +732,107 @@ document.addEventListener("DOMContentLoaded", () => { const y = this.currentMonth.getFullYear(); const m = this.currentMonth.getMonth(); const nextDate = new Date(y, m + 1, 1); + const lang = window.I18N_LANG || "fr-FR"; + let html = `
`; - html += `
${new Intl.DateTimeFormat("fr-FR", { month: "long" }).format(this.currentMonth)}
${this.generateMonthHTML(y, m)}
`; - html += `
${new Intl.DateTimeFormat("fr-FR", { month: "long" }).format(nextDate)}
${this.generateMonthHTML(nextDate.getFullYear(), nextDate.getMonth())}
`; + html += `
${new Intl.DateTimeFormat(lang, { month: "long" }).format(this.currentMonth)}
${this.generateMonthHTML(y, m)}
`; + html += `
${new Intl.DateTimeFormat(lang, { month: "long" }).format(nextDate)}
${this.generateMonthHTML(nextDate.getFullYear(), nextDate.getMonth())}
`; + html += `
`; + + this.monthCalendar.innerHTML = html; + } + + renderThreeMonthsView() { + const y = this.currentMonth.getFullYear(); + const m = this.currentMonth.getMonth(); + const d1 = this.currentMonth; + const d2 = new Date(y, m + 1, 1); + const d3 = new Date(y, m + 2, 1); + + let html = `
`; + [d1, d2, d3].forEach((d) => { + html += `
${new Intl.DateTimeFormat("fr-FR", { month: "long" }).format(d)}
${this.generateMonthHTML(d.getFullYear(), d.getMonth())}
`; + }); html += `
`; this.monthCalendar.innerHTML = html; } - renderYearView() { - const startYear = this.currentSchoolYearStart; - let html = '
'; - for (let i = 8; i < 12; i++) - html += `
${new Intl.DateTimeFormat("fr-FR", { month: "long" }).format(new Date(startYear, i))}
${this.generateMonthHTML(startYear, i)}
`; - for (let i = 0; i < 8; i++) - html += `
${new Intl.DateTimeFormat("fr-FR", { month: "long" }).format(new Date(startYear + 1, i))}
${this.generateMonthHTML(startYear + 1, i)}
`; - html += "
"; - this.monthCalendar.innerHTML = html; - } - - // Affiche le décompte des congés (Début, Utilisé, Reste) sous le calendrier renderMonthBalances() { const container = document.getElementById("fc-month-balances"); if (!container) return; - // On n'affiche les soldes que si on regarde 1 seul mois pour éviter la confusion - if (this.viewMode !== "1month") { - container.innerHTML = ""; - container.style.display = "none"; - return; + // 1. Déterminer les mois affichés selon la vue + const monthsToDisplay = []; + const y = this.currentMonth.getFullYear(); + const m = this.currentMonth.getMonth(); + + let numMonths = 1; + if (this.viewMode === "2months") numMonths = 2; + if (this.viewMode === "3months") numMonths = 3; + + for (let i = 0; i < numMonths; i++) { + const d = new Date(y, m + i, 1); + monthsToDisplay.push( + `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}`, + ); } - container.style.display = "grid"; - const ym = `${this.currentMonth.getFullYear()}-${String(this.currentMonth.getMonth() + 1).padStart(2, "0")}`; + container.style.display = "flex"; let html = ""; + // 2. Calcul dynamique pour Alex et Laia [FAMILY.ALEX, FAMILY.LAIA].forEach((person) => { - html += `
-
${person.prefix}
-
`; + html += `
+ ${person.prefix.toUpperCase()} +
`; ["CP", "JRA", "JA"].forEach((type) => { - // Utilisation des données pré-calculées par calculateMonthlyBalances() - const info = this.monthlyLeaveBalances[person.id]?.[type]?.[ym]; - const start = info ? info.availableAtMonthStart : 0; - const used = info ? info.usedInMonth : 0; - const end = Math.max(0, start - used); + // Solde de départ = celui du PREMIER mois affiché + const startInfo = + this.monthlyLeaveBalances[person.id]?.[type]?.[monthsToDisplay[0]]; + const startBal = startInfo ? startInfo.availableAtMonthStart : 0; + // Jours posés = Somme sur TOUS les mois affichés + let totalUsed = 0; + monthsToDisplay.forEach((ym) => { + const info = this.monthlyLeaveBalances[person.id]?.[type]?.[ym]; + if (info) totalUsed += info.usedInMonth; + }); + + // Solde de fin (théorique) à la fin de la période + const endBal = Math.max(0, startBal - totalUsed); const fmt = (n) => n > 0 ? (Number.isInteger(n) ? n : n.toFixed(1)) : "0"; - html += `
- ${type} -
-
${fmt(start)}
-
${fmt(used)}
-
${fmt(end)}
-
+ // Petit badge rouge uniquement s'il y a des congés posés + const usedHtml = + totalUsed > 0 + ? `-${fmt(totalUsed)}` + : ""; + + html += `
+ ${type} + ${fmt(endBal)} + ${usedHtml}
`; }); - - html += `
`; + html += `
`; }); - container.innerHTML = html; } - // Force le menu déroulant du récapitulatif à se caler sur le mois affiché syncSummaryWithMonth() { const typeSelect = document.getElementById("summType"); const valueSelect = document.getElementById("summValue"); - if (typeSelect && valueSelect && this.viewMode === "1month") { + if (typeSelect && valueSelect) { + // Le récap se synchronise avec le PREMIER mois affiché de la période const ym = `${this.currentMonth.getFullYear()}-${String(this.currentMonth.getMonth() + 1).padStart(2, "0")}`; - // Si on passe d'année à mois, on doit forcer le peuplement du select if (typeSelect.value !== "month") { typeSelect.value = "month"; - typeSelect.dispatchEvent(new Event("change")); // Déclenche populateValues() + typeSelect.dispatchEvent(new Event("change")); } - - // On sélectionne le mois actuel valueSelect.value = ym; this.updateGlobalSummary(); }