christmas

This commit is contained in:
2026-01-23 12:23:47 +01:00
parent 2df2fd0b2e
commit 3f01cbd8aa
4 changed files with 524 additions and 300 deletions
+236 -134
View File
@@ -1,163 +1,174 @@
<?php
// christmas-list.php
// Protection : nécessite d'être connecté
require __DIR__ . '/includes/auth.php';
require_login();
require_login('/login.php');
// Connexion DB
require __DIR__ . '/includes/db.php';
// Config page
$pageTitle = "PachaFamily - Christmas list";
$pageTitle = "PachaFamily - Llista de regals";
$activePage = "christmas-list";
$bodyClass = "pf-christmas-list";
$pageCss = "/modules/christmas-list/christmas-list.css";
require __DIR__ . '/header.php';
// Constantes
// Constantes “théoriques” pour la grille
$year = (int)date('Y');
$adults = ['Laia', 'Laura', 'Avi Iaia'];
$children = ['Pol', 'Pep', 'Elna', 'Bru', 'Guim'];
$occasions = [
'TIO' => 'Tió',
'NADAL' => 'Nadal',
'REIS' => 'Reis',
// IMPORTANT : aligner les codes avec ta BDD (enum('TIO','NOEL','ROIS'))
$allOccasionLabels = [
'TIO' => 'Tió',
'NOEL' => 'Nadal',
'ROIS' => 'Reis',
];
// Récup données
// Récup toutes les données pour lannée
$stmt = $pdo->prepare("
SELECT *
FROM pf_christmas_gifts
WHERE year = :year
ORDER BY adult_name, child_name, occasion, created_at
");
$stmt->execute(['year' => $year]);
$gifts = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Indexer par [adult][child][occasion]
$byAdult = [];
// Si aucune donnée, on évite les notices plus bas
if (!$gifts) {
$gifts = [];
}
// 1) Indexer par [occasion][child][adult] pour l'affichage par fête
$byOccasion = []; // [occasion][child][adult][] = gifts
foreach ($gifts as $gift) {
$a = $gift['adult_name'];
$c = $gift['child_name'];
$o = $gift['occasion'];
$byAdult[$a][$c][$o][] = $gift;
$c = $gift['child_name'];
$a = $gift['adult_name'];
$byOccasion[$o][$c][$a][] = $gift;
}
?>
<div class="pf-container">
<h1>Christmas list <?= htmlspecialchars($year) ?></h1>
<p>Visió sintètica dels regals per adult, infant i festa. Afegeix nous regals amb el botó “+”.</p>
<h1>Llista de regals <?= htmlspecialchars($year) ?></h1>
<!-- =============================================================== -->
<!-- VUE TABLEAU PAR FÊTE : mini-tableaux par enfant (totaux en tête) -->
<!-- =============================================================== -->
<section class="pf-section pf-section--panel">
<div class="cl-grid-wrapper">
<table class="pf-table cl-grid-table">
<thead>
<!-- Ligne 1 : cellule vide + noms des enfants (colspan=3) -->
<tr>
<th></th>
<?php foreach ($children as $child): ?>
<th colspan="<?= count($occasions) ?>" class="cl-child-header">
<?= htmlspecialchars($child) ?>
</th>
<?php endforeach; ?>
</tr>
<h2>Vista per festa</h2>
<!-- Ligne 2 : Adult + Tió / Nadal / Reis pour chaque enfant -->
<tr>
<th class="cl-header-adult">Adult</th>
<?php foreach ($children as $child): ?>
<?php foreach ($occasions as $occCode => $occLabel): ?>
<th class="cl-header-occ"><?= htmlspecialchars($occLabel) ?></th>
<?php endforeach; ?>
<?php endforeach; ?>
</tr>
</thead>
<tbody>
<?php foreach ($adults as $adult): ?>
<tr>
<!-- Colonne adulte -->
<td class="cl-adult-cell"><?= htmlspecialchars($adult) ?></td>
<!-- Colonnes (enfant x fête) -->
<?php foreach ($children as $child): ?>
<?php foreach ($occasions as $occCode => $occLabel): ?>
<?php
$cellGifts = $byAdult[$adult][$child][$occCode] ?? [];
$total = array_sum(array_column($cellGifts, 'amount'));
// Id unique pour cette cellule (pour cibler le menu en JS)
$cellId = 'cell_' . md5($adult . '_' . $child . '_' . $occCode);
?>
<td class="cl-gift-cell" data-cell-id="<?= $cellId ?>">
<div class="cl-gift-cell-content">
<?php if (!empty($cellGifts)): ?>
<ul class="cl-gift-list">
<?php foreach ($cellGifts as $gift): ?>
<li>
<?= htmlspecialchars($gift['gift_description']) ?>
<?php if ($gift['amount'] > 0): ?>
<span class="cl-gift-amount">
(<?= number_format($gift['amount'], 0, ',', ' ') ?> €)
</span>
<?php endif; ?>
</li>
<?php endforeach; ?>
</ul>
<?php else: ?>
<span class="cl-empty"> Cap regal</span>
<?php if (empty($gifts)): ?>
<p>No hi ha cap regal registrat per a <?= htmlspecialchars($year) ?>.</p>
<?php endif; ?>
<div class="cl-total-and-add">
<div class="cl-gift-total">
<?php if ($total > 0): ?>
Total: <?= number_format($total, 0, ',', ' ') ?> €
<?php else: ?>
&nbsp;
<?php endif; ?>
</div>
<?php foreach ($allOccasionLabels as $occCode => $occLabel): ?>
<div class="cl-occasion-block">
<h3 class="cl-occasion-title"><?= htmlspecialchars($occLabel) ?></h3>
<button type="button"
class="cl-add-btn"
data-target="<?= $cellId ?>">
+
</button>
</div>
</div>
<div class="cl-occasion-children-tables">
<?php
// Afficher tous les enfants (même vides) pour garder l'ordre fixe
$childrenForOccasion = $children;
<!-- Menu d'ajout caché au départ -->
<div class="cl-add-menu" id="<?= $cellId ?>">
<form method="post" action="/modules/christmas-list/save-gift.php" class="cl-gift-form">
<input type="hidden" name="year" value="<?= $year ?>">
<input type="hidden" name="adult_name" value="<?= htmlspecialchars($adult) ?>">
<input type="hidden" name="child_name" value="<?= htmlspecialchars($child) ?>">
<input type="hidden" name="occasion" value="<?= htmlspecialchars($occCode) ?>">
foreach ($childrenForOccasion as $childName):
// Prépare les listes par adulte pour cet enfant et cette fête
$lists = [];
$totals = [];
foreach ($adults as $adultName) {
$lists[$adultName] = $byOccasion[$occCode][$childName][$adultName] ?? [];
$totals[$adultName] = array_sum(array_map(
fn($g) => (float)$g['amount'],
$lists[$adultName]
));
}
// Nombre de lignes: max des tailles de listes Laia/Laura/Avi Iaia
$maxRowsChild = max(array_map('count', $lists));
?>
<table class="cl-child-table child-<?= strtolower($childName) ?>">
<colgroup>
<col class="cl-col" />
<col class="cl-col" />
<col class="cl-col" />
</colgroup>
<input type="text" name="gift_description" placeholder="Regal..." required>
<div class="cl-gift-form-row">
<input type="url" name="product_link" placeholder="Enllaç">
<input type="number" name="amount" placeholder="€" step="0.01" min="0">
</div>
<div class="cl-gift-form-actions">
<button type="button" class="cl-cancel-btn" data-target="<?= $cellId ?>">Cancel·lar</button>
<button type="submit" class="cl-ok-btn">OK</button>
</div>
</form>
</div>
</td>
<caption>
<?= htmlspecialchars($childName) ?>
<button
type="button"
class="cl-child-add-btn"
title="Afegeix un regal"
data-year="<?= $year ?>"
data-child="<?= htmlspecialchars($childName) ?>"
data-occasion="<?= htmlspecialchars($occCode) ?>"
>+</button>
</caption>
<thead>
<tr>
<?php foreach ($adults as $adultName): ?>
<th>
<div class="cl-th-inner">
<span class="cl-th-label"><?= htmlspecialchars($adultName) ?></span>
<span class="cl-summary-adult-total">
<?= number_format($totals[$adultName], 0, ',', ' ') ?> €
</span>
</div>
</th>
<?php endforeach; ?>
<?php endforeach; ?>
</tr>
</tr>
</thead>
<tbody>
<?php if ($maxRowsChild === 0): ?>
<tr>
<td><span class="cl-empty">—</span></td>
<td><span class="cl-empty">—</span></td>
<td><span class="cl-empty">—</span></td>
</tr>
<?php else: ?>
<?php for ($i = 0; $i < $maxRowsChild; $i++): ?>
<tr>
<?php foreach ($adults as $adultName): ?>
<?php $gift = $lists[$adultName][$i] ?? null; ?>
<td>
<?php if ($gift): ?>
<?php
$desc = htmlspecialchars($gift['gift_description']);
$amt = (float)$gift['amount'];
$plink = trim($gift['product_link'] ?? '');
?>
<?php if ($plink !== ''): ?>
<a href="<?= htmlspecialchars($plink) ?>" target="_blank" rel="noopener noreferrer" class="cl-gift-link"><?= $desc ?></a>
<?php else: ?>
<span class="cl-gift-desc"><?= $desc ?></span>
<?php endif; ?>
<?php if ($amt > 0): ?>
<span class="cl-gift-amount">(<?= number_format($amt, 0, ',', ' ') ?> €)</span>
<?php endif; ?>
<?php else: ?>
<span class="cl-empty">—</span>
<?php endif; ?>
</td>
<?php endforeach; ?>
</tr>
<?php endfor; ?>
<?php endif; ?>
</tbody>
</table>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
<?php endforeach; ?>
</section>
<!-- =============================================================== -->
<!-- RÉSUMÉ DU BUDGET (AGGRÉGÉ) -->
<!-- =============================================================== -->
<section class="pf-section pf-section--panel">
<h2>Resum del pressupost</h2>
<?php
@@ -187,7 +198,7 @@ foreach ($gifts as $gift) {
<tr>
<td><?= htmlspecialchars($row['adult_name']) ?></td>
<td><?= htmlspecialchars($row['child_name']) ?></td>
<td><?= htmlspecialchars($occasions[$row['occasion']] ?? $row['occasion']) ?></td>
<td><?= htmlspecialchars($allOccasionLabels[$row['occasion']] ?? $row['occasion']) ?></td>
<td><?= number_format($row['total'], 0, ',', ' ') ?> €</td>
</tr>
<?php endforeach; ?>
@@ -195,38 +206,129 @@ foreach ($gifts as $gift) {
</table>
</div>
</section>
<!-- =============================================================== -->
<!-- LISTE DÉTAILLÉE DES CADEAUX (vue "debug"/admin") -->
<!-- =============================================================== -->
<section class="pf-section pf-section--panel">
<h2>Llista detallada de regals</h2>
<div class="cl-detail-wrapper">
<table class="pf-table pf-table--compact">
<thead>
<tr>
<th>Adult</th>
<th>Infant</th>
<th>Festa</th>
<th>Regal</th>
<th>€</th>
<th>Enllaç</th>
</tr>
</thead>
<tbody>
<?php foreach ($gifts as $g): ?>
<tr>
<td><?= htmlspecialchars($g['adult_name']) ?></td>
<td><?= htmlspecialchars($g['child_name']) ?></td>
<td><?= htmlspecialchars($allOccasionLabels[$g['occasion']] ?? $g['occasion']) ?></td>
<td><?= htmlspecialchars($g['gift_description']) ?></td>
<td><?= number_format($g['amount'], 0, ',', ' ') ?></td>
<td>
<?php if (!empty($g['product_link'])): ?>
<a href="<?= htmlspecialchars($g['product_link']) ?>" target="_blank">🔗</a>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</section>
</div>
<!-- JS inline simple pour ouvrir/fermer les menus d'ajout -->
<!-- JS inline : modale d'ajout de cadeau -->
<script>
document.addEventListener('DOMContentLoaded', function () {
// Ouvrir le menu associé au bouton +
document.querySelectorAll('.cl-add-btn').forEach(function (btn) {
// Modale d'ajout de cadeau (bouton + à côté du nom de l'enfant)
const modal = document.getElementById('cl-gift-modal');
const backdrop = modal.querySelector('.cl-modal-backdrop');
const cancelBtn = modal.querySelector('.clm-cancel');
document.querySelectorAll('.cl-child-add-btn').forEach(function (btn) {
btn.addEventListener('click', function () {
const targetId = btn.getAttribute('data-target');
const menu = document.getElementById(targetId);
const year = btn.getAttribute('data-year');
const child = btn.getAttribute('data-child');
const occasion = btn.getAttribute('data-occasion');
// Fermer les autres menus avant d'ouvrir celui-ci
document.querySelectorAll('.cl-add-menu').forEach(function (m) {
if (m.id !== targetId) {
m.classList.remove('cl-add-menu--open');
}
});
modal.classList.add('cl-open');
menu.classList.toggle('cl-add-menu--open');
// Remplir les champs cachés
document.getElementById('clm-year').value = year;
document.getElementById('clm-child').value = child;
document.getElementById('clm-occasion').value = occasion;
// Reset des champs visibles
document.getElementById('clm-adult').selectedIndex = 0;
document.getElementById('clm-gift').value = '';
document.getElementById('clm-amount').value = '';
document.getElementById('clm-link').value = '';
});
});
// Boutons Cancel·lar pour fermer le menu
document.querySelectorAll('.cl-cancel-btn').forEach(function (btn) {
btn.addEventListener('click', function () {
const targetId = btn.getAttribute('data-target');
const menu = document.getElementById(targetId);
menu.classList.remove('cl-add-menu--open');
});
});
function closeModal() {
modal.classList.remove('cl-open');
}
cancelBtn.addEventListener('click', closeModal);
backdrop.addEventListener('click', closeModal);
});
</script>
<!-- Modal d'ajout de cadeau -->
<div id="cl-gift-modal" class="cl-modal" aria-hidden="true">
<div class="cl-modal-backdrop"></div>
<div class="cl-modal-dialog" role="dialog" aria-modal="true" aria-labelledby="cl-modal-title">
<form method="post" action="/modules/christmas-list/save-gift.php" class="cl-modal-form">
<h3 id="cl-modal-title">Afegeix un regal</h3>
<!-- Champs cachés (contexte) -->
<input type="hidden" name="year" id="clm-year" value="<?= $year ?>">
<input type="hidden" name="child_name" id="clm-child" value="">
<input type="hidden" name="occasion" id="clm-occasion" value="">
<!-- Adulte -->
<label class="clm-label">
Adult
<select name="adult_name" id="clm-adult" required>
<?php foreach ($adults as $adultName): ?>
<option value="<?= htmlspecialchars($adultName) ?>"><?= htmlspecialchars($adultName) ?></option>
<?php endforeach; ?>
</select>
</label>
<!-- Cadeau -->
<label class="clm-label">
Nom del regal
<input type="text" name="gift_description" id="clm-gift" placeholder="p. ex., Lego Star Wars" required>
</label>
<!-- Montant -->
<label class="clm-label">
Preu (€)
<input type="number" name="amount" id="clm-amount" placeholder="p. ex., 49,99" step="0.01" min="0">
</label>
<!-- Lien produit (optionnel) -->
<label class="clm-label">
Enllaç (opcional)
<input type="url" name="product_link" id="clm-link" placeholder="https://exemple.com/producte">
</label>
<div class="cl-modal-actions">
<button type="button" class="clm-cancel">Cancel·la</button>
<button type="submit" class="clm-ok">Desa</button>
</div>
</form>
</div>
</div>
<?php
require __DIR__ . '/footer.php';