Version initiale — carte des établissements scolaires

Carte Leaflet (annuaire Éducation nationale) + API PHP/MySQL :
fiche établissement (effectifs, IPS, population INSEE, DPE ADEME),
GED documents/photos, commentaires par groupe, gestion utilisateurs
et politique de mots de passe. Imports opendata (effectifs, IPS,
population, DPE, IRIS).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-03 21:35:41 +02:00
commit 5633969d98
40 changed files with 7242 additions and 0 deletions
+116
View File
@@ -0,0 +1,116 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Administration — Établissements scolaires</title>
<link rel="stylesheet" href="style.css"/>
</head>
<body class="admin-page">
<header class="admin-bar">
<h1>🔐 Administration</h1>
<div class="admin-user">
<span id="who"></span>
<a id="account-link" href="account.html" class="btn-secondary btn-sm" hidden>🔑 Mon mot de passe</a>
<a href="index.html" class="btn-secondary btn-sm">← Carte</a>
<button id="logout" type="button" class="btn-secondary btn-sm" hidden>Déconnexion</button>
</div>
</header>
<!-- Connexion -->
<section id="login" class="admin-section login-card" hidden>
<h2>Connexion administrateur</h2>
<form id="login-form" autocomplete="off">
<div class="field">
<label for="l-user">Identifiant</label>
<input id="l-user" type="text" required>
</div>
<div class="field">
<label for="l-pass">Mot de passe</label>
<input id="l-pass" type="password" required>
</div>
<button type="submit" class="btn-primary">Se connecter</button>
<p id="login-msg" class="propose-msg err"></p>
<p class="auth-foot"><a href="forgot.html">Mot de passe oublié ?</a></p>
</form>
</section>
<!-- Espace connecté -->
<main id="admin" class="admin-main" hidden>
<!-- File de validation -->
<section class="admin-section">
<h2>File d'attente de validation <span id="queue-count" class="tree-count"></span></h2>
<p class="hint">Éléments proposés par les internautes, en attente dans votre périmètre.</p>
<div id="queue" class="queue"></div>
</section>
<!-- Réservé au super-admin -->
<div id="super-only" hidden>
<section class="admin-section">
<h2>Arborescence des dossiers</h2>
<p class="hint">Arbre global appliqué à tous les établissements.</p>
<form id="folder-form" class="inline-form">
<input id="nf-name" type="text" placeholder="Nom du dossier" required>
<select id="nf-parent"></select>
<button type="submit" class="btn-primary btn-sm">Ajouter</button>
</form>
<div id="folders-admin" class="folders-admin"></div>
</section>
<section class="admin-section">
<h2>Utilisateurs</h2>
<p class="hint"><strong>Admin de périmètre</strong> : valide les documents de ses communes / groupes valideurs. <strong>Commentateur</strong> : participe seulement aux commentaires de fiche (via ses groupes), sans accès à la modération.</p>
<form id="user-form" class="inline-form">
<input id="nu-user" type="text" placeholder="Identifiant" required>
<input id="nu-mail" type="email" placeholder="E-mail (pour la récupération)">
<input id="nu-pass" type="text" placeholder="Mot de passe" required>
<select id="nu-role" title="Rôle de l'utilisateur">
<option value="perimeter">Admin de périmètre</option>
<option value="member">Commentateur</option>
</select>
<button type="submit" class="btn-primary btn-sm">Créer l'utilisateur</button>
</form>
<div id="nu-pw-meter" class="pw-meter"></div>
<p class="hint">Le mot de passe doit faire ≥ 8 caractères et combiner ≥ 3 types (minuscule, majuscule, chiffre, spécial). L'utilisateur devra le changer à sa 1<sup>re</sup> connexion.</p>
<div id="users-admin" class="users-admin"></div>
</section>
<section class="admin-section">
<h2>Groupes d'utilisateurs</h2>
<p class="hint">Un groupe rassemble des utilisateurs. Un groupe <strong>valideur</strong> permet à ses membres de valider les documents des établissements de ses communes. Les commentaires de fiche sont visibles entre membres d'un même groupe.</p>
<form id="group-form" class="inline-form">
<input id="ng-name" type="text" placeholder="Nom du groupe" required>
<label class="inline-check"><input id="ng-validate" type="checkbox"> peut valider les documents</label>
<button type="submit" class="btn-primary btn-sm">Créer un groupe</button>
</form>
<div id="groups-admin" class="users-admin"></div>
</section>
<section class="admin-section">
<h2>Import de l'opendata</h2>
<p class="hint">Télécharge la dernière version de l'annuaire de l'Éducation nationale et met à jour la base (accès Internet requis côté serveur).</p>
<button id="import-btn" type="button" class="btn-primary">⤓ Importer la dernière version</button>
<p id="import-msg" class="propose-msg"></p>
</section>
<section class="admin-section">
<h2>Performance énergétique (DPE — ADEME)</h2>
<p class="hint">Télécharge les DPE des bâtiments tertiaires de l'ADEME et les rattache aux établissements par proximité géographique. <strong>Opération longue</strong> (le dataset complet ≈ 532 000 DPE) ; laissez un département vide pour tout importer, ou indiquez un code pour un import ciblé. Accès Internet requis côté serveur.</p>
<form id="dpe-form" class="inline-form">
<input id="dpe-dep" type="text" placeholder="Département (ex. 75) — vide = tout" maxlength="3">
<input id="dpe-radius" type="number" min="1" max="2000" value="5" title="Rayon de rattachement (m) — 5 m = même bâtiment / adresse">
<button id="dpe-btn" type="submit" class="btn-primary btn-sm">⤓ Importer &amp; rattacher</button>
</form>
<p id="dpe-msg" class="propose-msg"></p>
</section>
</div>
</main>
<script src="pwpolicy.js"></script>
<script src="admin.js"></script>
</body>
</html>