V7.9 — Tableau de bord et navigation regroupée pour le Service Enfance

Le Service Enfance ouvrait onze onglets à plat et atterrissait sur l'écran de
saisie, alors que son travail commence par le contrôle. Les chiffres qui
déclenchent une action vivaient sur trois écrans distincts.

- Nouvelle page dashboard.php, réservée au Service Enfance et devenue sa page
  d'atterrissage : quatre tuiles d'action, les brouillons les plus anciens avec
  ouverture directe sur la bonne semaine, les plages de couverture les plus
  déficitaires, et le suivi des quotas annuels par agent.
- Navigation regroupée par intention (Piloter / Planifier / Consulter /
  Paramétrer). Les rôles à quelques pages gardent la barre simple.
- Sous-titre propre à chaque page : le bandeau générique n'apprenait rien.
- Pastille « À valider » alimentée depuis toutes les pages, et non plus
  seulement depuis la page qu'elle annonce.

Aucune règle métier n'est modifiée : le tableau de bord relit ce que
PlanningModel, CoverageModel et QuotaModel calculent déjà, et son endpoint est
gardé par requireService(). Le droit d'accès à la page vient de la migration
V7.9 ; sans elle, l'onglet n'apparaît pas et homeUrl() se replie sur planning.

Vérifié sur la base réelle : les chiffres de quota du tableau de bord sont
identiques à ceux de api/annual_overview.php, les trois rôles rendent leurs
écrans sans erreur, le rendu JS a été exécuté dans un DOM avec la réponse réelle
de l'API, et la page ne produit aucun attribut style inline (CSP).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
PTA
2026-08-10 16:48:50 +02:00
parent 66cc8c8ade
commit b68ac15de5
17 changed files with 1571 additions and 24 deletions

View File

