Files
HouseHub/family-calendar.php
T
2026-06-08 10:00:56 +02:00

292 lines
14 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/family-calendar/family-calendar.php
ini_set('display_errors', 1);
error_reporting(E_ALL);
require __DIR__ . '/includes/auth.php';
require_login();
require __DIR__ . '/includes/db.php';
require_once __DIR__ . '/includes/i18n.php';
// 1. Récupération de toutes les personnes avec leurs modes de garde
$stmtPeople = $pdo->query("SELECT id, name, user_id, role, care_modes FROM pf_people ORDER BY id ASC");
$familyPeople = $stmtPeople->fetchAll(PDO::FETCH_ASSOC);
$parents = [];
$kids = [];
// Liste de tous les modes de garde actifs dans le foyer
$activeCareModes = [];
foreach ($familyPeople as $p) {
$role = strtolower($p['role'] ?? '');
if ($role === 'parent') {
$parents[] = $p;
} elseif ($role === 'enfant') {
// Décodage sécurisé des modes de garde
$modes = json_decode($p['care_modes'] ?? '[]', true);
if (!is_array($modes)) $modes = [];
$p['modes'] = $modes;
$kids[] = $p;
foreach ($modes as $m) {
$activeCareModes[$m] = true;
}
}
}
$activeCareModes = array_keys($activeCareModes); // On récupère uniquement les noms uniques
$pageTitle = tr('fc_page_title');
$activePage = "family-calendar";
$mainClass = "pf-family-calendar";
$pageCss = "/modules/family-calendar/family-calendar.css";
require __DIR__ . '/header.php';
?>
<div class="pf-container" style="max-width:100%; padding:0;">
<div class="fc-header-row">
<h1><?= tr('fc_main_header') ?></h1>
<div style="display: flex; gap: 10px;">
<button id="btnOpenSnapshotModal" class="pf-btn-icon-text">
<span class="icon">⚖️</span>
<span class="text"><?= tr('fc_btn_correct_balances') ?></span>
</button>
<button id="btnOpenHolidays" class="pf-btn-icon-text">
<span class="icon">🏖️</span>
<span class="text"><?= tr('fc_btn_school_holidays') ?></span>
</button>
</div>
</div>
<div id="modalHolidays" class="pf-modal">
<div class="pf-modal-content">
<div class="pf-modal-header">
<h3 class="pf-modal-title">
<?= tr('fc_modal_holidays_title') ?>
<?php if (defined('ZONE_SCOLAIRE') && ZONE_SCOLAIRE !== 'Autre') echo '(Zone ' . htmlspecialchars(ZONE_SCOLAIRE) . ')'; ?>
</h3>
<button id="btnCloseHolidays" class="pf-modal-close" onclick="document.getElementById('modalHolidays').classList.remove('active')">&times;</button>
</div>
<div class="pf-modal-body" style="padding:0;">
<div style="width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch;">
<table id="schoolHolidaysTable" class="fc-holidays-table" style="min-width: 400px;">
<thead>
<tr>
<th><?= tr('fc_col_period') ?></th>
<th><?= tr('fc_col_from') ?></th>
<th><?= tr('fc_col_to') ?></th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
</div>
</div>
<div id="modalSnapshot" class="pf-modal">
<div class="pf-modal-content">
<div class="pf-modal-header">
<h3 class="pf-modal-title">📸 <?= tr('fc_modal_snap_title') ?></h3>
<button type="button" id="btnCloseSnapshot" class="pf-modal-close" onclick="document.getElementById('modalSnapshot').classList.remove('open'); document.body.classList.remove('no-scroll');">&times;</button>
</div>
<div class="pf-modal-body">
<form id="formSnapshot">
<div class="pf-form-row">
<div class="pf-form-group">
<label class="pf-label"><?= tr('fc_label_person') ?></label>
<select id="snapPerson" class="pf-input" required>
<option value="" disabled selected>-- <?= tr('fc_choose_person') ?> --</option>
<?php foreach ($familyPeople as $person): ?>
<option value="<?= htmlspecialchars($person['id']) ?>">
<?= htmlspecialchars($person['name']) ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="pf-form-group">
<label class="pf-label"><?= tr('fc_label_leave_type') ?></label>
<select id="snapType" class="pf-input" required>
<option value="CP">CP</option>
<option value="JRA">JRA</option>
<option value="JA">JA</option>
</select>
</div>
</div>
<div class="pf-form-group">
<label class="pf-label"><?= tr('fc_label_apply_date') ?></label>
<input type="date" id="snapDate" class="pf-input" required title="<?= tr('fc_snap_date_hint') ?>">
</div>
<div class="pf-form-group">
<label class="pf-label"><?= tr('fc_label_remaining_balance') ?></label>
<div style="display:flex; align-items:center;">
<input type="number" step="0.5" id="snapBalance" class="pf-input" placeholder="<?= tr('fc_placeholder_balance') ?>" style="border-radius: 8px 0 0 8px; border-right: none; font-weight: bold; color: var(--pf-primary);" required>
<span style="background: var(--pf-bg-lighter); border: 1px solid var(--pf-border); padding: 0 12px; height: 42px; display: flex; align-items: center; border-radius: 0 8px 8px 0; color: var(--pf-text-muted); font-size: 0.9rem; font-weight: 600;">
<?= tr('fc_unit_days') ?>
</span>
</div>
</div>
</form>
</div>
<div class="pf-modal-footer">
<button type="button" class="pf-btn pf-btn-secondary" onclick="document.getElementById('modalSnapshot').classList.remove('open'); document.body.classList.remove('no-scroll');"><?= tr('btn_cancel') ?></button>
<button type="submit" form="formSnapshot" class="pf-btn pf-btn-primary"><?= tr('fc_btn_save_snap') ?></button>
</div>
</div>
</div>
<section class="pf-section">
<div class="fc-month-calendar-wrapper">
<div class="fc-month-header">
<div class="fc-month-nav-row">
<button id="fc-prev-month" class="fc-nav-button"></button>
<div id="fc-smart-date-selector" style="display:flex; align-items:center; justify-content:center; flex-grow:1; gap:6px;">
<select id="fc-select-month" class="fc-smart-select"></select>
<select id="fc-select-year" class="fc-smart-select"></select>
<span id="fc-multi-month-suffix" style="display:none; font-size:1.3rem; font-weight:800; color:#0f172a; margin-left:4px;"></span>
</div>
<button id="fc-next-month" class="fc-nav-button"></button>
</div>
<div class="fc-view-controls">
<button id="fc-today-btn" class="fc-today-button" title="<?= tr('fc_today_title') ?>"><?= tr('fc_today_short') ?></button> <div class="fc-view-divider"></div>
<button class="fc-view-button fc-view-button--active" data-view="1month"><?= tr('fc_view_1m') ?></button>
<button class="fc-view-button" data-view="2months"><?= tr('fc_view_2m') ?></button>
<button class="fc-view-button" data-view="3months"><?= tr('fc_view_3m') ?></button>
</div>
</div>
<div class="fc-calendar-container">
<div id="fc-month-calendar" class="fc-month-calendar"></div>
<div id="fc-month-selectionMenu" class="fc-selection-menu" style="display:none;"></div>
</div>
<div id="fc-month-balances" class="fc-month-balances"></div>
</div>
</section>
<section class="pf-section">
<div class="fc-week-header">
<h2><?= tr('fc_weekly_planning') ?></h2>
<div class="fc-week-nav-controls">
<button id="fc-prev-school-year" class="fc-nav-button"></button>
<span id="fc-current-school-year-label"></span>
<button id="fc-next-school-year" class="fc-nav-button"></button>
</div>
</div>
<div id="planningTable-wrapper">
<table id="planningTable">
<thead>
<tr>
<th rowspan="3" class="col-month col-sticky-mois"><?= tr('fc_col_month') ?></th>
<th rowspan="3" class="col-month col-sticky-mois"><?= tr('fc_col_week_short') ?></th>
<th rowspan="3" class="col-day"><?= tr('day_mon') ?></th>
<th rowspan="3" class="col-day"><?= tr('day_tue') ?></th>
<th rowspan="3" class="col-day"><?= tr('day_wed') ?></th>
<th rowspan="3" class="col-day"><?= tr('day_thu') ?></th>
<th rowspan="3" class="col-day"><?= tr('day_fri') ?></th>
<?php foreach ($activeCareModes as $mode): ?>
<th rowspan="3" class="col-total rotated-text"><span><?= htmlspecialchars($mode) ?></span></th>
<?php endforeach; ?>
<?php foreach ($kids as $kid): ?>
<th rowspan="3" class="col-total rotated-text"><span>Maladie <?= htmlspecialchars($kid['name']) ?></span></th>
<?php endforeach; ?>
<?php foreach ($parents as $index => $parent):
$parentClass = ($index % 2 === 0) ? 'col-alex' : 'col-laia';
?>
<th colspan="6" class="<?= $parentClass ?> header-group"><?= htmlspecialchars(strtoupper($parent['name'])) ?></th>
<?php endforeach; ?>
</tr>
<tr>
<?php foreach ($parents as $index => $parent):
$parentClass = ($index % 2 === 0) ? 'col-alex' : 'col-laia';
?>
<th colspan="2" class="<?= $parentClass ?>-sub">CP</th>
<th colspan="2" class="<?= $parentClass ?>-sub">JRA</th>
<th colspan="2" class="<?= $parentClass ?>-sub">JA</th>
<?php endforeach; ?>
</tr>
<tr>
<?php foreach ($parents as $index => $parent):
$parentClass = ($index % 2 === 0) ? 'col-alex' : 'col-laia';
?>
<th class="<?= $parentClass ?>-sub <?= $parentClass ?>-av"><?= tr('fc_col_av') ?></th>
<th class="<?= $parentClass ?>-sub <?= $parentClass ?>-use"><?= tr('fc_col_use') ?></th>
<th class="<?= $parentClass ?>-sub <?= $parentClass ?>-av"><?= tr('fc_col_av') ?></th>
<th class="<?= $parentClass ?>-sub <?= $parentClass ?>-use"><?= tr('fc_col_use') ?></th>
<th class="<?= $parentClass ?>-sub <?= $parentClass ?>-av"><?= tr('fc_col_av') ?></th>
<th class="<?= $parentClass ?>-sub <?= $parentClass ?>-use"><?= tr('fc_col_use') ?></th>
<?php endforeach; ?>
</tr>
</thead>
<tbody id="planningBody"></tbody>
</table>
<div id="selectionMenu" class="fc-selection-menu" style="display:none;"></div>
</div>
</section>
<section class="pf-section pf-section--bottom-panels">
<div class="fc-bottom-grid">
<div class="pf-card">
<div class="pf-card-title fc-summary-header">
<span><?= tr('fc_summary_title') ?></span>
<div class="fc-summary-controls">
<select id="summType" class="fc-summ-select">
<option value="year"><?= tr('fc_summ_year') ?></option>
<option value="month"><?= tr('fc_summ_month') ?></option>
</select>
<select id="summValue" class="fc-summ-select"></select>
</div>
</div>
<div class="pf-card-body">
<div id="globalSummary" class="fc-summary-vertical"></div>
</div>
</div>
<div class="pf-card">
<h2 class="pf-card-title"><?= tr('fc_legend_title') ?></h2>
<div class="pf-card-body">
<div class="pf-legend-grid">
<div class="pf-legend-item"><div class="pf-legend-color fc-legend-school-holiday"></div><span><?= tr('leg_school_holidays') ?></span></div>
<div class="pf-legend-item"><div class="pf-legend-color fc-legend-public-holiday"></div><span><?= tr('leg_public_holiday') ?></span></div>
<?php foreach ($activeCareModes as $index => $mode):
// Génération d'une couleur pseudo-aléatoire mais fixe par mode
$hue = ($index * 137) % 360;
?>
<div class="pf-legend-item">
<div class="pf-legend-color" style="background: hsl(<?= $hue ?>, 70%, 50%);"></div>
<span><?= htmlspecialchars($mode) ?></span>
</div>
<?php endforeach; ?>
<?php foreach ($kids as $kid): ?>
<div class="pf-legend-item">
<div class="pf-legend-color" style="background: var(--pf-danger, #ef4444); opacity: 0.8;"></div>
<span>Maladie <?= htmlspecialchars($kid['name']) ?></span>
</div>
<?php endforeach; ?>
</div>
</div>
</div>
</div>
</section>
</div>
<script>
// 🟢 OBJET DE CONFIGURATION GLOBAL POUR LE JAVASCRIPT
window.FAMILY_CONFIG = {
parents: <?= json_encode($parents) ?>,
kids: <?= json_encode($kids) ?>,
activeCareModes: <?= json_encode($activeCareModes) ?>
};
</script>
<script src="/modules/family-calendar/family-calendar.js"></script>
<?php require __DIR__ . '/footer.php'; ?>