diff --git a/global.css b/global.css index 3b2062c..ca9a6b2 100644 --- a/global.css +++ b/global.css @@ -125,7 +125,9 @@ body { top: 64px; left: 0; right: 0; - bottom: 0; + height: calc(100vh - 64px); /* Remplace le bottom: 0 pour éviter le bug iOS */ + overflow-y: auto; /* Permet le scroll si le menu contient beaucoup d'items */ + -webkit-overflow-scrolling: touch; /* Fluidité sur iOS */ background: white; padding: 20px; flex-direction: column; @@ -306,16 +308,30 @@ p { } .pf-nav { display: none; - } /* Caché sur mobile, activé via burger */ + } .pf-header-actions { display: none; - } /* Caché sur mobile, dans le menu */ - + } .pf-burger-btn { display: block; - } /* Affiché sur mobile */ + } + + /* Ajustements d'espacement pour petits écrans */ + .pf-main { + padding: 16px; + } + + .pf-modules-grid { + /* Sécurité : force 1 colonne sur mobile au lieu du auto-fill */ + grid-template-columns: 1fr; + gap: 16px; + } + + .pf-login-container { + margin: 30px 16px; /* Évite de toucher les bords de l'écran */ + padding: 24px; + } - /* Menu Mobile Ouvert */ .pf-mobile-nav-link { font-size: 1.2rem; font-weight: 600; diff --git a/modules/holidays/holidays.css b/modules/holidays/holidays.css index 6770b3f..a0d75ef 100644 --- a/modules/holidays/holidays.css +++ b/modules/holidays/holidays.css @@ -141,7 +141,7 @@ body.no-scroll { /* --- 4. CARTES --- */ .hol-ideas-grid { display: grid; - grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); + grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr)); gap: 24px; margin-bottom: 40px; } @@ -459,48 +459,74 @@ body.no-scroll { flex-direction: column; align-items: flex-start; } + + /* On empile proprement les boutons d'action */ .hol-title-actions { width: 100%; + flex-direction: column; /* Essentiel pour que les boutons width: 100% ne s'écrasent pas */ + gap: 10px; } .hol-add-btn, .hol-map-toggle { width: 100%; + justify-content: center; /* Centre le texte et l'icône */ } + .form-row { flex-direction: column; gap: 10px; } - /* Sur mobile, les colonnes s'empilent */ + .hol-columns-wrapper { grid-template-columns: 1fr; } + /* Modale 100% écran avec scroll natif fluide */ .pf-modal-content { padding: 16px; width: 100%; height: 100%; max-height: 100vh; border-radius: 0; + overflow-y: auto; + -webkit-overflow-scrolling: touch; } - @media (max-width: 768px) { - .hol-date-weather-wrapper { - gap: 6px; /* On rapproche la météo de la date sur mobile */ - } - /* On aligne le haut de la carte au cas où le contenu passe sur 2 lignes */ - .hol-cp-header { - align-items: flex-start; - } + /* Adaptation des lignes de budget sur mobile pour éviter qu'elles ne soient compressées */ + .savings-line-item { + flex-wrap: wrap; + gap: 10px; + } + .savings-line-item input[type="text"] { + min-width: 100%; /* Le nom de la dépense prend toute la ligne */ + } + .savings-line-item input[type="number"] { + flex-grow: 1; /* Le prix s'ajuste sur la 2ème ligne */ + } - /* On autorise le titre et les dates à prendre la place nécessaire */ - .hol-cp-info-group { - flex: 1; - min-width: 0; /* Empêche le flexbox de "déborder" de l'écran */ - } + .hol-date-weather-wrapper { + gap: 6px; + } - .hol-cp-title { - white-space: normal; /* Permet au titre de l'étape de passer à la ligne si besoin */ - } + .hol-cp-header { + align-items: flex-start; + flex-direction: column; /* On passe le titre et le prix l'un sous l'autre si besoin */ + } + + .hol-cp-info-group { + flex: 1; + min-width: 0; + width: 100%; + } + + .hol-cp-title { + white-space: normal; + } + + .hol-cp-actions-group { + width: 100%; + justify-content: flex-end; + margin-top: 8px; } } diff --git a/modules/holidays/holidays.js b/modules/holidays/holidays.js index 75acdbc..b9a06bf 100644 --- a/modules/holidays/holidays.js +++ b/modules/holidays/holidays.js @@ -580,16 +580,63 @@ function deleteCheckpoint() { } // ============================================================================ -// 5. GLISSER-DÉPOSER POUR RÉORDONNER LES ÉTAPES +// 5. RÉORDONNANCEMENT DES ÉTAPES (DRAG & DROP PC + FLÈCHES MOBILE) // ============================================================================ + +// On sort cette fonction pour pouvoir l'appeler depuis les boutons fléchés sur mobile +function saveCheckpointOrder() { + const locations = [ + ...document.querySelectorAll(".hol-checkpoint-draggable"), + ].map((el) => el.getAttribute("data-location")); + const holidayId = document.querySelector('input[name="holiday_id"]').value; + + const formData = new FormData(); + formData.append("holiday_id", holidayId); + formData.append("locations", JSON.stringify(locations)); + + fetch("/modules/holidays/includes/api/reorder_checkpoints.php", { + method: "POST", + body: formData, + }).then(() => window.location.reload()); +} + +// Fonction appelée par les flèches Haut/Bas sur mobile +function moveStepMobile(btn, direction) { + const item = btn.closest(".hol-checkpoint-draggable"); + const container = item.parentElement; + + if ( + direction === -1 && + item.previousElementSibling && + item.previousElementSibling.classList.contains("hol-checkpoint-draggable") + ) { + container.insertBefore(item, item.previousElementSibling); + saveCheckpointOrder(); + } else if ( + direction === 1 && + item.nextElementSibling && + item.nextElementSibling.classList.contains("hol-checkpoint-draggable") + ) { + container.insertBefore(item, item.nextElementSibling.nextElementSibling); + saveCheckpointOrder(); + } +} + document.addEventListener("DOMContentLoaded", () => { const checkpoints = document.querySelectorAll(".hol-checkpoint-draggable"); const container = checkpoints[0]?.parentElement; if (!container) return; + const isMobile = window.innerWidth <= 768; let draggedItem = null; checkpoints.forEach((item) => { + // Si on est sur mobile, on supprime l'attribut draggable pour éviter les conflits de scroll + if (isMobile) { + item.removeAttribute("draggable"); + return; + } + item.addEventListener("dragstart", function (e) { draggedItem = this; setTimeout(() => (this.style.opacity = "0.4"), 0); @@ -633,22 +680,6 @@ document.addEventListener("DOMContentLoaded", () => { { offset: Number.NEGATIVE_INFINITY }, ).element; } - - function saveCheckpointOrder() { - const locations = [ - ...document.querySelectorAll(".hol-checkpoint-draggable"), - ].map((el) => el.getAttribute("data-location")); - const holidayId = document.querySelector('input[name="holiday_id"]').value; - - const formData = new FormData(); - formData.append("holiday_id", holidayId); - formData.append("locations", JSON.stringify(locations)); - - fetch("/modules/holidays/includes/api/reorder_checkpoints.php", { - method: "POST", - body: formData, - }).then(() => window.location.reload()); - } }); // ============================================================================ @@ -702,7 +733,11 @@ function openPlanningModal(step) { html += `