Files
Presencia/frontend/public/index.html
T
Claude 626b46d9d6 Implémenter le design Presencia (projet Claude Design)
Reprend la maquette Presencia.dc.html sur l'application réelle : thème
clair chaud à accent vert forêt, navigation latérale groupée par rôle et
tableau de bord, en conservant l'intégralité du fonctionnel existant.

Frontend
- Écran de connexion en deux panneaux (argumentaire + formulaire).
- Tableau de bord par rôle : compteurs du mois et liste « à faire
  maintenant » (sociétés prêtes à valider, cadres en retard, saisie à
  compléter), plus l'état du mois par société côté admin.
- Planning : saisie rapide au pinceau, trois affichages (grille, compact,
  liste), sélecteur avec raccourcis clavier (1–4, ⌫, ↵ pour appliquer à
  la journée), barre d'état de verrouillage, « Tout effacer ».
- Nouvelle vue Historique pour les cadres (totaux par mois et statut).
- Validation & export : barre de progression et compteurs de
  demi-journées par cadre.
- Mobile : liste verticale, navigation en barre basse, cibles 44 px.

Backend
- GET /api/validations/overview — état de toutes les sociétés d'un mois.
- GET /api/attendance/history — totaux par mois et par statut.
- DELETE /api/attendance/month — effacement d'un mois (mêmes verrous).
- Compteur de demi-journées saisies par cadre dans /validations/company.

Polices et icônes servies localement (Inter, sous-ensemble de 18 icônes
Phosphor) au lieu de Google Fonts et unpkg : l'application ne fait plus
aucune requête externe au chargement.

Vérifié de bout en bout via la vraie configuration nginx : 62 contrôles
Playwright (desktop et mobile), tous passants, sur base réinitialisée et
rejoués deux fois pour garantir le déterminisme.
2026-08-03 18:00:34 +00:00