@@ -0,0 +1,164 @@
<?php
/** @var string $currentWeek */
?>
<section id="dashboard-view" class="app-view page-content dashboard-page">
<section class="card dashboard-context-card">
<div class="section-heading">
<div>
<h2>Semaine de travail</h2>
<p class="section-subtitle" id="dashboard-week-label">Chargement de la semaine en cours…</p>
</div>
<div class="dashboard-context-actions">
<label class="field dashboard-week-field">
<span>Semaine analysée</span>
<input id="dashboard-week" type="week" value="<?= htmlspecialchars($currentWeek) ?>">
</label>
<button id="dashboard-refresh" class="button button-secondary" type="button">Actualiser</button>
</div>
</div>
<p class="dashboard-context-note" id="dashboard-week-context" hidden></p>
</section>
<div id="dashboard-message" class="message" role="status" aria-live="polite"></div>
<div id="dashboard-loading" class="empty-state" hidden>Consolidation des indicateurs…</div>
<div class="dashboard-tiles" aria-live="polite">
<a class="dashboard-tile dashboard-tile-action" id="dashboard-tile-pending" href="pending.php">
<span class="dashboard-tile-label">Plannings à valider</span>
<strong class="dashboard-tile-value" id="dashboard-pending-count">—</strong>
<small class="dashboard-tile-detail" id="dashboard-pending-detail">Brouillons contenant des affectations</small>
<span class="dashboard-tile-cta">Ouvrir la file de validation</span>
</a>
<a class="dashboard-tile dashboard-tile-action" id="dashboard-tile-coverage" href="coverage.php">
<span class="dashboard-tile-label">Manques de couverture</span>
<strong class="dashboard-tile-value" id="dashboard-coverage-count">—</strong>
<small class="dashboard-tile-detail" id="dashboard-coverage-detail">Sur la semaine analysée</small>
<span class="dashboard-tile-cta">Voir le détail des plages</span>
</a>
<a class="dashboard-tile dashboard-tile-action" id="dashboard-tile-quota" href="annual.php">
<span class="dashboard-tile-label">Quotas dépassés</span>
<strong class="dashboard-tile-value" id="dashboard-quota-count">—</strong>
<small class="dashboard-tile-detail" id="dashboard-quota-detail">Agents au-delà de leur quota annuel</small>
<span class="dashboard-tile-cta">Ouvrir la vue annuelle</span>
</a>
<a class="dashboard-tile dashboard-tile-action" id="dashboard-tile-setup" href="administration.php">
<span class="dashboard-tile-label">Lieux à paramétrer</span>
<strong class="dashboard-tile-value" id="dashboard-setup-count">—</strong>
<small class="dashboard-tile-detail" id="dashboard-setup-detail">Sans horaires de couverture attendus</small>
<span class="dashboard-tile-cta">Ouvrir l’administration</span>
</a>
</div>
<div class="dashboard-columns">
<section class="card dashboard-list-card">
<div class="section-heading">
<div>
<h2>À valider en priorité</h2>
<p class="section-subtitle">Les brouillons dont la semaine est la plus ancienne.</p>
</div>
<a class="button button-secondary" href="pending.php">Tout voir</a>
</div>
<div id="dashboard-pending-empty" class="empty-state" hidden>Aucun planning n’attend de validation.</div>
<ul class="dashboard-list" id="dashboard-pending-list"></ul>
</section>
<section class="card dashboard-list-card">
<div class="section-heading">
<div>
<h2>Couverture à renforcer</h2>
<p class="section-subtitle">Les plages les plus déficitaires de la semaine analysée.</p>
</div>
<a class="button button-secondary" id="dashboard-coverage-link" href="coverage.php">Tout voir</a>
</div>
<div id="dashboard-coverage-empty" class="empty-state" hidden>Aucun manque de couverture sur cette semaine.</div>
<ul class="dashboard-list" id="dashboard-coverage-list"></ul>
<div id="dashboard-coverage-unconfigured" class="dashboard-inline-note" hidden></div>
</section>
</div>
<section class="card dashboard-quota-card">
<div class="section-heading">
<div>
<h2>Suivi des quotas annuels</h2>
<p class="section-subtitle" id="dashboard-quota-subtitle">Heures affectées, validées et brouillon comprises, sur l’année civile.</p>
</div>
<a class="button button-secondary" href="annual.php">Vue annuelle détaillée</a>
</div>
<div class="dashboard-quota-summary">
<article class="summary-card">
<span>Agents suivis</span>
<strong id="dashboard-quota-agents">—</strong>
<small>actifs</small>
</article>
<article class="summary-card">
<span>Consommation globale</span>
<strong id="dashboard-quota-rate">—</strong>
<small id="dashboard-quota-rate-detail">du quota cumulé</small>
</article>
<article class="summary-card">
<span>Reste à affecter</span>
<strong id="dashboard-quota-remaining">—</strong>
<small>hors agents déjà au-delà</small>
</article>
<article class="summary-card">
<span>Sans aucune heure</span>
<strong id="dashboard-quota-empty">—</strong>
<small>agent(s) non planifié(s)</small>
</article>
</div>
<div id="dashboard-quota-empty-state" class="empty-state" hidden>Aucun agent actif à suivre.</div>
<div class="dashboard-quota-table-wrap">
<table class="dashboard-quota-table">
<thead>
<tr>
<th>Agent</th>
<th>Lieu de rattachement</th>
<th>Quota annuel</th>
<th>Affecté</th>
<th>Consommation</th>
<th></th>
</tr>
</thead>
<tbody id="dashboard-quota-body"></tbody>
</table>
</div>
</section>
<section class="card dashboard-shortcuts-card">
<div class="section-heading">
<div>
<h2>Actions fréquentes</h2>
<p class="section-subtitle">Les écrans les plus utilisés, accessibles en un clic.</p>
</div>
</div>
<div class="dashboard-shortcuts">
<a class="dashboard-shortcut" href="planning.php">
<strong>Saisir un planning</strong>
<small>Un agent, une semaine, un lieu.</small>
</a>
<a class="dashboard-shortcut" href="structures.php">
<strong>Consulter un lieu</strong>
<small>Qui travaille où cette semaine.</small>
</a>
<a class="dashboard-shortcut" href="teams.php">
<strong>Composer une équipe</strong>
<small>Mercredis et vacances scolaires.</small>
</a>
<a class="dashboard-shortcut" href="vacations.php">
<strong>Mettre à jour les vacances</strong>
<small>Périodes scolaires de référence.</small>
</a>
<a class="dashboard-shortcut" href="pta.php">
<strong>Ouvrir un PTA détaillé</strong>
<small>Souhaits, contraintes et répartition.</small>
</a>
<a class="dashboard-shortcut" href="administration.php">
<strong>Gérer les référentiels</strong>
<small>Agents, lieux, postes, couverture.</small>
</a>
</div>
</section>
</section>