Files
HouseHub/modules/holidays/index.php
T
2026-03-28 18:20:21 +01:00

229 lines
10 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
// modules/holidays/index.php
// 1. Récupération des voyages + Calculs (Coût Total ET Montant déjà financé)
// 1. Récupération des voyages + Calculs (Coût Total ET Montant déjà financé)
$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,
(
COALESCE((SELECT SUM(ABS(amount)) FROM pf_expenses WHERE holiday_id = h.id), 0) +
COALESCE((SELECT SUM(amount) FROM pf_savings WHERE holiday_id = h.id), 0)
) as total_funded
FROM pf_holidays h
ORDER BY
-- COALESCE permet de rejeter les voyages sans date tout à la fin de la liste (ex: l'an 2999)
COALESCE(start_date, '2999-12-31') ASC,
FIELD(status, 'booked', 'planned', 'draft', 'passed', 'archived')
";
$holidays = $pdo->query($sql)->fetchAll(PDO::FETCH_ASSOC);
// 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']));
?>
<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>
<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 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; ?>
</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>
<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>
</div>
</div>
<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>
<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>
<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>
<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>
<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>
<?php
function renderHolidayCard($h, $pdo) {
$stmt = $pdo->prepare("SELECT * FROM pf_holidays_items WHERE holiday_id = ?");
$stmt->execute([$h['id']]);
$items = $stmt->fetchAll(PDO::FETCH_ASSOC);
$json = htmlspecialchars(json_encode(['main' => $h, 'items' => $items]), ENT_QUOTES, 'UTF-8');
$dateDisplay = htmlspecialchars($h['period_hint'] ?? '');
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'
};
// --- NOUVEAU : Calcul de la progression ---
$cost = (float)$h['total_cost'];
$funded = (float)$h['total_funded'];
$leftToPay = max(0, $cost - $funded);
// Pourcentage pour la barre de progression (max 100%)
$percent = $cost > 0 ? min(100, round(($funded / $cost) * 100)) : 0;
// Couleur de la barre : Rouge si < 50%, Jaune si < 100%, Vert si tout est payé
$barColor = $percent === 100 ? '#10b981' : ($percent > 50 ? '#f59e0b' : '#ef4444');
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 class='hol-idea-meta'>
<span>🗓️ ".($dateDisplay ?: 'Dates à définir')."</span>
</div>
<div style='margin-top:auto; padding-top:10px; border-top:1px solid #f1f5f9;'>
<div style='display:flex; justify-content:space-between; align-items:center; margin-bottom:5px;'>
<span style='font-size:0.85rem; color:#64748b;'>Budget Total</span>
<span style='font-size:1rem; font-weight:bold; color:#1e293b;'>".number_format($cost, 0, ',', ' ')." €</span>
</div>
<div style='width:100%; height:6px; background:#e2e8f0; border-radius:3px; margin-bottom:8px; overflow:hidden;'>
<div style='width:{$percent}%; height:100%; background:{$barColor}; transition:width 0.3s ease;'></div>
</div>
<div style='display:flex; justify-content:space-between; align-items:center; font-size:0.8rem;'>
<span style='color:#10b981; font-weight:600;'>✓ Financé : ".number_format($funded, 0, ',', ' ')." €</span>
<span style='color:#ef4444; font-weight:600;'>Reste : ".number_format($leftToPay, 0, ',', ' ')." €</span>
</div>
</div>
</div>
";
}
?>
<script src="/modules/holidays/holidays.js"></script>