mirror of
https://github.com/siop-spelev/siop2.git
synced 2026-08-08 12:41:54 +00:00
feat(r4): maquettes HD mobile technicien — 7 écrans offline-first à valider
Design d'abord : aucune ligne de code Expo avant validation. Ma journée (en ligne / hors-ligne côte à côte), fiche OT, clôture terrain (bilan codé R2, garde visible, variante « en file »), scan QR des étiquettes A6 (R1, hors-ligne inclus), fiche ascenseur, checklist du mois (coches individuelles en file), synchro & conflits (verrou optimiste, l'humain tranche). Tokens répliqués, bi-thème, données du parc seedé. 5 décisions soumises avec les écrans : offline-first en file, verrou optimiste, périmètre fermé technicien, scan résolu en local, photos compressées en file — ni audio ni géolocalisation en R4 (loi 09-08). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -54,5 +54,6 @@ pnpm + Turborepo. `apps/api` : NestJS, Prisma, PostgreSQL (pgvector + PostGIS),
|
||||
- ✅ **R3.3** : 7 écrans web fidèles à maquette-r3 (stock/alertes, fiche pièce, BC + réception, création BC préremplie depuis l'alerte, tiers, bibliothèque, statistiques) + fiche OT complète (coûts réels : consommer à prix figé / saisir temps à taux figé ; carte Documents) + fiche ascenseur (Documents) + taux horaire dans Personnes + nav Ressources/Statistiques activée par la matrice. Recette R3 automatisée (13/13 e2e Playwright).
|
||||
- ✅ **R3.4 — corrections de recette + recherche globale** (17/07) : revue pixel (artefact) → 8 écarts corrigés sur arbitrage du référent (filtre fournisseur + tri sous-seuil + entrée de stock en liste, fournisseur cliquable, sélecteur de période 3/6/12 sur les stats, rattachements syndic→site via `Location.partnerId` (migration `r3_recette_fixes`), filtre « Rattaché à » + glisser-déposer en bibliothèque, aperçus/ouverture des documents) ; **recherche globale ⌘K** (`GET /search`, 73 opérations, familles filtrées par la matrice, « voir autre » respecté). 74 tests API, 14/14 Playwright.
|
||||
- 🏁 **R3 CLOSE (17/07/2026, tag `release/r3`)** : recettée par le référent (revue pixel + 8 corrections + recherche globale, CI verte). Reste : redéploiement Dokploy (manuel, webhook CD absent) et vérification en ligne.
|
||||
- 🔄 **Reprise ici** : redéployer sur Dokploy et vérifier en ligne (migration `r3_recette_fixes` + seed au boot) → ouverture R4 Mobile (Expo, design d'abord — maquettes avant tout code).
|
||||
- ✅ **R4 — maquettes rédigées** (17/07) : `maquette-r4.html`, 7 écrans mobile technicien offline-first (Ma journée bi-état, fiche OT, clôture terrain avec garde, scan QR des étiquettes R1, fiche ascenseur, checklist en file, synchro & conflits à verrou optimiste) + 5 décisions à acter (offline-first en file, verrou optimiste tranché par l'humain, périmètre fermé technicien, scan local, photos en file — ni audio ni géoloc en R4).
|
||||
- 🔄 **Reprise ici** : validation des maquettes + 5 décisions par le référent → R4.1 socle mobile (Expo). En parallèle : redéployer `release/r3` sur Dokploy et vérifier en ligne.
|
||||
- Détail quotidien : `docs/journal/journal.md`. Dépôt : `siop-spelev/siop2` (privé), jalons R0→R5.
|
||||
|
||||
641
docs/02-design/maquettes/maquette-r4.html
Normal file
641
docs/02-design/maquettes/maquette-r4.html
Normal file
@@ -0,0 +1,641 @@
|
||||
<!doctype html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>SIOP V2 — Maquettes HD · R4 Mobile technicien</title>
|
||||
</head>
|
||||
<body>
|
||||
<!--
|
||||
SIOP V2 — Maquettes HD de la release R4 « Mobile technicien » (design-first).
|
||||
À VALIDER PAR LE RÉFÉRENT AVANT TOUT CODE EXPO (principe n°1).
|
||||
Cible : l'app du TECHNICIEN (Ahmed) — offline-first, Expo Go.
|
||||
La gestion reste web ; le demandeur reste sur le portail QR public (R2).
|
||||
Tokens répliqués de ../tokens.css ; gabarit téléphone repris de maquette-r3
|
||||
(écran portail) et étendu : tabbar, file de synchro, conflits.
|
||||
Recette type (plan de releases) : mode avion en sous-sol → cocher la grille
|
||||
→ retour réseau → synchro sans perdre une saisie (verrou optimiste).
|
||||
-->
|
||||
<style>
|
||||
/* ═══ Tokens (répliques de ../tokens.css) ═══ */
|
||||
:root{
|
||||
--primaire:#1f4fb8;--primaire-actif:#1a439c;--primaire-doux:#eaf0fb;
|
||||
--safran:#dd8a0b;--safran-doux:#fdf3e3;
|
||||
--fond:#f5f7fa;--surface:#ffffff;--surface-2:#eef2f7;
|
||||
--bordure:#dce3ec;--bordure-forte:#b9c4d4;
|
||||
--encre:#1b2534;--encre-2:#55647a;--encre-3:#8494ab;
|
||||
--st-ouvert:#3d6fe0;--st-ouvert-fond:#e9effc;--st-encours:#6d5bd8;--st-encours-fond:#efecfa;
|
||||
--st-attente:#b96f07;--st-attente-fond:#fbf1df;--st-termine:#178a50;--st-termine-fond:#e6f5ec;
|
||||
--st-annule:#68788f;--st-annule-fond:#edf0f4;
|
||||
--prio-bloque:#d92626;--prio-bloque-fond:#fdeaea;--prio-haute:#d92626;
|
||||
--prio-moyenne:#b96f07;--prio-basse:#178a50;--prio-aucune:#8494ab;
|
||||
--succes:#178a50;--alerte:#b96f07;--danger:#d92626;--info:#3d6fe0;
|
||||
--graf-1:#3b69d6;--graf-2:#dd8a0b;--graf-3:#1f9e8e;--graf-4:#8a63d2;--graf-grille:#e6ebf2;
|
||||
--nav-fond:#16233b;--nav-encre:#c6d2e4;--nav-encre-vif:#ffffff;--nav-bordure:#24344f;
|
||||
--police-ui:"Manrope","Avenir Next","Segoe UI Variable",system-ui,sans-serif;
|
||||
--rayon:10px;--rayon-controle:8px;--ombre-menu:0 8px 24px rgb(16 30 54/.14);
|
||||
--transition:140ms ease-out;
|
||||
}
|
||||
@media (prefers-color-scheme:dark){:root{
|
||||
--primaire:#6e92e8;--primaire-actif:#8facf0;--primaire-doux:#1d2c4c;
|
||||
--safran:#e89a1f;--safran-doux:#33270f;
|
||||
--fond:#0f1622;--surface:#182234;--surface-2:#1e2a40;
|
||||
--bordure:#2b3850;--bordure-forte:#3d4d6b;
|
||||
--encre:#e8edf5;--encre-2:#a7b4c8;--encre-3:#6d7d96;
|
||||
--st-ouvert:#7da2ee;--st-ouvert-fond:#1c2a47;--st-encours:#a394ec;--st-encours-fond:#262040;
|
||||
--st-attente:#e0a33c;--st-attente-fond:#322510;--st-termine:#4bc084;--st-termine-fond:#12301f;
|
||||
--st-annule:#93a3ba;--st-annule-fond:#222d3f;
|
||||
--prio-bloque:#f26d6d;--prio-bloque-fond:#3a1414;--prio-haute:#f26d6d;
|
||||
--prio-moyenne:#e0a33c;--prio-basse:#4bc084;--prio-aucune:#6d7d96;
|
||||
--succes:#4bc084;--alerte:#e0a33c;--danger:#f26d6d;--info:#7da2ee;
|
||||
--graf-1:#5580e4;--graf-2:#c7820a;--graf-3:#26a896;--graf-4:#9673de;--graf-grille:#24304a;
|
||||
--nav-fond:#0c1524;--nav-encre:#a7b4c8;--nav-encre-vif:#f2f6fc;--nav-bordure:#1e2c44;
|
||||
--ombre-menu:0 8px 24px rgb(0 0 0/.45);
|
||||
}}
|
||||
:root[data-theme="light"]{
|
||||
--primaire:#1f4fb8;--primaire-actif:#1a439c;--primaire-doux:#eaf0fb;
|
||||
--safran:#dd8a0b;--safran-doux:#fdf3e3;
|
||||
--fond:#f5f7fa;--surface:#ffffff;--surface-2:#eef2f7;
|
||||
--bordure:#dce3ec;--bordure-forte:#b9c4d4;
|
||||
--encre:#1b2534;--encre-2:#55647a;--encre-3:#8494ab;
|
||||
--st-ouvert:#3d6fe0;--st-ouvert-fond:#e9effc;--st-encours:#6d5bd8;--st-encours-fond:#efecfa;
|
||||
--st-attente:#b96f07;--st-attente-fond:#fbf1df;--st-termine:#178a50;--st-termine-fond:#e6f5ec;
|
||||
--st-annule:#68788f;--st-annule-fond:#edf0f4;
|
||||
--prio-bloque:#d92626;--prio-bloque-fond:#fdeaea;--prio-haute:#d92626;
|
||||
--prio-moyenne:#b96f07;--prio-basse:#178a50;--prio-aucune:#8494ab;
|
||||
--succes:#178a50;--alerte:#b96f07;--danger:#d92626;--info:#3d6fe0;
|
||||
--graf-1:#3b69d6;--graf-2:#dd8a0b;--graf-3:#1f9e8e;--graf-4:#8a63d2;--graf-grille:#e6ebf2;
|
||||
--nav-fond:#16233b;--nav-encre:#c6d2e4;--nav-encre-vif:#ffffff;--nav-bordure:#24344f;
|
||||
--ombre-menu:0 8px 24px rgb(16 30 54/.14);
|
||||
}
|
||||
:root[data-theme="dark"]{
|
||||
--primaire:#6e92e8;--primaire-actif:#8facf0;--primaire-doux:#1d2c4c;
|
||||
--safran:#e89a1f;--safran-doux:#33270f;
|
||||
--fond:#0f1622;--surface:#182234;--surface-2:#1e2a40;
|
||||
--bordure:#2b3850;--bordure-forte:#3d4d6b;
|
||||
--encre:#e8edf5;--encre-2:#a7b4c8;--encre-3:#6d7d96;
|
||||
--st-ouvert:#7da2ee;--st-ouvert-fond:#1c2a47;--st-encours:#a394ec;--st-encours-fond:#262040;
|
||||
--st-attente:#e0a33c;--st-attente-fond:#322510;--st-termine:#4bc084;--st-termine-fond:#12301f;
|
||||
--st-annule:#93a3ba;--st-annule-fond:#222d3f;
|
||||
--prio-bloque:#f26d6d;--prio-bloque-fond:#3a1414;--prio-haute:#f26d6d;
|
||||
--prio-moyenne:#e0a33c;--prio-basse:#4bc084;--prio-aucune:#6d7d96;
|
||||
--succes:#4bc084;--alerte:#e0a33c;--danger:#f26d6d;--info:#7da2ee;
|
||||
--graf-1:#5580e4;--graf-2:#c7820a;--graf-3:#26a896;--graf-4:#9673de;--graf-grille:#24304a;
|
||||
--nav-fond:#0c1524;--nav-encre:#a7b4c8;--nav-encre-vif:#f2f6fc;--nav-bordure:#1e2c44;
|
||||
--ombre-menu:0 8px 24px rgb(0 0 0/.45);
|
||||
}
|
||||
|
||||
/* ═══ Base ═══ */
|
||||
*{box-sizing:border-box;margin:0}
|
||||
html,body{background:var(--fond)}
|
||||
body{font-family:var(--police-ui);color:var(--encre);font-size:14px;line-height:1.5}
|
||||
button{font:inherit;cursor:pointer;border:0;background:none;color:inherit}
|
||||
button:focus-visible,a:focus-visible{outline:2px solid var(--primaire);outline-offset:2px;border-radius:4px}
|
||||
.num{font-variant-numeric:tabular-nums}
|
||||
|
||||
/* ═══ Barre de revue (outil maquette, pas l'app) ═══ */
|
||||
.revue{position:sticky;top:0;z-index:50;display:flex;align-items:center;gap:12px;flex-wrap:wrap;
|
||||
padding:10px 16px;background:var(--nav-fond);color:var(--nav-encre);font-size:13px}
|
||||
.revue b{color:var(--nav-encre-vif);letter-spacing:.02em}
|
||||
.revue .onglets{display:flex;gap:4px;flex-wrap:wrap}
|
||||
.revue .onglets button{padding:6px 10px;border-radius:6px;color:var(--nav-encre)}
|
||||
.revue .onglets button:hover{background:rgb(255 255 255/.08);color:var(--nav-encre-vif)}
|
||||
.revue .onglets button[aria-selected="true"]{background:rgb(255 255 255/.12);color:var(--nav-encre-vif);
|
||||
box-shadow:inset 3px 0 0 var(--safran)}
|
||||
.revue .droite{margin-left:auto;display:flex;align-items:center;gap:8px}
|
||||
.revue .theme{padding:6px 10px;border:1px solid var(--nav-bordure);border-radius:6px}
|
||||
.note-ecran{max-width:1120px;margin:14px auto 0;padding:0 20px;color:var(--encre-2);font-size:13px}
|
||||
.note-ecran b{color:var(--encre)}
|
||||
|
||||
/* ═══ Écrans (mobile only — pas de coquille web en R4) ═══ */
|
||||
.ecran{display:none;max-width:1120px;margin:18px auto 44px;padding:0 20px}
|
||||
.ecran.actif{display:block}
|
||||
.tels{display:flex;gap:28px;justify-content:center;flex-wrap:wrap}
|
||||
.tel{width:310px;border:1px solid var(--bordure-forte);border-radius:28px;overflow:hidden;background:var(--fond);
|
||||
box-shadow:var(--ombre-menu);display:flex;flex-direction:column}
|
||||
.tel .encoche{height:26px;background:var(--nav-fond);display:flex;justify-content:center;align-items:center;flex:none}
|
||||
.tel .encoche i{width:70px;height:7px;border-radius:999px;background:rgb(255 255 255/.18)}
|
||||
.tel .legende{flex:none;text-align:center;font-size:11.5px;font-weight:700;letter-spacing:.05em;
|
||||
text-transform:uppercase;color:var(--encre-3);padding:8px;background:var(--surface-2)}
|
||||
.ecran-tel{padding:14px;display:flex;flex-direction:column;gap:10px;min-height:560px}
|
||||
|
||||
/* Entête app */
|
||||
.entete-tel{display:flex;align-items:center;gap:8px}
|
||||
.entete-tel .flamme{color:var(--safran);font-size:16px}
|
||||
.entete-tel b{font-size:16px;letter-spacing:.03em}
|
||||
.entete-tel small{color:var(--encre-3);font-size:10.5px;margin-top:3px}
|
||||
.entete-tel .fin{margin-left:auto;display:flex;align-items:center;gap:6px}
|
||||
.avatar-tel{width:26px;height:26px;border-radius:50%;background:var(--st-encours);color:#fff;
|
||||
display:flex;align-items:center;justify-content:center;font-size:10.5px;font-weight:700}
|
||||
.sync{font-size:10.5px;font-weight:700;color:var(--st-termine);background:var(--st-termine-fond);
|
||||
padding:2px 8px;border-radius:999px;white-space:nowrap}
|
||||
.sync.off{color:var(--st-attente);background:var(--st-attente-fond)}
|
||||
.titre-tel{font-size:17px;font-weight:800;display:flex;align-items:center;gap:8px}
|
||||
.titre-tel .filet{margin-left:auto;font-size:11px;color:var(--encre-3);font-weight:600}
|
||||
|
||||
/* Bandeaux */
|
||||
.bandeau-off{display:flex;align-items:center;gap:8px;background:var(--st-attente-fond);color:var(--st-attente);
|
||||
border:1px solid currentColor;border-radius:10px;padding:8px 10px;font-size:12px;font-weight:700}
|
||||
.bandeau-urgence{display:flex;align-items:center;gap:8px;background:var(--prio-bloque-fond);color:var(--prio-bloque);
|
||||
border-radius:10px;padding:8px 10px;font-size:12px;font-weight:800}
|
||||
.point-pulse{width:8px;height:8px;border-radius:50%;background:currentColor;flex:none}
|
||||
|
||||
/* Cartes OT */
|
||||
.carte-ot-tel{background:var(--surface);border:1px solid var(--bordure);border-radius:12px;padding:11px 12px;
|
||||
border-left:4px solid transparent}
|
||||
.carte-ot-tel.bloque{border-left-color:var(--prio-bloque)}
|
||||
.carte-ot-tel.haute{border-left-color:var(--prio-haute)}
|
||||
.carte-ot-tel.moyenne{border-left-color:var(--prio-moyenne)}
|
||||
.carte-ot-tel.basse{border-left-color:var(--prio-basse)}
|
||||
.carte-ot-tel .type-t{font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--encre-2);
|
||||
font-weight:700;display:flex;justify-content:space-between;align-items:center;gap:6px}
|
||||
.carte-ot-tel b{display:block;margin:3px 0 2px;font-size:14px}
|
||||
.carte-ot-tel .ou{color:var(--encre-2);font-size:12px}
|
||||
.st{font-size:10.5px;font-weight:700;padding:2px 8px;border-radius:999px;white-space:nowrap}
|
||||
.st.ouvert{color:var(--st-ouvert);background:var(--st-ouvert-fond)}
|
||||
.st.encours{color:var(--st-encours);background:var(--st-encours-fond)}
|
||||
.st.attente{color:var(--st-attente);background:var(--st-attente-fond)}
|
||||
.st.termine{color:var(--st-termine);background:var(--st-termine-fond)}
|
||||
.pastille-file{font-size:10.5px;font-weight:700;color:var(--st-attente);background:var(--st-attente-fond);
|
||||
padding:2px 8px;border-radius:999px}
|
||||
|
||||
/* Boutons */
|
||||
.btn-tel{display:flex;justify-content:center;align-items:center;gap:8px;padding:12px;border-radius:10px;
|
||||
font-weight:700;font-size:14.5px;background:var(--primaire);color:#fff;width:100%}
|
||||
.btn-tel.vert{background:var(--succes)}
|
||||
.btn-tel.gris{background:var(--bordure-forte);color:var(--surface)}
|
||||
.btn-tel.contour{background:var(--surface);color:var(--primaire);border:1.5px solid var(--primaire)}
|
||||
.paire-boutons{display:flex;gap:8px}
|
||||
.paire-boutons .btn-tel{padding:10px;font-size:13px}
|
||||
|
||||
/* Fiche : cartes d'info */
|
||||
.carte-tel{background:var(--surface);border:1px solid var(--bordure);border-radius:12px;padding:12px;
|
||||
display:flex;flex-direction:column;gap:8px}
|
||||
.carte-tel h4{font-size:10.5px;letter-spacing:.07em;text-transform:uppercase;color:var(--encre-2)}
|
||||
.ligne-info{display:flex;justify-content:space-between;gap:10px;font-size:12.5px}
|
||||
.ligne-info span:first-child{color:var(--encre-2)}
|
||||
.ligne-info b{text-align:right}
|
||||
.garde{font-size:11.5px;color:var(--alerte);font-weight:600}
|
||||
|
||||
/* Bilan codé (selects) */
|
||||
.champ-tel{display:flex;flex-direction:column;gap:4px}
|
||||
.champ-tel label{font-size:11px;font-weight:700;color:var(--encre-2)}
|
||||
.champ-tel label em{color:var(--danger);font-style:normal}
|
||||
.select-tel{border:1.5px solid var(--bordure-forte);border-radius:9px;background:var(--surface);
|
||||
padding:9px 10px;font-size:13px;color:var(--encre);display:flex;justify-content:space-between;align-items:center}
|
||||
.select-tel.vide{color:var(--encre-3)}
|
||||
.grille-2-tel{display:grid;grid-template-columns:1fr 1fr;gap:8px}
|
||||
|
||||
/* Checklist */
|
||||
.progress{height:8px;border-radius:999px;background:var(--surface-2);overflow:hidden}
|
||||
.progress i{display:block;height:100%;border-radius:999px;background:var(--succes);width:58%}
|
||||
.check-item{display:flex;align-items:center;gap:10px;background:var(--surface);border:1px solid var(--bordure);
|
||||
border-radius:10px;padding:10px 12px;font-size:13px}
|
||||
.check-item .case{width:20px;height:20px;border-radius:6px;border:2px solid var(--bordure-forte);flex:none}
|
||||
.check-item.fait .case{background:var(--succes);border-color:var(--succes);position:relative}
|
||||
.check-item.fait .case::after{content:'✓';color:#fff;font-size:13px;font-weight:800;position:absolute;inset:0;
|
||||
display:flex;align-items:center;justify-content:center}
|
||||
.check-item.fait{color:var(--encre-2)}
|
||||
.check-item .file-chip{margin-left:auto}
|
||||
|
||||
/* Scan */
|
||||
.viseur{flex:1;min-height:340px;border-radius:12px;background:
|
||||
radial-gradient(circle at 50% 45%, #2c3a52 0%, #131c2c 70%);position:relative;display:flex;
|
||||
align-items:center;justify-content:center}
|
||||
.viseur .cadre-qr{width:170px;height:170px;border-radius:14px;border:2.5px solid var(--safran);
|
||||
box-shadow:0 0 0 2000px rgb(9 14 22/.45)}
|
||||
.viseur p{position:absolute;bottom:14px;color:#dfe7f2;font-size:12.5px}
|
||||
|
||||
/* Historique fiche ascenseur */
|
||||
.hist-item{display:flex;gap:8px;align-items:baseline;font-size:12.5px;padding:7px 0;border-top:1px solid var(--bordure)}
|
||||
.hist-item:first-of-type{border-top:0}
|
||||
.hist-item .ref{color:var(--primaire);font-weight:700;flex:none}
|
||||
.hist-item .quand{margin-left:auto;color:var(--encre-3);font-size:11px;white-space:nowrap}
|
||||
|
||||
/* File de synchro */
|
||||
.file-item{display:flex;align-items:center;gap:10px;background:var(--surface);border:1px solid var(--bordure);
|
||||
border-radius:10px;padding:10px 12px;font-size:12.5px}
|
||||
.file-item .ico{width:28px;height:28px;border-radius:8px;background:var(--surface-2);display:flex;
|
||||
align-items:center;justify-content:center;flex:none;font-size:14px}
|
||||
.file-item .quoi b{display:block;font-size:12.5px}
|
||||
.file-item .quoi span{color:var(--encre-2);font-size:11px}
|
||||
.file-item .etat{margin-left:auto;font-size:10.5px;font-weight:700;padding:2px 8px;border-radius:999px;white-space:nowrap}
|
||||
.etat.attente{color:var(--st-attente);background:var(--st-attente-fond)}
|
||||
.etat.envoi{color:var(--info);background:var(--st-ouvert-fond)}
|
||||
.etat.fait{color:var(--st-termine);background:var(--st-termine-fond)}
|
||||
.etat.conflit{color:var(--danger);background:var(--prio-bloque-fond)}
|
||||
.carte-conflit{background:var(--prio-bloque-fond);border:1.5px solid var(--danger);border-radius:12px;
|
||||
padding:12px;display:flex;flex-direction:column;gap:8px}
|
||||
.carte-conflit h4{color:var(--danger);font-size:12.5px;display:flex;gap:6px;align-items:center}
|
||||
.carte-conflit p{font-size:12px;color:var(--encre)}
|
||||
.carte-conflit small{font-size:11px;color:var(--encre-2)}
|
||||
|
||||
/* Tabbar */
|
||||
.tabbar{margin-top:auto;display:flex;border-top:1px solid var(--bordure);background:var(--surface);
|
||||
border-radius:0 0 0 0;padding:6px 4px 8px}
|
||||
.tabbar a{flex:1;display:flex;flex-direction:column;align-items:center;gap:2px;font-size:9.5px;
|
||||
font-weight:700;color:var(--encre-3);text-decoration:none;position:relative}
|
||||
.tabbar a.actif{color:var(--primaire)}
|
||||
.tabbar a .pic{font-size:17px;line-height:1.2}
|
||||
.tabbar .badge-tab{position:absolute;top:-3px;right:calc(50% - 16px);background:var(--st-attente);
|
||||
color:#fff;font-size:9px;font-weight:800;padding:0 5px;border-radius:999px}
|
||||
.tabbar .badge-tab.rouge{background:var(--prio-bloque)}
|
||||
|
||||
/* Photos jointes */
|
||||
.photos-tel{display:flex;gap:8px}
|
||||
.photo-tel{width:56px;height:56px;border-radius:9px;background:var(--surface-2);border:1px solid var(--bordure);
|
||||
display:flex;align-items:center;justify-content:center;font-size:19px;position:relative}
|
||||
.photo-tel .file-chip{position:absolute;bottom:-6px;right:-6px}
|
||||
.file-chip{font-size:9px;font-weight:800;color:var(--st-attente);background:var(--st-attente-fond);
|
||||
border:1px solid currentColor;padding:0 5px;border-radius:999px}
|
||||
</style>
|
||||
|
||||
<header class="revue">
|
||||
<b>SIOP · Maquettes R4 — Mobile technicien</b>
|
||||
<nav class="onglets" role="tablist" aria-label="Écrans">
|
||||
<button role="tab" aria-selected="true" data-cible="jour">1 · Ma journée</button>
|
||||
<button role="tab" aria-selected="false" data-cible="fiche-ot">2 · Fiche OT</button>
|
||||
<button role="tab" aria-selected="false" data-cible="cloture">3 · Clôture terrain</button>
|
||||
<button role="tab" aria-selected="false" data-cible="scan">4 · Scan QR</button>
|
||||
<button role="tab" aria-selected="false" data-cible="ascenseur">5 · Fiche ascenseur</button>
|
||||
<button role="tab" aria-selected="false" data-cible="checklist">6 · Checklist du mois</button>
|
||||
<button role="tab" aria-selected="false" data-cible="synchro">7 · Synchro & conflits</button>
|
||||
</nav>
|
||||
<div class="droite"><button class="theme" id="btn-theme">Thème : auto</button></div>
|
||||
</header>
|
||||
|
||||
<!-- ═══ 1 · MA JOURNÉE ═══ -->
|
||||
<p class="note-ecran" data-note="jour"><b>Intention :</b> l'app s'ouvre sur les OT d'Ahmed, triés
|
||||
<b>priorité puis échéance</b> — urgence « personne bloquée » toujours en tête. Le même écran vit
|
||||
<b>en ligne et hors-ligne</b> : hors-ligne, rien ne disparaît, un bandeau l'assume et la tabbar
|
||||
compte les saisies en file. La pastille de synchro est permanente (vert = à jour, ambre = en attente).</p>
|
||||
<section class="ecran actif" id="jour">
|
||||
<div class="tels">
|
||||
<div class="tel">
|
||||
<div class="encoche"><i></i></div>
|
||||
<div class="legende">En ligne — à jour</div>
|
||||
<div class="ecran-tel">
|
||||
<div class="entete-tel">
|
||||
<span class="flamme">♦</span><b>SIOP</b>
|
||||
<small>Technicien</small>
|
||||
<span class="fin"><span class="sync">Synchro à jour</span><span class="avatar-tel">AB</span></span>
|
||||
</div>
|
||||
<div class="titre-tel">Ma journée <span class="filet">jeudi 17 juil.</span></div>
|
||||
<div class="bandeau-urgence"><span class="point-pulse"></span>1 personne bloquée — B2 · Tour Atlas</div>
|
||||
<div class="carte-ot-tel bloque">
|
||||
<div class="type-t">OT-2026-0342 · Dépannage <span class="st ouvert">Ouvert</span></div>
|
||||
<b>Personne bloquée en cabine</b>
|
||||
<div class="ou">Asc. B2 — Tour Atlas · Aïn Diab</div>
|
||||
</div>
|
||||
<div class="carte-ot-tel haute">
|
||||
<div class="type-t">OT-2026-0341 · Dépannage <span class="st encours">En cours</span></div>
|
||||
<b>Bruit anormal en gaine</b>
|
||||
<div class="ou">Asc. A1 — Résidence Al Manar · échéance 18 juil.</div>
|
||||
</div>
|
||||
<div class="carte-ot-tel moyenne">
|
||||
<div class="type-t">OT-2026-0336 · Préventif <span class="st ouvert">Ouvert</span></div>
|
||||
<b>Contrôle mensuel — juillet</b>
|
||||
<div class="ou">Asc. A2 — Résidence Al Manar · grille 0/12</div>
|
||||
</div>
|
||||
<div class="carte-ot-tel basse">
|
||||
<div class="type-t">OT-2026-0329 · Travaux <span class="st attente">En attente</span></div>
|
||||
<b>Remplacement coulisseaux</b>
|
||||
<div class="ou">Asc. C1 — Anfa Place · pièce commandée (BC-2026-0024)</div>
|
||||
</div>
|
||||
<nav class="tabbar">
|
||||
<a class="actif" href="#"><span class="pic">☰</span>Ma journée</a>
|
||||
<a href="#"><span class="pic">▣</span>Scanner</a>
|
||||
<a href="#"><span class="pic">✓</span>Préventif</a>
|
||||
<a href="#"><span class="pic">⇅</span>Synchro</a>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tel">
|
||||
<div class="encoche"><i></i></div>
|
||||
<div class="legende">Hors-ligne — sous-sol</div>
|
||||
<div class="ecran-tel">
|
||||
<div class="entete-tel">
|
||||
<span class="flamme">♦</span><b>SIOP</b>
|
||||
<small>Technicien</small>
|
||||
<span class="fin"><span class="sync off">Hors-ligne</span><span class="avatar-tel">AB</span></span>
|
||||
</div>
|
||||
<div class="titre-tel">Ma journée <span class="filet">jeudi 17 juil.</span></div>
|
||||
<div class="bandeau-off">⚠ Hors-ligne — vos saisies partent en file et se synchroniseront au retour du réseau.</div>
|
||||
<div class="carte-ot-tel haute">
|
||||
<div class="type-t">OT-2026-0341 · Dépannage <span class="st encours">En cours</span></div>
|
||||
<b>Bruit anormal en gaine</b>
|
||||
<div class="ou">Asc. A1 — Résidence Al Manar · échéance 18 juil.</div>
|
||||
</div>
|
||||
<div class="carte-ot-tel moyenne">
|
||||
<div class="type-t">OT-2026-0336 · Préventif <span class="st ouvert">Ouvert</span> <span class="pastille-file">2 en file</span></div>
|
||||
<b>Contrôle mensuel — juillet</b>
|
||||
<div class="ou">Asc. A2 — Résidence Al Manar · grille 7/12</div>
|
||||
</div>
|
||||
<div class="carte-ot-tel basse">
|
||||
<div class="type-t">OT-2026-0329 · Travaux <span class="st attente">En attente</span></div>
|
||||
<b>Remplacement coulisseaux</b>
|
||||
<div class="ou">Asc. C1 — Anfa Place · pièce commandée (BC-2026-0024)</div>
|
||||
</div>
|
||||
<nav class="tabbar">
|
||||
<a class="actif" href="#"><span class="pic">☰</span>Ma journée</a>
|
||||
<a href="#"><span class="pic">▣</span>Scanner</a>
|
||||
<a href="#"><span class="pic">✓</span>Préventif</a>
|
||||
<a href="#"><span class="pic">⇅</span>Synchro<span class="badge-tab">3</span></a>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ═══ 2 · FICHE OT ═══ -->
|
||||
<p class="note-ecran" data-note="fiche-ot" hidden><b>Intention :</b> la même machine à états que le web
|
||||
(R2) — un seul <b>bouton principal</b> selon l'état, jamais de liste de transitions. Consommer une pièce
|
||||
et saisir du temps reprennent les règles R3 (prix et taux <b>figés</b> annoncés avant le geste). Les photos
|
||||
partent en file comme le reste. Aucune saisie n'exige le réseau.</p>
|
||||
<section class="ecran" id="fiche-ot">
|
||||
<div class="tels">
|
||||
<div class="tel">
|
||||
<div class="encoche"><i></i></div>
|
||||
<div class="legende">OT en cours — actions terrain</div>
|
||||
<div class="ecran-tel">
|
||||
<div class="entete-tel">
|
||||
<span class="flamme">♦</span><b>‹ OT-2026-0341</b>
|
||||
<span class="fin"><span class="sync">Synchro à jour</span></span>
|
||||
</div>
|
||||
<div class="titre-tel">Bruit anormal en gaine <span class="st encours">En cours</span></div>
|
||||
<div class="carte-tel">
|
||||
<h4>Intervention</h4>
|
||||
<div class="ligne-info"><span>Équipement</span><b>Asc. A1 — Résidence Al Manar</b></div>
|
||||
<div class="ligne-info"><span>Priorité</span><b style="color:var(--prio-haute)">Haute</b></div>
|
||||
<div class="ligne-info"><span>Échéance</span><b>18 juillet</b></div>
|
||||
<div class="ligne-info"><span>Demande liée</span><b>DEM-2026-0107 · Karim D.</b></div>
|
||||
</div>
|
||||
<div class="carte-tel">
|
||||
<h4>Pièces & main-d'œuvre — 505 MAD</h4>
|
||||
<div class="ligne-info"><span>Coulisseau 16 mm × 2</span><b class="num">240</b></div>
|
||||
<div class="ligne-info"><span>Graisse guide × 1</span><b class="num">85</b></div>
|
||||
<div class="ligne-info"><span>Ahmed · 1 h 30 × 120/h</span><b class="num">180</b></div>
|
||||
<div class="paire-boutons">
|
||||
<button class="btn-tel contour">+ Pièce</button>
|
||||
<button class="btn-tel contour">+ Temps</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="carte-tel">
|
||||
<h4>Photos</h4>
|
||||
<div class="photos-tel">
|
||||
<span class="photo-tel">🖼</span>
|
||||
<span class="photo-tel">🖼<span class="file-chip">en file</span></span>
|
||||
<span class="photo-tel" style="color:var(--primaire);font-size:23px">+</span>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn-tel vert">Clôturer l'intervention</button>
|
||||
<div class="garde">Bilan incomplet : « État des portes », « Action réalisée », « Élément concerné » — la clôture ouvrira le bilan.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ═══ 3 · CLÔTURE TERRAIN ═══ -->
|
||||
<p class="note-ecran" data-note="cloture" hidden><b>Intention :</b> le bilan codé R2, plein écran et au
|
||||
pouce : 3 champs requis (<em>*</em>), la garde reste <b>visible et bloquante</b> tant qu'ils manquent —
|
||||
identique au web, mêmes référentiels administrables. Hors-ligne, « Clôturer » met la clôture <b>en
|
||||
file</b> : l'OT passe localement à « Terminé (en file) » et se confirme à la synchro.</p>
|
||||
<section class="ecran" id="cloture">
|
||||
<div class="tels">
|
||||
<div class="tel">
|
||||
<div class="encoche"><i></i></div>
|
||||
<div class="legende">Bilan incomplet — garde visible</div>
|
||||
<div class="ecran-tel">
|
||||
<div class="entete-tel"><span class="flamme">♦</span><b>‹ Clôturer OT-2026-0341</b></div>
|
||||
<div class="carte-tel">
|
||||
<h4>Bilan d'intervention — requis pour clôturer</h4>
|
||||
<div class="grille-2-tel">
|
||||
<div class="champ-tel"><label>État des portes <em>*</em></label><span class="select-tel">Fonctionnelles ▾</span></div>
|
||||
<div class="champ-tel"><label>Position cabine</label><span class="select-tel vide">Sélectionner ▾</span></div>
|
||||
<div class="champ-tel"><label>Anomalie constatée</label><span class="select-tel">Frottement guides ▾</span></div>
|
||||
<div class="champ-tel"><label>Cause extérieure</label><span class="select-tel vide">Sélectionner ▾</span></div>
|
||||
<div class="champ-tel"><label>Action réalisée <em>*</em></label><span class="select-tel">Remplacement pièce ▾</span></div>
|
||||
<div class="champ-tel"><label>Élément concerné <em>*</em></label><span class="select-tel vide">Sélectionner ▾</span></div>
|
||||
</div>
|
||||
<div class="garde">⚠ « Élément concerné » manque — la clôture restera bloquée (même garde que le web).</div>
|
||||
</div>
|
||||
<div class="carte-tel">
|
||||
<h4>Checklist liée — 12/12 ✓</h4>
|
||||
<div class="ligne-info"><span>Grille de juillet cochée sur place</span><b style="color:var(--succes)">complète</b></div>
|
||||
</div>
|
||||
<button class="btn-tel gris">Clôturer (bilan incomplet)</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tel">
|
||||
<div class="encoche"><i></i></div>
|
||||
<div class="legende">Complet, hors-ligne — clôture en file</div>
|
||||
<div class="ecran-tel">
|
||||
<div class="entete-tel"><span class="flamme">♦</span><b>‹ Clôturer OT-2026-0341</b>
|
||||
<span class="fin"><span class="sync off">Hors-ligne</span></span></div>
|
||||
<div class="carte-tel">
|
||||
<h4>Bilan d'intervention — complet</h4>
|
||||
<div class="grille-2-tel">
|
||||
<div class="champ-tel"><label>État des portes <em>*</em></label><span class="select-tel">Fonctionnelles ▾</span></div>
|
||||
<div class="champ-tel"><label>Position cabine</label><span class="select-tel">À niveau ▾</span></div>
|
||||
<div class="champ-tel"><label>Anomalie constatée</label><span class="select-tel">Frottement guides ▾</span></div>
|
||||
<div class="champ-tel"><label>Cause extérieure</label><span class="select-tel">Aucune ▾</span></div>
|
||||
<div class="champ-tel"><label>Action réalisée <em>*</em></label><span class="select-tel">Remplacement pièce ▾</span></div>
|
||||
<div class="champ-tel"><label>Élément concerné <em>*</em></label><span class="select-tel">Guides ▾</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn-tel vert">Clôturer — partira à la synchro</button>
|
||||
<div class="bandeau-off">La clôture est enregistrée sur le téléphone. Elle sera rejouée telle quelle au retour du réseau.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ═══ 4 · SCAN QR ═══ -->
|
||||
<p class="note-ecran" data-note="scan" hidden><b>Intention :</b> le scanner lit le <b>QR des étiquettes
|
||||
A6</b> posées en R1 (la référence de l'appareil) et ouvre la fiche — y compris <b>hors-ligne</b>, sur le
|
||||
parc déjà synchronisé. En dessous de l'épaule : saisie manuelle de la référence. Aucune géolocalisation
|
||||
en R4 (backlog v2, loi 09-08 : minimisation).</p>
|
||||
<section class="ecran" id="scan">
|
||||
<div class="tels">
|
||||
<div class="tel">
|
||||
<div class="encoche"><i></i></div>
|
||||
<div class="legende">Scanner — QR de l'étiquette A6</div>
|
||||
<div class="ecran-tel">
|
||||
<div class="entete-tel"><span class="flamme">♦</span><b>Scanner</b>
|
||||
<span class="fin"><span class="sync off">Hors-ligne</span></span></div>
|
||||
<div class="viseur">
|
||||
<span class="cadre-qr"></span>
|
||||
<p>Visez le QR de l'étiquette de cabine</p>
|
||||
</div>
|
||||
<button class="btn-tel contour">Saisir la référence (A1, B2…)</button>
|
||||
<nav class="tabbar">
|
||||
<a href="#"><span class="pic">☰</span>Ma journée</a>
|
||||
<a class="actif" href="#"><span class="pic">▣</span>Scanner</a>
|
||||
<a href="#"><span class="pic">✓</span>Préventif</a>
|
||||
<a href="#"><span class="pic">⇅</span>Synchro<span class="badge-tab">3</span></a>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ═══ 5 · FICHE ASCENSEUR ═══ -->
|
||||
<p class="note-ecran" data-note="ascenseur" hidden><b>Intention :</b> après le scan, tout ce qu'Ahmed
|
||||
doit savoir <b>devant la machine</b> : identité, statut, organes, historique des interventions (bilans
|
||||
codés lisibles). Consultation seule : la création d'OT reste au dispatcher (web) et le signalement au
|
||||
portail QR public (R2) — le mobile n'ajoute pas de 3ᵉ canal.</p>
|
||||
<section class="ecran" id="ascenseur">
|
||||
<div class="tels">
|
||||
<div class="tel">
|
||||
<div class="encoche"><i></i></div>
|
||||
<div class="legende">Résultat du scan — Asc. A1</div>
|
||||
<div class="ecran-tel">
|
||||
<div class="entete-tel"><span class="flamme">♦</span><b>‹ Asc. A1</b>
|
||||
<span class="fin"><span class="st termine">En service</span></span></div>
|
||||
<div class="titre-tel">Otis Gen2 — Résidence Al Manar</div>
|
||||
<div class="carte-tel">
|
||||
<h4>Identité</h4>
|
||||
<div class="ligne-info"><span>Emplacement</span><b>Hall principal</b></div>
|
||||
<div class="ligne-info"><span>Mise en service</span><b>mars 2019</b></div>
|
||||
<div class="ligne-info"><span>Sous contrat</span><b style="color:var(--succes)">Oui — préventif mensuel</b></div>
|
||||
<div class="ligne-info"><span>Gardien</span><b>M. Alami · 06 12 34 56 78</b></div>
|
||||
</div>
|
||||
<div class="carte-tel">
|
||||
<h4>Interventions récentes</h4>
|
||||
<div class="hist-item"><span class="ref">OT-0341</span> Bruit anormal — guides <span class="quand">en cours</span></div>
|
||||
<div class="hist-item"><span class="ref">OT-0329</span> Portes — contact remplacé <span class="quand">2 juil.</span></div>
|
||||
<div class="hist-item"><span class="ref">OT-0318</span> Préventif juin — 12/12 ✓ <span class="quand">18 juin</span></div>
|
||||
<div class="hist-item"><span class="ref">OT-0303</span> Armoire cde — fusible <span class="quand">30 mai</span></div>
|
||||
</div>
|
||||
<div class="carte-tel">
|
||||
<h4>Organes suivis</h4>
|
||||
<div class="ligne-info"><span>Treuil ZAA20</span><b>—</b></div>
|
||||
<div class="ligne-info"><span>Portes cabine S3300</span><b>2 pannes / 12 mois</b></div>
|
||||
<div class="ligne-info"><span>Armoire de commande</span><b>1 panne / 12 mois</b></div>
|
||||
</div>
|
||||
<button class="btn-tel">Voir mes OT sur cet appareil (2)</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ═══ 6 · CHECKLIST DU MOIS ═══ -->
|
||||
<p class="note-ecran" data-note="checklist" hidden><b>Intention :</b> la grille préventive R2, cochable
|
||||
<b>au pouce et hors-ligne</b> — chaque coche part en file individuellement (pas de « tout ou rien » :
|
||||
7 coches faites = 7 coches sauvées, même si le téléphone s'éteint). La progression et le statut du mois
|
||||
sont ceux du serveur à la dernière synchro, assumés comme tels.</p>
|
||||
<section class="ecran" id="checklist">
|
||||
<div class="tels">
|
||||
<div class="tel">
|
||||
<div class="encoche"><i></i></div>
|
||||
<div class="legende">Grille de juillet — hors-ligne, 7/12</div>
|
||||
<div class="ecran-tel">
|
||||
<div class="entete-tel"><span class="flamme">♦</span><b>‹ Préventif — juillet</b>
|
||||
<span class="fin"><span class="sync off">Hors-ligne</span></span></div>
|
||||
<div class="titre-tel">Asc. A2 — grille mensuelle <span class="filet num">7/12</span></div>
|
||||
<div class="progress"><i></i></div>
|
||||
<div class="check-item fait"><span class="case"></span>Verrouillage portes palières</div>
|
||||
<div class="check-item fait"><span class="case"></span>Contacts de porte cabine</div>
|
||||
<div class="check-item fait"><span class="case"></span>Niveau d'huile du treuil</div>
|
||||
<div class="check-item fait"><span class="case"></span>Jeu des coulisseaux <span class="file-chip">en file</span></div>
|
||||
<div class="check-item fait"><span class="case"></span>Éclairage cabine & secours <span class="file-chip">en file</span></div>
|
||||
<div class="check-item"><span class="case"></span>Parachute — essai statique</div>
|
||||
<div class="check-item"><span class="case"></span>Fins de course haut/bas</div>
|
||||
<div class="check-item"><span class="case"></span>Téléalarme — essai d'appel</div>
|
||||
<div class="bandeau-off">2 coches en file — la grille se recale à la synchro.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ═══ 7 · SYNCHRO & CONFLITS ═══ -->
|
||||
<p class="note-ecran" data-note="synchro" hidden><b>Intention :</b> la file est <b>visible et honnête</b> :
|
||||
chaque saisie hors-ligne y est listée, rejouée dans l'ordre au retour du réseau. Conflit (verrou
|
||||
optimiste : l'OT a changé côté serveur depuis la lecture) → la file <b>s'arrête sur l'élément</b>, montre
|
||||
qui a modifié quoi et quand, et l'humain tranche — rien n'est écrasé ni perdu en silence. C'est l'écran
|
||||
de la recette type « mode avion en sous-sol ».</p>
|
||||
<section class="ecran" id="synchro">
|
||||
<div class="tels">
|
||||
<div class="tel">
|
||||
<div class="encoche"><i></i></div>
|
||||
<div class="legende">Retour réseau — file en cours</div>
|
||||
<div class="ecran-tel">
|
||||
<div class="entete-tel"><span class="flamme">♦</span><b>Synchro</b>
|
||||
<span class="fin"><span class="sync">Envoi… 2/4</span></span></div>
|
||||
<div class="titre-tel">File d'attente <span class="filet">rejouée dans l'ordre</span></div>
|
||||
<div class="file-item"><span class="ico">✓</span>
|
||||
<span class="quoi"><b>Coche « Jeu des coulisseaux »</b><span>OT-2026-0336 · 14 h 21</span></span>
|
||||
<span class="etat fait">envoyée</span></div>
|
||||
<div class="file-item"><span class="ico">✓</span>
|
||||
<span class="quoi"><b>Coche « Éclairage cabine »</b><span>OT-2026-0336 · 14 h 24</span></span>
|
||||
<span class="etat fait">envoyée</span></div>
|
||||
<div class="file-item"><span class="ico">🖼</span>
|
||||
<span class="quoi"><b>Photo — guides (1,8 Mo)</b><span>OT-2026-0341 · 14 h 32</span></span>
|
||||
<span class="etat envoi">envoi…</span></div>
|
||||
<div class="file-item"><span class="ico">🏁</span>
|
||||
<span class="quoi"><b>Clôture + bilan codé</b><span>OT-2026-0341 · 14 h 40</span></span>
|
||||
<span class="etat attente">en attente</span></div>
|
||||
<nav class="tabbar">
|
||||
<a href="#"><span class="pic">☰</span>Ma journée</a>
|
||||
<a href="#"><span class="pic">▣</span>Scanner</a>
|
||||
<a href="#"><span class="pic">✓</span>Préventif</a>
|
||||
<a class="actif" href="#"><span class="pic">⇅</span>Synchro<span class="badge-tab">2</span></a>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tel">
|
||||
<div class="encoche"><i></i></div>
|
||||
<div class="legende">Conflit — l'humain tranche</div>
|
||||
<div class="ecran-tel">
|
||||
<div class="entete-tel"><span class="flamme">♦</span><b>Synchro</b>
|
||||
<span class="fin"><span class="sync off">1 conflit</span></span></div>
|
||||
<div class="titre-tel">File d'attente <span class="filet">arrêtée sur le conflit</span></div>
|
||||
<div class="carte-conflit">
|
||||
<h4>⚠ Conflit sur OT-2026-0341</h4>
|
||||
<p><b>Salma Idrissi a modifié cet OT à 14 h 38</b> (réassigné + commentaire) pendant que vous étiez hors-ligne. Votre clôture de 14 h 40 n'a <b>pas</b> été appliquée.</p>
|
||||
<small>Votre saisie est conservée telle quelle dans la file — rien n'est perdu.</small>
|
||||
<button class="btn-tel" style="padding:10px;font-size:13px">Revoir l'OT à jour puis rejouer</button>
|
||||
<button class="btn-tel contour" style="padding:10px;font-size:13px">Abandonner ma clôture</button>
|
||||
</div>
|
||||
<div class="file-item"><span class="ico">🏁</span>
|
||||
<span class="quoi"><b>Clôture + bilan codé</b><span>OT-2026-0341 · 14 h 40</span></span>
|
||||
<span class="etat conflit">conflit</span></div>
|
||||
<div class="file-item"><span class="ico">🖼</span>
|
||||
<span class="quoi"><b>Photo — guides (1,8 Mo)</b><span>OT-2026-0341 · 14 h 32</span></span>
|
||||
<span class="etat fait">envoyée</span></div>
|
||||
<nav class="tabbar">
|
||||
<a href="#"><span class="pic">☰</span>Ma journée</a>
|
||||
<a href="#"><span class="pic">▣</span>Scanner</a>
|
||||
<a href="#"><span class="pic">✓</span>Préventif</a>
|
||||
<a class="actif" href="#"><span class="pic">⇅</span>Synchro<span class="badge-tab rouge">1</span></a>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
(function(){
|
||||
var onglets=document.querySelectorAll('.revue .onglets button');
|
||||
var ecrans=document.querySelectorAll('.ecran');
|
||||
var notes=document.querySelectorAll('.note-ecran');
|
||||
onglets.forEach(function(b){b.addEventListener('click',function(){
|
||||
onglets.forEach(function(x){x.setAttribute('aria-selected','false')});
|
||||
b.setAttribute('aria-selected','true');
|
||||
var cible=b.dataset.cible;
|
||||
ecrans.forEach(function(e){e.classList.toggle('actif',e.id===cible)});
|
||||
notes.forEach(function(n){n.hidden=(n.dataset.note!==cible)});
|
||||
window.scrollTo({top:0});
|
||||
})});
|
||||
var ordre=['auto','light','dark'];var i=0;
|
||||
var bt=document.getElementById('btn-theme');
|
||||
bt.addEventListener('click',function(){
|
||||
i=(i+1)%3;var m=ordre[i];
|
||||
if(m==='auto'){document.documentElement.removeAttribute('data-theme')}
|
||||
else{document.documentElement.setAttribute('data-theme',m)}
|
||||
bt.textContent='Thème : '+(m==='auto'?'auto':(m==='light'?'clair':'sombre'));
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -4,6 +4,21 @@ Trace chronologique des sessions (la plus récente en premier). Le **playbook**
|
||||
|
||||
---
|
||||
|
||||
## 2026-07-17 — Pr. Daaif (+ Claude) — R4 ouverte : maquettes mobile (design d'abord)
|
||||
|
||||
**Actions**
|
||||
|
||||
- **`maquette-r4.html`** (docs/02-design/maquettes) : 7 écrans de l'app technicien — Ma journée (en ligne ET hors-ligne côte à côte), Fiche OT, Clôture terrain (bilan codé R2, garde visible ; variante « en file » hors-ligne), Scan QR (étiquettes A6 de R1, hors-ligne inclus), Fiche ascenseur (consultation devant la machine), Checklist du mois (coches individuelles en file), **Synchro & conflits** (file visible, conflit de verrou optimiste où l'humain tranche). Tokens répliqués, bi-thème, gabarit téléphone repris de la maquette R3, données du parc seedé. Vérifiée en navigateur (7 onglets + bascule sombre, zéro erreur console).
|
||||
- Artefact de validation publié pour le référent (7 écrans + preuve bi-thème + **5 décisions à acter** : D1 offline-first lecture locale/écriture en file, D2 verrou optimiste tranché par l'humain, D3 périmètre fermé « app du technicien » sans création d'OT mobile, D4 scan local des étiquettes R1, D5 photos compressées en file — pas d'audio ni de géolocalisation en R4, loi 09-08).
|
||||
|
||||
**Décisions**
|
||||
|
||||
- Aucune actée — les 5 décisions ci-dessus **attendent la validation du référent avec les écrans**. Aucune ligne de code Expo avant (principe n°1).
|
||||
|
||||
**Prochaine étape** : validation référent (maquettes + décisions) → R4.1 socle mobile (Expo, coquille + connexion démo + lecture hors-ligne) ; en parallèle, redéploiement Dokploy de `release/r3` toujours à faire.
|
||||
|
||||
---
|
||||
|
||||
## 2026-07-17 — Pr. Daaif (+ Claude) — R3 CLOSE : tag `release/r3`
|
||||
|
||||
**Actions**
|
||||
|
||||
Reference in New Issue
Block a user