refacto holidays
This commit is contained in:
+167
-424
@@ -1,459 +1,202 @@
|
||||
<?php
|
||||
// modules/holidays/index.php
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// 1. LOGIQUE PHP : RÉCUPÉRATION DES DONNÉES
|
||||
// ------------------------------------------------------------------
|
||||
// 1. Récupération des voyages + Calcul du coût total
|
||||
$sql = "
|
||||
SELECT h.*,
|
||||
(
|
||||
COALESCE(h.budget_food, 0) +
|
||||
COALESCE(h.budget_extra, 0) +
|
||||
COALESCE((SELECT SUM(amount) FROM pf_holidays_items WHERE holiday_id = h.id), 0)
|
||||
) as total_cost
|
||||
FROM pf_holidays h
|
||||
ORDER BY FIELD(status, 'booked', 'planned', 'draft', 'passed', 'archived'),
|
||||
start_date ASC
|
||||
";
|
||||
$holidays = $pdo->query($sql)->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!function_exists('hol_q')) {
|
||||
function hol_q(PDO $pdo, string $sql, array $params = []): array {
|
||||
$st = $pdo->prepare($sql);
|
||||
$st->execute($params);
|
||||
return $st->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
}
|
||||
|
||||
$ideaId = isset($_GET['id']) ? (int)$_GET['id'] : 0;
|
||||
$isDetailView = ($ideaId > 0);
|
||||
$currentIdea = null; // Stockera les données si on est en vue détail
|
||||
|
||||
// Préparation des variables par défaut pour éviter les erreurs "undefined variable"
|
||||
$transport = []; $lodging = []; $acts = []; $budget = [];
|
||||
$fixedTotal = 0; $ppTotal = 0;
|
||||
$planned = []; $ideas = []; $archived = [];
|
||||
|
||||
if ($isDetailView) {
|
||||
// --- MODE DÉTAIL ---
|
||||
|
||||
// 1. Récupérer l'idée principale
|
||||
$rows = hol_q($pdo, "SELECT * FROM pf_holidays_ideas WHERE id = ?", [$ideaId]);
|
||||
$currentIdea = $rows[0] ?? null;
|
||||
|
||||
if ($currentIdea) {
|
||||
// 2. Récupérer les données pour la CARTE (un seul point)
|
||||
// Le JS filtrera lat/lng invalides
|
||||
$mapIdeas = hol_q($pdo, "
|
||||
SELECT id, title, country, region, city,
|
||||
CAST(lat AS DECIMAL(9,6)) AS lat,
|
||||
CAST(lng AS DECIMAL(9,6)) AS lng,
|
||||
status, desired_start_date, desired_end_date
|
||||
FROM pf_holidays_ideas
|
||||
WHERE id = ?
|
||||
", [$ideaId]);
|
||||
|
||||
// 3. Récupérer les sous-éléments (Transport, Logement, etc.)
|
||||
$transport = hol_q($pdo, "SELECT * FROM pf_holidays_transport WHERE idea_id = ? ORDER BY created_at DESC", [$ideaId]);
|
||||
$lodging = hol_q($pdo, "SELECT * FROM pf_holidays_lodging WHERE idea_id = ? ORDER BY created_at DESC", [$ideaId]);
|
||||
$acts = hol_q($pdo, "SELECT * FROM pf_holidays_activities WHERE idea_id = ? ORDER BY created_at DESC", [$ideaId]);
|
||||
$budget = hol_q($pdo, "SELECT category, label, amount, per_person FROM pf_holidays_budget_items WHERE idea_id = ? ORDER BY created_at DESC", [$ideaId]);
|
||||
|
||||
// 4. Calculs totaux budget
|
||||
$sumRow = hol_q($pdo, "
|
||||
SELECT
|
||||
SUM(CASE WHEN per_person=0 THEN amount ELSE 0 END) AS fixed_total,
|
||||
SUM(CASE WHEN per_person=1 THEN amount ELSE 0 END) AS per_person_total
|
||||
FROM pf_holidays_budget_items WHERE idea_id = ?
|
||||
", [$ideaId])[0] ?? ['fixed_total' => 0, 'per_person_total' => 0];
|
||||
|
||||
$fixedTotal = (float)($sumRow['fixed_total'] ?? 0);
|
||||
$ppTotal = (float)($sumRow['per_person_total'] ?? 0);
|
||||
}
|
||||
|
||||
} else {
|
||||
// --- MODE LISTE ---
|
||||
|
||||
// 1. Données pour la CARTE (tous les points valides)
|
||||
$mapIdeas = hol_q($pdo, "
|
||||
SELECT id, title, country, region, city,
|
||||
CAST(lat AS DECIMAL(9,6)) AS lat,
|
||||
CAST(lng AS DECIMAL(9,6)) AS lng,
|
||||
status, desired_start_date, desired_end_date
|
||||
FROM pf_holidays_ideas
|
||||
WHERE status IN ('draft','shortlist','favorite','planned')
|
||||
AND lat IS NOT NULL
|
||||
AND lng IS NOT NULL
|
||||
");
|
||||
|
||||
// 2. Récupérer les listes
|
||||
$planned = hol_q($pdo, "
|
||||
SELECT * FROM pf_holidays_ideas
|
||||
WHERE status = 'planned'
|
||||
ORDER BY COALESCE(desired_start_date, created_at) DESC
|
||||
");
|
||||
$ideas = hol_q($pdo, "
|
||||
SELECT * FROM pf_holidays_ideas
|
||||
WHERE status IN ('draft','shortlist','favorite')
|
||||
ORDER BY FIELD(status,'favorite','shortlist','draft'), created_at DESC
|
||||
");
|
||||
$archived = hol_q($pdo, "
|
||||
SELECT * FROM pf_holidays_ideas
|
||||
WHERE status = 'archived'
|
||||
ORDER BY updated_at DESC
|
||||
");
|
||||
}
|
||||
// Tri par statut
|
||||
$active = array_filter($holidays, fn($h) => in_array($h['status'], ['draft', 'planned', 'booked']));
|
||||
$history = array_filter($holidays, fn($h) => in_array($h['status'], ['passed', 'archived']));
|
||||
?>
|
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css">
|
||||
|
||||
<?php if ($isDetailView): ?>
|
||||
|
||||
<?php if (!$currentIdea): ?>
|
||||
<div class="pf-holidays__titlebar">
|
||||
<h1>Idée introuvable</h1>
|
||||
<div class="hol-title-actions">
|
||||
<a class="btn" href="/holidays.php">← Retour à la liste</a>
|
||||
</div>
|
||||
</div>
|
||||
<p>Cette idée de vacances n'existe pas ou a été supprimée.</p>
|
||||
<?php else: ?>
|
||||
<div class="pf-holidays__titlebar">
|
||||
<h1><?= htmlspecialchars($currentIdea['title']) ?></h1>
|
||||
<div class="hol-title-actions">
|
||||
<a class="btn" href="/holidays.php">← Retour</a>
|
||||
<button class="btn btn-edit" id="hol-edit-open" data-edit-id="<?= (int)$ideaId ?>">Éditer</button>
|
||||
<button class="btn btn-delete" id="hol-delete" data-del-id="<?= (int)$ideaId ?>">Supprimer</button>
|
||||
<button class="hol-map-toggle" id="hol-map-open">🌍 Carte</button>
|
||||
</div>
|
||||
<div class="pf-holidays">
|
||||
|
||||
<div class="pf-holidays__titlebar">
|
||||
<h1>Mes Vacances ✈️</h1>
|
||||
<div class="hol-title-actions">
|
||||
<button class="hol-add-btn" onclick="openHolidayModal('add')">+ Créer un voyage</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="hol-idea-meta">
|
||||
<?= htmlspecialchars(trim(($currentIdea['city'] ? $currentIdea['city'] . ', ' : '') . ($currentIdea['region'] ? $currentIdea['region'] . ', ' : '') . ($currentIdea['country'] ?? ''))) ?>
|
||||
<?php if (!empty($currentIdea['desired_start_date'])): ?>
|
||||
• Dates: <?= htmlspecialchars($currentIdea['desired_start_date']) ?><?= !empty($currentIdea['desired_end_date']) ? ' → ' . htmlspecialchars($currentIdea['desired_end_date']) : '' ?>
|
||||
<?php elseif (!empty($currentIdea['season_hint'])): ?>
|
||||
• Saison: <?= htmlspecialchars($currentIdea['season_hint']) ?>
|
||||
<section class="pf-section">
|
||||
<div class="hol-ideas-grid">
|
||||
<?php if (empty($active)): ?>
|
||||
<p style="color:var(--text-muted); font-style:italic;">Aucun voyage en cours. Planifions quelque chose !</p>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($currentIdea['ideal_days'])): ?>
|
||||
• Durée idéale: <?= (int)$currentIdea['ideal_days'] ?> j
|
||||
<?php endif; ?>
|
||||
• Statut: <strong><?= htmlspecialchars($currentIdea['status']) ?></strong>
|
||||
</p>
|
||||
|
||||
<div class="hol-grid">
|
||||
<section class="pf-section pf-section--panel">
|
||||
<h2>Transport</h2>
|
||||
<form method="post" action="/modules/holidays/save.php" class="hol-inline-form">
|
||||
<input type="hidden" name="action" value="add_transport">
|
||||
<input type="hidden" name="idea_id" value="<?= (int)$ideaId ?>">
|
||||
<select name="mode" required>
|
||||
<option value="TRAIN">TRAIN</option><option value="PLANE">PLANE</option>
|
||||
<option value="CAR">CAR</option><option value="BUS">BUS</option><option value="BOAT">BOAT</option>
|
||||
</select>
|
||||
<input type="number" name="duration_min" min="0" placeholder="Durée (min)">
|
||||
<input type="number" step="0.01" name="cost" placeholder="Coût (€)">
|
||||
<input type="number" step="0.01" name="co2_kg" placeholder="CO₂ (kg)">
|
||||
<input type="url" name="link" placeholder="Lien">
|
||||
<input type="text" name="notes" placeholder="Notes">
|
||||
<button type="submit" class="btn">Ajouter</button>
|
||||
</form>
|
||||
<ul class="hol-list">
|
||||
<?php foreach ($transport as $t): ?>
|
||||
<li><?= htmlspecialchars($t['mode']) ?>
|
||||
<?= $t['duration_min'] !== null ? ' • ' . (int)$t['duration_min'] . ' min' : '' ?>
|
||||
<?= $t['cost'] !== null ? ' • ' . number_format((float)$t['cost'], 0, ',', ' ') . ' €' : '' ?>
|
||||
<?php if (!empty($t['link'])): ?> • <a href="<?= htmlspecialchars($t['link']) ?>" target="_blank" rel="noopener">🔗</a><?php endif; ?>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section class="pf-section pf-section--panel">
|
||||
<h2>Hébergement</h2>
|
||||
<form method="post" action="/modules/holidays/save.php" class="hol-inline-form">
|
||||
<input type="hidden" name="action" value="add_lodging">
|
||||
<input type="hidden" name="idea_id" value="<?= (int)$ideaId ?>">
|
||||
<select name="type" required>
|
||||
<option value="HOTEL">HOTEL</option><option value="APT">APT</option>
|
||||
<option value="HOUSE">HOUSE</option><option value="CAMPING">CAMPING</option><option value="OTHER">OTHER</option>
|
||||
</select>
|
||||
<input type="text" name="location_text" placeholder="Localisation">
|
||||
<input type="number" step="0.01" name="price_per_n" placeholder="€ / nuit">
|
||||
<input type="number" name="nights" placeholder="Nuits">
|
||||
<label><input type="checkbox" name="free_cancel" value="1"> Annulation gratuite</label>
|
||||
<label><input type="checkbox" name="family_friendly" value="1" checked> Family-friendly</label>
|
||||
<input type="url" name="link" placeholder="Lien">
|
||||
<input type="text" name="notes" placeholder="Notes">
|
||||
<button type="submit" class="btn">Ajouter</button>
|
||||
</form>
|
||||
<ul class="hol-list">
|
||||
<?php foreach ($lodging as $l): ?>
|
||||
<li><?= htmlspecialchars($l['type']) ?>
|
||||
<?= !empty($l['location_text']) ? ' • ' . htmlspecialchars($l['location_text']) : '' ?>
|
||||
<?= $l['price_per_n'] !== null ? ' • ' . number_format((float)$l['price_per_n'], 0, ',', ' ') . ' €/nuit' : '' ?>
|
||||
<?= $l['nights'] !== null ? ' × ' . (int)$l['nights'] . 'n' : '' ?>
|
||||
<?php if (!empty($l['link'])): ?> • <a href="<?= htmlspecialchars($l['link']) ?>" target="_blank" rel="noopener">🔗</a><?php endif; ?>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section class="pf-section pf-section--panel">
|
||||
<h2>Activités</h2>
|
||||
<form method="post" action="/modules/holidays/save.php" class="hol-inline-form">
|
||||
<input type="hidden" name="action" value="add_activity">
|
||||
<input type="hidden" name="idea_id" value="<?= (int)$ideaId ?>">
|
||||
<input type="text" name="name" placeholder="Nom" required>
|
||||
<input type="text" name="kind" placeholder="Type (ex: PARK)">
|
||||
<input type="number" step="0.01" name="cost_est" placeholder="€ estimé">
|
||||
<label><input type="checkbox" name="need_booking" value="1"> Réservation</label>
|
||||
<select name="weather">
|
||||
<option value="ANY">ANY</option><option value="GOOD">GOOD</option><option value="RAIN">RAIN</option>
|
||||
</select>
|
||||
<input type="url" name="link" placeholder="Lien">
|
||||
<input type="text" name="notes" placeholder="Notes">
|
||||
<button type="submit" class="btn">Ajouter</button>
|
||||
</form>
|
||||
<ul class="hol-list">
|
||||
<?php foreach ($acts as $a): ?>
|
||||
<li><?= htmlspecialchars($a['name']) ?><?= !empty($a['kind']) ? ' (' . htmlspecialchars($a['kind']) . ')' : '' ?>
|
||||
<?= $a['cost_est'] !== null ? ' • ' . number_format((float)$a['cost_est'], 0, ',', ' ') . ' €' : '' ?>
|
||||
<?= !empty($a['need_booking']) ? ' • Réservation requise' : '' ?>
|
||||
<?php if (!empty($a['link'])): ?> • <a href="<?= htmlspecialchars($a['link']) ?>" target="_blank" rel="noopener">🔗</a><?php endif; ?>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section class="pf-section pf-section--panel">
|
||||
<h2>Budget</h2>
|
||||
<form method="post" action="/modules/holidays/save.php" class="hol-inline-form">
|
||||
<input type="hidden" name="action" value="add_budget">
|
||||
<input type="hidden" name="idea_id" value="<?= (int)$ideaId ?>">
|
||||
<select name="category" required>
|
||||
<option>TRANSPORT</option><option>LODGING</option><option>FOOD</option>
|
||||
<option>ACTIVITIES</option><option>LOCAL</option><option>INSURANCE</option><option>VISAS</option><option>OTHER</option>
|
||||
</select>
|
||||
<input type="text" name="label" placeholder="Label (facultatif)">
|
||||
<input type="number" step="0.01" name="amount" placeholder="Montant (€)" required>
|
||||
<label><input type="checkbox" name="per_person" value="1"> Par personne</label>
|
||||
<button type="submit" class="btn">Ajouter</button>
|
||||
</form>
|
||||
|
||||
<div class="hol-budget-summary">
|
||||
<strong>Fixe:</strong> <?= number_format($fixedTotal, 0, ',', ' ') ?> €
|
||||
• <strong>Par personne:</strong> <?= number_format($ppTotal, 0, ',', ' ') ?> €
|
||||
</div>
|
||||
|
||||
<ul class="hol-list">
|
||||
<?php foreach ($budget as $b): ?>
|
||||
<li>[<?= htmlspecialchars($b['category']) ?>] <?= htmlspecialchars($b['label'] ?? '') ?> —
|
||||
<?= number_format((float)$b['amount'], 0, ',', ' ') ?> €<?= $b['per_person'] ? ' /pers.' : '' ?>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</section>
|
||||
<?php foreach ($active as $h): ?>
|
||||
<?php renderHolidayCard($h, $pdo); ?>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<?php if (!empty($history)): ?>
|
||||
<section class="pf-section" style="margin-top: 40px; border-top: 1px solid #e2e8f0; padding-top: 20px;">
|
||||
<h3 style="color:var(--text-muted);">Historique</h3>
|
||||
<div class="hol-ideas-grid" style="opacity: 0.7;">
|
||||
<?php foreach ($history as $h): ?>
|
||||
<?php renderHolidayCard($h, $pdo); ?>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php else: ?>
|
||||
<div class="pf-holidays__titlebar">
|
||||
<h1>Idées de vacances</h1>
|
||||
<div class="hol-title-actions">
|
||||
<button class="hol-add-btn" id="hol-add-open">+ Ajouter une idée</button>
|
||||
<button class="hol-map-toggle" id="hol-map-open">🌍 Carte</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section class="pf-section pf-section--panel">
|
||||
<h2>Vacances planifiées</h2>
|
||||
<p class="cl-legend">Dates souhaitées, prêtes à être réservées.</p>
|
||||
<div class="hol-ideas-grid">
|
||||
<?php foreach ($planned as $it): ?>
|
||||
<div class="hol-idea-card" data-id="<?= (int)$it['id'] ?>">
|
||||
<div class="hol-idea-card__head">
|
||||
<h3><?= htmlspecialchars($it['title']) ?></h3>
|
||||
<span class="hol-status hol-status--planned">planned</span>
|
||||
</div>
|
||||
<p class="hol-idea-meta">
|
||||
<?= htmlspecialchars(trim(($it['city'] ? $it['city'] . ', ' : '') . ($it['region'] ? $it['region'] . ', ' : '') . ($it['country'] ?? ''))) ?>
|
||||
<?php if (!empty($it['desired_start_date'])): ?>
|
||||
• Dates: <?= htmlspecialchars($it['desired_start_date']) ?><?= !empty($it['desired_end_date']) ? ' → ' . htmlspecialchars($it['desired_end_date']) : '' ?>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($it['ideal_days'])): ?>
|
||||
• Durée idéale: <?= (int)$it['ideal_days'] ?> j
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
<?php if (!empty($it['notes'])): ?>
|
||||
<p class="hol-notes"><?= nl2br(htmlspecialchars(mb_strimwidth($it['notes'], 0, 160, '…'))) ?></p>
|
||||
<?php endif; ?>
|
||||
<div class="hol-card-actions">
|
||||
<a class="btn" href="/holidays.php?id=<?= (int)$it['id'] ?>">Ouvrir</a>
|
||||
<button class="btn btn-edit" data-edit-id="<?= (int)$it['id'] ?>">Éditer</button>
|
||||
<button class="btn btn-delete" data-del-id="<?= (int)$it['id'] ?>">Supprimer</button>
|
||||
</div>
|
||||
<div id="holidayModal" class="pf-modal">
|
||||
<div class="pf-modal-content" style="max-width: 800px; width: 95%;">
|
||||
<h3 id="modalTitle" class="pf-modal-title">Planifier le voyage</h3>
|
||||
|
||||
<form action="/modules/holidays/save_new.php" method="POST" id="holidayForm">
|
||||
<input type="hidden" name="id" id="inp_id">
|
||||
<input type="hidden" name="action" value="save">
|
||||
|
||||
<div class="form-row">
|
||||
<div style="flex: 2;">
|
||||
<label class="pf-label">Nom du voyage</label>
|
||||
<input type="text" name="title" id="inp_title" class="pf-input" placeholder="Ex: Octobre - Portugal" required>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="pf-section pf-section--panel">
|
||||
<h2>Idées</h2>
|
||||
<p class="cl-legend">Brouillons, favoris, shortlist.</p>
|
||||
<div class="hol-ideas-grid">
|
||||
<?php foreach ($ideas as $it): ?>
|
||||
<div class="hol-idea-card" data-id="<?= (int)$it['id'] ?>">
|
||||
<div class="hol-idea-card__head">
|
||||
<h3><?= htmlspecialchars($it['title']) ?></h3>
|
||||
<span class="hol-status hol-status--<?= htmlspecialchars($it['status']) ?>"><?= htmlspecialchars($it['status']) ?></span>
|
||||
</div>
|
||||
<p class="hol-idea-meta">
|
||||
<?= htmlspecialchars(trim(($it['city'] ? $it['city'] . ', ' : '') . ($it['region'] ? $it['region'] . ', ' : '') . ($it['country'] ?? ''))) ?>
|
||||
<?php if (!empty($it['desired_start_date'])): ?>
|
||||
• Dates: <?= htmlspecialchars($it['desired_start_date']) ?><?= !empty($it['desired_end_date']) ? ' → ' . htmlspecialchars($it['desired_end_date']) : '' ?>
|
||||
<?php elseif (!empty($it['season_hint'])): ?>
|
||||
• Saison: <?= htmlspecialchars($it['season_hint']) ?>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($it['ideal_days'])): ?>
|
||||
• Durée idéale: <?= (int)$it['ideal_days'] ?> j
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
<?php if (!empty($it['notes'])): ?>
|
||||
<p class="hol-notes"><?= nl2br(htmlspecialchars(mb_strimwidth($it['notes'], 0, 160, '…'))) ?></p>
|
||||
<?php endif; ?>
|
||||
<div class="hol-card-actions">
|
||||
<a class="btn" href="/holidays.php?id=<?= (int)$it['id'] ?>">Ouvrir</a>
|
||||
<button class="btn btn-edit" data-edit-id="<?= (int)$it['id'] ?>">Éditer</button>
|
||||
<button class="btn btn-delete" data-del-id="<?= (int)$it['id'] ?>">Supprimer</button>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="pf-section pf-section--panel">
|
||||
<h2>Archivées</h2>
|
||||
<div class="hol-ideas-grid hol-ideas-grid--archived">
|
||||
<?php foreach ($archived as $it): ?>
|
||||
<div class="hol-idea-card hol-idea-card--archived" data-id="<?= (int)$it['id'] ?>">
|
||||
<h3><?= htmlspecialchars($it['title']) ?></h3>
|
||||
<div class="hol-card-actions">
|
||||
<button class="btn btn-edit" data-edit-id="<?= (int)$it['id'] ?>">Éditer</button>
|
||||
<button class="btn btn-delete" data-del-id="<?= (int)$it['id'] ?>">Supprimer</button>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="hol-modal" id="hol-add-modal" aria-hidden="true">
|
||||
<div class="hol-backdrop"></div>
|
||||
<div class="hol-dialog" role="dialog" aria-modal="true" aria-labelledby="hol-add-title">
|
||||
<form method="post" action="/modules/holidays/save.php" class="hol-form">
|
||||
<h3 id="hol-add-title">Ajouter une idée</h3>
|
||||
<input type="hidden" name="action" value="create_idea">
|
||||
|
||||
<label>Titre <input type="text" name="title" required></label>
|
||||
|
||||
<div class="hol-inline">
|
||||
<label>Pays <input type="text" name="country"></label>
|
||||
<label>Région <input type="text" name="region"></label>
|
||||
<label>Ville <input type="text" name="city" placeholder="Pour la carte"></label>
|
||||
</div>
|
||||
|
||||
<div class="hol-inline">
|
||||
<label>Lat <input type="number" step="0.000001" name="lat" placeholder="41.385064"></label>
|
||||
<label>Lng <input type="number" step="0.000001" name="lng" placeholder="2.173404"></label>
|
||||
<button type="button" class="btn hol-geocode-btn" data-scope="add">Géocoder</button>
|
||||
</div>
|
||||
|
||||
<div class="hol-inline">
|
||||
<label>Dates souhaitées (début) <input type="date" name="desired_start_date"></label>
|
||||
<label>Dates souhaitées (fin) <input type="date" name="desired_end_date"></label>
|
||||
</div>
|
||||
|
||||
<div class="hol-inline">
|
||||
<label>Saison (facultatif) <input type="text" name="season_hint" placeholder="Mai–Juin"></label>
|
||||
<label>Durée idéale (jours) <input type="number" name="ideal_days" min="1" step="1"></label>
|
||||
</div>
|
||||
|
||||
<label>Statut
|
||||
<select name="status">
|
||||
<option value="draft">draft</option>
|
||||
<option value="shortlist">shortlist</option>
|
||||
<option value="favorite">favorite</option>
|
||||
<option value="planned">planned</option>
|
||||
<option value="archived">archived</option>
|
||||
<div style="flex: 1;">
|
||||
<label class="pf-label">Statut</label>
|
||||
<select name="status" id="inp_status" class="pf-input">
|
||||
<option value="draft">Brouillon ✏️</option>
|
||||
<option value="planned">Planifié 📅</option>
|
||||
<option value="booked">Réservé ✅</option>
|
||||
<option value="passed">Passé 👋</option>
|
||||
<option value="archived">Archivé 🗄️</option>
|
||||
</select>
|
||||
</label>
|
||||
|
||||
<label>Notes <textarea name="notes" rows="4" placeholder="Activités phares, contraintes, liens..."></textarea></label>
|
||||
|
||||
<div class="hol-actions">
|
||||
<button type="button" class="hol-cancel">Annuler</button>
|
||||
<button type="submit" class="hol-ok">Créer</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
<div class="hol-modal" id="hol-edit-modal" aria-hidden="true">
|
||||
<div class="hol-backdrop"></div>
|
||||
<div class="hol-dialog" role="dialog" aria-modal="true" aria-labelledby="hol-edit-title">
|
||||
<form method="post" action="/modules/holidays/save.php" class="hol-form" id="hol-edit-form">
|
||||
<h3 id="hol-edit-title">Éditer l’idée</h3>
|
||||
<input type="hidden" name="action" value="update_idea">
|
||||
<input type="hidden" name="id" id="edit-id">
|
||||
|
||||
<label>Titre <input type="text" name="title" id="edit-title" required></label>
|
||||
|
||||
<div class="hol-inline">
|
||||
<label>Pays <input type="text" name="country" id="edit-country"></label>
|
||||
<label>Région <input type="text" name="region" id="edit-region"></label>
|
||||
<label>Ville <input type="text" name="city" id="edit-city"></label>
|
||||
</div>
|
||||
|
||||
<div class="hol-inline">
|
||||
<label>Lat <input type="number" step="0.000001" name="lat" id="edit-lat"></label>
|
||||
<label>Lng <input type="number" step="0.000001" name="lng" id="edit-lng"></label>
|
||||
<button type="button" class="btn hol-geocode-btn" data-scope="edit">Géocoder</button>
|
||||
<div class="form-row">
|
||||
<div>
|
||||
<label class="pf-label">Période (Texte libre)</label>
|
||||
<input type="text" name="period_hint" id="inp_period" class="pf-input" placeholder="Ex: Octobre 2026">
|
||||
</div>
|
||||
<div style="display:flex; gap:10px;">
|
||||
<div style="flex:1">
|
||||
<label class="pf-label">Du</label>
|
||||
<input type="date" name="start_date" id="inp_start" class="pf-input" lang="fr">
|
||||
</div>
|
||||
<div style="flex:1">
|
||||
<label class="pf-label">Au</label>
|
||||
<input type="date" name="end_date" id="inp_end" class="pf-input" lang="fr">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hol-inline">
|
||||
<label>Début <input type="date" name="desired_start_date" id="edit-start"></label>
|
||||
<label>Fin <input type="date" name="desired_end_date" id="edit-end"></label>
|
||||
<hr style="border: 0; border-top: 1px solid #e2e8f0; margin: 20px 0;">
|
||||
|
||||
<div class="hol-columns-wrapper">
|
||||
|
||||
<div class="hol-col">
|
||||
<div class="hol-col-header">
|
||||
<h4 style="color:#2563eb;">🚗 Transport</h4>
|
||||
<button type="button" class="btn-add-item" onclick="addItem('transport')" title="Ajouter un transport">+</button>
|
||||
</div>
|
||||
<div id="list_transport" class="dynamic-list"></div>
|
||||
</div>
|
||||
|
||||
<div class="hol-col">
|
||||
<div class="hol-col-header">
|
||||
<h4 style="color:#059669;">🏨 Hébergement</h4>
|
||||
<button type="button" class="btn-add-item" onclick="addItem('accommodation')" title="Ajouter un hébergement">+</button>
|
||||
</div>
|
||||
<div id="list_accommodation" class="dynamic-list"></div>
|
||||
</div>
|
||||
|
||||
<div class="hol-col">
|
||||
<div class="hol-col-header">
|
||||
<h4 style="color:#d97706;">🎫 Activité</h4>
|
||||
<button type="button" class="btn-add-item" onclick="addItem('activity')" title="Ajouter une activité">+</button>
|
||||
</div>
|
||||
<div id="list_activity" class="dynamic-list"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hol-inline">
|
||||
<label>Saison <input type="text" name="season_hint" id="edit-season"></label>
|
||||
<label>Durée idéale <input type="number" name="ideal_days" id="edit-days" min="1" step="1"></label>
|
||||
<hr style="border: 0; border-top: 1px solid #e2e8f0; margin: 20px 0;">
|
||||
|
||||
<div class="form-row">
|
||||
<div>
|
||||
<label class="pf-label">🍔 Budget Food & Bev (€)</label>
|
||||
<input type="number" step="0.01" name="budget_food" id="inp_food" class="pf-input" placeholder="0.00">
|
||||
</div>
|
||||
<div>
|
||||
<label class="pf-label">🎁 Budget Extras (€)</label>
|
||||
<input type="number" step="0.01" name="budget_extra" id="inp_extra" class="pf-input" placeholder="0.00">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label>Statut
|
||||
<select name="status" id="edit-status">
|
||||
<option value="draft">draft</option>
|
||||
<option value="shortlist">shortlist</option>
|
||||
<option value="favorite">favorite</option>
|
||||
<option value="planned">planned</option>
|
||||
<option value="archived">archived</option>
|
||||
</select>
|
||||
</label>
|
||||
<div class="form-group">
|
||||
<label class="pf-label">Notes</label>
|
||||
<textarea name="notes" id="inp_notes" class="pf-input" rows="2" placeholder="Idées en vrac..."></textarea>
|
||||
</div>
|
||||
|
||||
<label>Notes <textarea name="notes" rows="4" id="edit-notes"></textarea></label>
|
||||
|
||||
<div class="hol-actions">
|
||||
<button type="button" class="hol-cancel">Annuler</button>
|
||||
<button type="submit" class="hol-ok">Enregistrer</button>
|
||||
<div class="modal-footer">
|
||||
<button type="button" onclick="deleteHoliday()" id="btn_delete" class="pf-btn btn-secondary" style="color:#ef4444; border-color:#fca5a5; margin-right:auto; display:none;">Supprimer</button>
|
||||
<button type="button" onclick="document.getElementById('holidayModal').style.display='none'" class="pf-btn btn-secondary">Annuler</button>
|
||||
<button type="submit" class="pf-btn">Enregistrer</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hol-modal" id="hol-map-modal" aria-hidden="true">
|
||||
<div class="hol-backdrop"></div>
|
||||
<div class="hol-dialog hol-dialog--map" role="dialog" aria-modal="true" aria-labelledby="hol-map-title">
|
||||
<div class="hol-map-header">
|
||||
<h3 id="hol-map-title">Carte des idées</h3>
|
||||
<button class="hol-cancel">Fermer</button>
|
||||
<?php
|
||||
function renderHolidayCard($h, $pdo) {
|
||||
// Récupérer le détail des items pour l'affichage JS futur
|
||||
$stmt = $pdo->prepare("SELECT * FROM pf_holidays_items WHERE holiday_id = ?");
|
||||
$stmt->execute([$h['id']]);
|
||||
$items = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// JSON pour le JS
|
||||
$json = htmlspecialchars(json_encode(['main' => $h, 'items' => $items]), ENT_QUOTES, 'UTF-8');
|
||||
|
||||
// Affichage des dates
|
||||
$dateDisplay = htmlspecialchars($h['period_hint'] ?? '');
|
||||
|
||||
// MODIFICATION ICI : Format d/m/Y (jj/mm/aaaa)
|
||||
if (empty($dateDisplay) && $h['start_date']) {
|
||||
$dateDisplay = date('d/m/Y', strtotime($h['start_date']));
|
||||
if ($h['end_date']) $dateDisplay .= ' → ' . date('d/m/Y', strtotime($h['end_date']));
|
||||
}
|
||||
|
||||
$statusClass = match($h['status']) {
|
||||
'booked' => 'bg-green-100 text-green-800',
|
||||
'planned' => 'bg-blue-100 text-blue-800',
|
||||
'passed' => 'bg-gray-100 text-gray-600',
|
||||
default => 'bg-yellow-50 text-yellow-800'
|
||||
};
|
||||
|
||||
echo "
|
||||
<div class='hol-idea-card' onclick='editHoliday($json)'>
|
||||
<div class='hol-idea-card__head'>
|
||||
<h3>".htmlspecialchars($h['title'])."</h3>
|
||||
<span style='font-size:0.75rem; padding:2px 8px; border-radius:12px; font-weight:bold;' class='$statusClass'>
|
||||
".strtoupper($h['status'])."
|
||||
</span>
|
||||
</div>
|
||||
<div id="hol-map" style="width: 100%; height: calc(100vh - 140px);"></div>
|
||||
<div class='hol-idea-meta'>
|
||||
<span>🗓️ ".($dateDisplay ?: 'Dates à définir')."</span>
|
||||
</div>
|
||||
|
||||
<div style='margin-top:auto; padding-top:10px; border-top:1px solid #f1f5f9; display:flex; justify-content:space-between; align-items:center;'>
|
||||
<span style='font-size:0.85rem; color:#64748b;'>Budget Total</span>
|
||||
<span style='font-size:1.1rem; font-weight:bold; color:#1e293b;'>".number_format($h['total_cost'], 0, ',', ' ')." €</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
";
|
||||
}
|
||||
?>
|
||||
|
||||
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
|
||||
<script>
|
||||
const HOL_MAP_DATA = <?= json_encode($mapIdeas, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>;
|
||||
</script>
|
||||
<script src="/modules/holidays/holidays.js"></script>
|
||||
Reference in New Issue
Block a user