294 lines
12 KiB
HTML
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.
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Presencia — Gestion des présences</title>
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Crect width='100' height='100' rx='22' fill='%233f6b54'/%3E%3C/svg%3E" />
<link rel="stylesheet" href="css/inter.css" />
<link rel="stylesheet" href="css/styles.css" />
<link rel="stylesheet" href="css/presencia.css" />
<link rel="stylesheet" href="css/phosphor.css" />
<link rel="stylesheet" href="css/app.css" />
</head>
<body>
<!-- ══════════════ LOGIN ══════════════ -->
<section id="view-login" class="login-split">
<div class="login-pitch">
<div class="brand-row">
<span class="brand-mark"></span>
<span class="brand-name">Presencia</span>
</div>
<div class="login-pitch-copy">
<h1>Les présences,<br />sans le tableur.</h1>
<p class="text-muted">Saisie par demi-journée, validation en deux temps, export mensuel par société. Chaque cadre remplit son mois en moins de deux minutes.</p>
</div>
<div class="login-pitch-feet">
<span>Validation cadre puis administrateur</span>
<span>Export PDF &amp; Excel</span>
</div>
</div>
<div class="login-formside">
<form id="login-form" class="login-form" autocomplete="on">
<div>
<h3>Connexion</h3>
<p class="login-lede">Accès réservé — les comptes sont créés par un administrateur.</p>
</div>
<div class="field">
<label for="login-email">Adresse e-mail</label>
<input class="input" id="login-email" type="email" required autocomplete="username" placeholder="vous@societe.com" />
</div>
<div class="field">
<label for="login-password">Mot de passe</label>
<input class="input" id="login-password" type="password" required autocomplete="current-password" placeholder="••••••••" />
</div>
<div id="login-error" class="login-error" hidden></div>
<button type="submit" class="btn btn-primary btn-block">Se connecter</button>
</form>
</div>
</section>
<!-- ══════════════ APP ══════════════ -->
<div id="app" class="shell" hidden>
<aside class="side">
<div class="side-brand">
<span class="brand-mark small"></span>
<span class="brand-name small">Presencia</span>
</div>
<nav id="side-nav"></nav>
<div class="side-foot">
<div class="side-user">
<span id="user-initials" class="avatar"></span>
<span class="side-user-text">
<span id="user-name" class="side-user-name"></span>
<span id="user-meta" class="side-user-meta"></span>
</span>
</div>
<button id="logout-btn" class="navitem"><i class="ni-ico ph ph-sign-out"></i><span>Déconnexion</span></button>
</div>
</aside>
<main class="content">
<div class="mobile-only mobile-head">
<span class="brand-mark tiny"></span>
<span id="screen-title" class="mobile-title"></span>
<button id="logout-btn-mobile" class="chipbtn">Quitter</button>
</div>
<!-- ─── DASHBOARD ─── -->
<section id="view-dashboard" class="view stack-20">
<div>
<h3 id="dash-greeting"></h3>
<p id="dash-subtitle" class="lede"></p>
</div>
<div id="dash-tiles" class="tile-grid"></div>
<div class="stack-8">
<h6>À faire maintenant</h6>
<div id="dash-actions" class="stack-6"></div>
</div>
<div id="dash-company-block" class="stack-8" hidden>
<h6>État du mois par société</h6>
<div class="card table-card">
<table class="table">
<thead><tr><th>Société</th><th>Cadres validés</th><th>Statut</th><th></th></tr></thead>
<tbody id="dash-company-rows"></tbody>
</table>
</div>
</div>
</section>
<!-- ─── PLANNING ─── -->
<section id="view-planning" class="view stack-14" hidden>
<div class="planning-head">
<div class="planning-head-title">
<button id="back-to-plannings" class="btn btn-ghost back-link" hidden>← Tous les plannings</button>
<h3 id="planning-title"></h3>
<p id="planning-subtitle" class="lede"></p>
</div>
<div class="month-nav">
<button id="prev-month" class="btn btn-secondary btn-icon" aria-label="Mois précédent"><i class="ph ph-caret-left"></i></button>
<span id="month-label" class="month-label"></span>
<button id="next-month" class="btn btn-secondary btn-icon" aria-label="Mois suivant"><i class="ph ph-caret-right"></i></button>
</div>
</div>
<div class="lockbar">
<i id="lock-icon" class="ph ph-pencil-simple-line lockbar-icon"></i>
<span class="lockbar-text">
<span id="lock-title" class="lockbar-title"></span>
<span id="lock-detail" class="lockbar-detail"></span>
</span>
<span class="lockbar-actions">
<button id="reopen-month-btn" class="btn btn-secondary" hidden>Réouvrir le mois</button>
<button id="validate-month-btn" class="btn btn-primary" hidden>Valider mon mois</button>
</span>
</div>
<div class="toolrow">
<span class="toolrow-label">Saisie rapide</span>
<div id="brush-options" class="toolrow-items"></div>
</div>
<div class="toolrow">
<div id="view-options" class="toolrow-items"></div>
<span class="toolrow-right">
<button id="fill-workdays-btn" class="btn btn-secondary">Remplir les jours ouvrés</button>
<button id="clear-month-btn" class="btn btn-secondary">Tout effacer</button>
</span>
</div>
<div id="brush-hint" class="brush-hint"></div>
<div id="planning-view" class="pv-grid">
<div class="cal-head">
<span>Lun</span><span>Mar</span><span>Mer</span><span>Jeu</span><span>Ven</span><span>Sam</span><span>Dim</span>
</div>
<div id="cal-grid" class="cal-grid"></div>
</div>
<div id="planning-summary" class="summary-row"></div>
</section>
<!-- ─── PLANNINGS (admin) ─── -->
<section id="view-plannings" class="view stack-14" hidden>
<div>
<h3>Plannings des cadres</h3>
<p id="plannings-subtitle" class="lede"></p>
</div>
<div class="filter-bar">
<span class="field">
<label for="pl-co">Société</label>
<select class="input" id="pl-co"><option value="all">Toutes les sociétés</option></select>
</span>
<span class="field">
<label for="pl-q">Rechercher un cadre</label>
<input class="input" id="pl-q" placeholder="Nom ou e-mail" />
</span>
</div>
<div id="cadre-rows" class="stack-6"></div>
</section>
<!-- ─── VALIDATION & EXPORT (admin) ─── -->
<section id="view-validation" class="view stack-14" hidden>
<div>
<h3>Validation &amp; export</h3>
<p class="lede">Une société se valide quand tous ses cadres ont validé leur mois.</p>
</div>
<div class="filter-bar">
<span class="field">
<label for="va-co">Société</label>
<select class="input" id="va-co"></select>
</span>
<span class="field">
<label for="va-mo">Mois</label>
<select class="input" id="va-mo"></select>
</span>
</div>
<div class="card validation-card">
<div class="validation-head">
<span class="validation-head-text">
<span id="validation-company-name" class="validation-company"></span>
<span id="validation-status-text" class="validation-status"></span>
</span>
<span class="validation-head-actions">
<button id="export-pdf-btn" class="btn btn-secondary"><i class="ph ph-file-pdf"></i>PDF</button>
<button id="export-excel-btn" class="btn btn-secondary"><i class="ph ph-file-xls"></i>Excel</button>
<button id="validate-company-btn" class="btn btn-primary">Valider la société</button>
</span>
</div>
<div class="progress"><span id="validation-progress" class="progress-bar"></span></div>
<table class="table">
<thead><tr><th>Cadre</th><th>Demi-journées</th><th>Statut</th><th></th></tr></thead>
<tbody id="validation-rows"></tbody>
</table>
</div>
</section>
<!-- ─── COMPANIES (admin) ─── -->
<section id="view-companies" class="view stack-14" hidden>
<div class="page-head">
<div>
<h3>Sociétés</h3>
<p id="companies-count" class="lede"></p>
</div>
<button id="add-company-btn" class="btn btn-primary"><i class="ph ph-plus"></i>Nouvelle société</button>
</div>
<div class="card table-card">
<table class="table">
<thead><tr><th>Nom</th><th>Cadres actifs</th><th>Créée le</th><th></th></tr></thead>
<tbody id="companies-rows"></tbody>
</table>
</div>
</section>
<!-- ─── USERS (admin) ─── -->
<section id="view-users" class="view stack-14" hidden>
<div class="page-head">
<div>
<h3>Utilisateurs</h3>
<p class="lede">Aucune inscription publique — les comptes sont créés ici.</p>
</div>
<button id="add-user-btn" class="btn btn-primary"><i class="ph ph-plus"></i>Nouvel utilisateur</button>
</div>
<div class="filter-bar">
<span class="field">
<label for="us-co">Société</label>
<select class="input" id="us-co"><option value="all">Toutes les sociétés</option></select>
</span>
<span class="field">
<label for="us-q">Rechercher</label>
<input class="input" id="us-q" placeholder="Nom ou e-mail" />
</span>
</div>
<div class="card table-card">
<table class="table">
<thead><tr><th>Nom</th><th>E-mail</th><th>Rôle</th><th>Société</th><th>Statut</th><th></th></tr></thead>
<tbody id="users-rows"></tbody>
</table>
</div>
</section>
<!-- ─── HISTORY ─── -->
<section id="view-history" class="view stack-14" hidden>
<div>
<h3>Historique</h3>
<p class="lede">Vos mois saisis et leurs totaux.</p>
</div>
<div class="card table-card">
<table class="table">
<thead><tr><th>Mois</th><th>Présent</th><th>Non-présent</th><th>Congé</th><th>RTT</th><th>Statut</th><th></th></tr></thead>
<tbody id="history-rows"></tbody>
</table>
</div>
</section>
</main>
<nav id="mobile-nav" class="mobile-only mobile-nav"></nav>
</div>
<!-- ══════════════ POPOVER ══════════════ -->
<div id="pop-backdrop" class="pop-backdrop" hidden></div>
<div id="pop" class="pop" hidden>
<div class="pop-head">
<span id="pop-title" class="pop-title"></span>
<span class="pop-hint">1–4 au clavier</span>
</div>
<div id="pop-options"></div>
<button id="pop-clear" class="pop-opt pop-opt-muted"><i class="dot st-none"></i>Effacer<span class="kbd">⌫</span></button>
<button id="pop-whole-day" class="pop-opt"><i class="ph ph-arrows-out-line-horizontal pop-ico"></i>Appliquer à la journée<span class="kbd">↵</span></button>
</div>
<!-- ══════════════ DIALOG ══════════════ -->
<div id="dialog-backdrop" class="dialog-backdrop" hidden>
<div id="dialog" class="dialog"></div>
</div>
<!-- ══════════════ TOAST ══════════════ -->
<div id="toast" class="toast" hidden></div>
<script src="js/app.js"></script>
</body>
</html>