document.addEventListener("DOMContentLoaded", () => {
// Fermer les modales si on clique en dehors du contenu
window.onclick = function (event) {
const modal = document.getElementById("holidayModal");
if (event.target == modal) {
closeHolidayModal();
}
};
});
// --- 1. GESTION DE LA MODALE D'ÉDITION RAPIDE ---
function openHolidayModal(mode) {
const modal = document.getElementById("holidayModal");
const form = document.getElementById("holidayForm");
const btnDelete = document.getElementById("btn_delete");
// Reset complet pour éviter les résidus d'une carte précédente
form.reset();
document.getElementById("inp_id").value = "";
document.getElementById("list_transport").innerHTML = "";
document.getElementById("list_accommodation").innerHTML = "";
document.getElementById("list_activity").innerHTML = "";
if (mode === "add") {
document.getElementById("modalTitle").innerText = "Planifier le voyage";
btnDelete.style.display = "none";
} else {
document.getElementById("modalTitle").innerText = "Modification rapide";
btnDelete.style.display = "block";
}
modal.style.display = "flex";
// Focus sur le champ titre pour une saisie rapide (petit délai pour l'animation d'ouverture)
setTimeout(() => document.getElementById("inp_title").focus(), 100);
}
function closeHolidayModal() {
document.getElementById("holidayModal").style.display = "none";
}
// Fonction appelée au clic sur le bouton ✏️ de la carte (injectée par PHP)
function editHoliday(data) {
const h = data.main;
// On ouvre la modale en mode édition (ça reset les listes)
openHolidayModal("edit");
// Remplissage des champs principaux
document.getElementById("inp_id").value = h.id;
document.getElementById("inp_title").value = h.title;
document.getElementById("inp_status").value = h.status;
document.getElementById("inp_period").value = h.period_hint || "";
document.getElementById("inp_start").value = h.start_date || "";
document.getElementById("inp_end").value = h.end_date || "";
// Pour éviter d'afficher "0" dans un champ vide, on vérifie si la valeur est > 0
document.getElementById("inp_food").value =
h.budget_food > 0 ? h.budget_food : "";
document.getElementById("inp_extra").value =
h.budget_extra > 0 ? h.budget_extra : "";
document.getElementById("inp_notes").value = h.notes || "";
// Remplissage des listes dynamiques (Transport, Hébergement, Activité)
if (data.items && data.items.length > 0) {
data.items.forEach((item) => {
addItem(item.category, item.name, item.amount, item.is_paid);
});
}
}
// --- 2. GESTION DES LISTES DYNAMIQUES DANS LA MODALE ---
function addItem(category, name = "", amount = "", isPaid = 0) {
const container = document.getElementById("list_" + category);
const div = document.createElement("div");
// Style en ligne pour s'assurer que ça reste propre sans dépendre de classes externes complexes
div.style.display = "flex";
div.style.gap = "8px";
div.style.alignItems = "center";
div.style.marginBottom = "10px";
// Astuce pour lier la checkbox visuelle à l'input caché (valeur 0 ou 1 pour MySQL)
const checkedAttr = isPaid == 1 ? "checked" : "";
div.innerHTML = `
`;
container.appendChild(div);
}
function deleteHoliday() {
if (
!confirm(
"Voulez-vous vraiment supprimer définitivement ce voyage ? Cette action est irréversible.",
)
)
return;
const form = document.getElementById("holidayForm");
// On injecte un input caché pour signaler au PHP que c'est une demande de suppression
const input = document.createElement("input");
input.type = "hidden";
input.name = "action_delete";
input.value = "1";
form.appendChild(input);
form.submit();
}
// --- 3. GESTION DE LA CARTE (Leaflet - Optionnel selon si tu l'utilises ou non) ---
let map = null;
function toggleMap() {
const modal = document.getElementById("hol-map-modal");
if (modal.style.display === "flex") {
modal.style.display = "none";
} else {
modal.style.display = "flex";
// Petit délai pour laisser le temps au DOM de s'afficher avant d'init Leaflet
setTimeout(initMap, 100);
}
}
function initMap() {
if (map) {
map.invalidateSize(); // Recalcule la taille si la fenêtre a changé
return;
}
if (typeof L === "undefined") return;
// Centré sur l'Europe par défaut
map = L.map("hol-map").setView([46.6, 2.4], 4);
L.tileLayer(
"https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png",
{
attribution: "© OpenStreetMap",
},
).addTo(map);
// On récupère les points définis en global dans le PHP
if (typeof HOL_MAP_POINTS !== "undefined") {
HOL_MAP_POINTS.forEach((pt) => {
const color =
pt.status === "planned" || pt.status === "booked" ? "green" : "blue";
// Cercle simple
L.circleMarker([pt.lat, pt.lng], {
color: color,
radius: 8,
fillOpacity: 0.8,
})
.addTo(map)
.bindPopup(`${pt.title}
${pt.status}`);
});
}
}
// ============================================================================
// 4. GESTION DE LA CARTE DÉTAILLÉE (ROADTRIP) ET GÉOCODAGE
// ============================================================================
let detailMap = null;
document.addEventListener("DOMContentLoaded", () => {
// Si on est sur la page détail et que la div "tripMap" existe, on initie la carte
if (document.getElementById("tripMap")) {
initDetailMap();
}
});
function initDetailMap() {
if (typeof L === "undefined" || typeof MAP_POINTS === "undefined") return;
detailMap = L.map("tripMap");
// Fond de carte propre (CartoDB Voyager)
L.tileLayer(
"https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png",
{
attribution: "© OpenStreetMap",
},
).addTo(detailMap);
if (MAP_POINTS.length === 0) {
detailMap.setView([46.6, 2.4], 5); // Centré sur la France par défaut si vide
return;
}
const latlngs = [];
const bounds = L.latLngBounds();
MAP_POINTS.forEach((pt, index) => {
const pos = [pt.lat, pt.lng];
latlngs.push(pos);
bounds.extend(pos);
// Couleur selon le paiement
const color = pt.paid == 1 ? "#10b981" : "#f59e0b";
// On place un petit cercle pour chaque point
const marker = L.circleMarker(pos, {
color: color,
radius: 7,
fillOpacity: 1,
fillColor: "white",
weight: 3,
}).addTo(detailMap);
// Numérotation et Popup
marker.bindPopup(`