QR Attendance (QRCONTR) — UX/UI Design Specification¶
Module: QR Attendance (QRCONTR) Brands: Papillon HR Suite + ALTARYS ENTERPRISE HR Suite Date: 30/03/2026 Author: DESIGNER (Claude Code) Input: docs/prd/qr-attendance-prd.md v1.0
Table of Contents¶
- Design Decisions Summary
- User Flow Diagrams
- Screen-by-Screen Wireframes
- Interaction Specifications
- Responsive Behavior
- Offline Behavior
- French Micro-copy
- Component Specifications
- Brand Compliance Checklist
1. Design Decisions Summary¶
This section records the key UX decisions made for the module, with reasoning.
D1: Clock-In Experience — Full-Screen Camera Scanner¶
Decision: The clock-in/out screen is a full-screen camera viewfinder with a single QR frame overlay. No menus, no chrome — just scan and go. Reasoning: This is a high-frequency, time-pressured action (employee standing at entrance). Hick's Law — zero choices = fastest action. The < 1s response target (NFR) demands minimal UI overhead. Inspired by transit card scanners: tap and walk.
D2: Dashboard Layout — Status Cards + Scrollable Employee List¶
Decision: Daily attendance dashboard uses horizontal status summary cards (Présents, En retard, Absents, Télétravail, En congé) at the top, followed by a filterable/searchable employee list below. Reasoning: The "status cards → list" pattern gives HR an instant pulse check (Gestalt: proximity groups the KPIs), then drill-down capability. On mobile, cards scroll horizontally; on desktop, they sit in a row.
D3: Navigation — Bottom Tab Bar (Mobile) / Sidebar (Desktop)¶
Decision: Papillon uses a 4-tab bottom navigation (Pointage, Tableau de bord, Historique, Plus). Enterprise uses a left sidebar with all sections visible. Reasoning: Fitts's Law — bottom tabs are in the thumb zone on mobile. 4 tabs respects the "4±1" cognitive limit. Enterprise users need rapid switching between more views, so a persistent sidebar with groupings works better.
D4: Regularization & Télétravail — Wizard-Style Bottom Sheets (Mobile) / Side Panels (Desktop)¶
Decision: Requests use progressive-disclosure bottom sheets on mobile (step 1: select date → step 2: fill details → step 3: confirm). On desktop, a slide-in side panel with all fields visible. Reasoning: Mobile screen real estate is precious. A 3-step bottom sheet keeps cognitive load low per step (Miller's Law). Desktop has space for the full form without splitting.
D5: QR Scanner Result — Full-Screen Celebration Moment¶
Decision: Successful scan triggers a full-screen success state: large animated checkmark, time displayed prominently, warm amber pulse animation. Stays 2 seconds then auto-dismisses to history. Reasoning: This is the module's signature moment. A premium celebration builds habit and confidence ("it worked!"). For users new to digital tools, explicit, joyful confirmation reduces anxiety.
D6: Report Viewing — In-App Preview + Export¶
Decision: Reports are rendered in-app as scrollable tables with sticky headers, with an export FAB (Excel/CSV). Not PDF-first. Reasoning: In-app viewing works offline (cached data). PDF generation requires server round-trips. The export button handles formal sharing needs. Sticky headers keep context while scrolling long tables.
D7: Empty States — Contextual Guidance, Not Just "No Data"¶
Decision: Every empty state includes an illustration, explanation, and a single CTA to resolve it. Example: empty dashboard shows "Aucun employé n'a pointé aujourd'hui" + "Vérifiez que le QR code est affiché sur site." Reasoning: Empty states are learning moments. For first-time HR users transitioning from paper, a helpful empty state teaches the system's workflow.
D8: Offline Indicator — Persistent Subtle Banner, Not Modal¶
Decision: A thin amber banner sits below the top bar when offline: "Hors ligne — vos pointages seront synchronisés." No blocking modals. Reasoning: Offline is the expected state for many users. A modal would be disruptive and anxiety-inducing. A calm, persistent banner normalizes offline operation.
D9: Module Activation — Compliance Notice as Onboarding Step¶
Decision: The délégués du personnel compliance notice is presented as the first step in a 3-step module onboarding wizard (1. Compliance notice → 2. Create first site → 3. Create first schedule), not as a popup. Reasoning: Progressive disclosure in context. Integrating compliance into the setup flow ensures it's seen but doesn't feel like a bureaucratic blocker. The "not required" nature is preserved — the wizard can be completed without checking the box.
D10: Anomaly Presentation — Inline Badges with Tap-to-Expand¶
Decision: Anomalies (shared device, auto-closed, incomplete) are shown as colored badges on the employee row, tappable to expand details. Reasoning: Badges provide at-a-glance scanning (pre-attentive processing via color). Tap-to-expand avoids overloading the list with details most employees won't have.
2. User Flow Diagrams¶
2.1 Employee Clock-In/Out Flow¶
flowchart TD
A[Ouvrir l'app Papillon] --> B{Connecté ?}
B -->|Non| C[Écran de connexion]
C --> B
B -->|Oui| D[Accueil — Tab Pointage]
D --> E[Appuyer 'Scanner le QR']
E --> F{Caméra autorisée ?}
F -->|Non| G[Demande permission caméra]
G -->|Refusé| H[Message: Activez la caméra dans les paramètres]
G -->|Accepté| I[Scanner plein écran]
F -->|Oui| I
I --> J{QR décodé ?}
J -->|Non - timeout 10s| K[Message: QR non reconnu. Réessayez.]
K --> I
J -->|Oui| L{En ligne ?}
L -->|Oui| M[Validation serveur HMAC + tenant + site + token]
L -->|Non| N[Validation locale cache IndexedDB]
M --> O{Valide ?}
N --> O
O -->|Non| P[Écran erreur: QR invalide. Contactez les RH.]
O -->|Oui| Q{Employé actif ?}
Q -->|Non| R[Écran erreur: Compte désactivé]
Q -->|Oui| S{Doublon 15 min ?}
S -->|Oui| T[Message: Pointage déjà enregistré]
S -->|Non| U[Déterminer IN ou OUT]
U --> V[Enregistrer clock event]
V --> W{En ligne ?}
W -->|Oui| X[Sync immédiat]
W -->|Non| Y[Queue IndexedDB]
X --> Z[🎉 Écran succès: Pointage enregistré — HH:MM]
Y --> Z
Z -->|2s auto-dismiss| AA[Retour historique du jour]
2.2 HR Daily Dashboard Flow¶
flowchart TD
A[HR ouvre Tab Tableau de bord] --> B{En ligne ?}
B -->|Oui| C[Fetch données temps réel]
B -->|Non| D[Charger cache local]
C --> E[Afficher skeleton shimmer]
E --> F[Render: Cartes résumé + Liste employés]
D --> F
F --> G{Action HR ?}
G -->|Filtre département| H[Filtrer liste]
G -->|Filtre site| H
G -->|Filtre statut| H
G -->|Recherche nom| H
H --> F
G -->|Tap employé| I[Détail pointage du jour]
I --> J{Anomalie ?}
J -->|Oui| K[Afficher détail anomalie]
J -->|Non| L[Voir heures, statut, site]
G -->|Tap anomalie badge| K
G -->|Créer régularisation directe| M[Bottom sheet / Side panel régularisation]
M --> N[Remplir formulaire]
N --> O[Confirmer — auto-approuvé]
O --> F
2.3 Regularization Request Flow (Employee)¶
flowchart TD
A[Employé ouvre Historique] --> B[Voir liste pointages du mois]
B --> C[Tap sur un jour avec problème]
C --> D[Détail du jour]
D --> E[Bouton 'Demander une régularisation']
E --> F[Step 1: Sélectionner la raison]
F --> G{Raison = AUTRE ?}
G -->|Oui| H[Champ détail obligatoire]
G -->|Non| I[Step 2: Corriger les heures]
H --> I
I --> J[Saisir heure arrivée et/ou départ corrigée]
J --> K[Step 3: Confirmer]
K --> L{En ligne ?}
L -->|Oui| M[Envoyer au serveur — PENDING]
L -->|Non| N[Queue IndexedDB — marqué PENDING local]
M --> O[Confirmation: Demande envoyée]
N --> O
O --> P[Notification manager + HR]
2.4 Télétravail Request Flow¶
flowchart TD
A[Employé ouvre Plus > Télétravail] --> B[Calendrier du mois]
B --> C[Sélectionner une date future]
C --> D{Date < préavis min ?}
D -->|Oui| E[Raison obligatoire]
D -->|Non| F[Raison optionnelle]
E --> G[Formulaire de demande]
F --> G
G --> H{Limite hebdo/mensuelle atteinte ?}
H -->|Oui| I[Warning: Limite atteinte — demande soumise à validation]
H -->|Non| J[Confirmer]
I --> J
J --> K{En ligne ?}
K -->|Oui| L[Envoyer — PENDING]
K -->|Non| M[Queue IndexedDB]
L --> N[Confirmation: Demande soumise]
M --> N
2.5 Site & QR Code Configuration Flow (HR)¶
flowchart TD
A[HR ouvre Configuration > Sites] --> B[Liste des sites]
B --> C{Sites existants ?}
C -->|Non| D[Empty state: Créez votre premier site]
C -->|Oui| E[Afficher liste avec QR status]
D --> F[Bouton + Nouveau site]
E --> F
F --> G[Formulaire: Nom + Adresse optionnelle]
G --> H[Sauvegarder]
H --> I[QR généré automatiquement]
I --> J[Aperçu QR + Boutons Télécharger / Imprimer]
E --> K[Tap site existant]
K --> L[Détail site: QR + actions]
L --> M{Régénérer QR ?}
M -->|Oui| N[Confirmation: L'ancien QR sera invalidé]
N -->|Confirmer| O[Nouveau QR généré]
N -->|Annuler| L
2.6 Module Activation Onboarding Flow¶
flowchart TD
A[HR active module QRCONTR] --> B[Wizard Step 1: Notice de conformité]
B --> C{Consultation délégués effectuée ?}
C -->|Oui - coche la case| D[Champs optionnels: Date + PV]
C -->|Non - passe sans cocher| E[Enregistrement: reminder affiché, non acquitté]
D --> F[Step 2: Créer premier site]
E --> F
F --> G[Formulaire site + génération QR]
G --> H[Step 3: Créer premier horaire]
H --> I[Formulaire horaire Lun-Sam]
I --> J[Félicitations — Module prêt !]
J --> K[Redirection vers Dashboard]
3. Screen-by-Screen Wireframes¶
3.1 Clock-In/Out Scanner Screen (Papillon)¶
Design decisions applied: D1 (full-screen scanner), D5 (celebration moment)
┌─────────────────────────┐
│ ← Retour 🔦 │ ← Torch toggle
│ │
│ │
│ ┌─────────────┐ │
│ │ │ │
│ │ QR FRAME │ │ ← Animated corners
│ │ OVERLAY │ │ pulsing amber
│ │ │ │
│ └─────────────┘ │
│ │
│ Placez le QR code │ ← Helper text
│ dans le cadre │
│ │
│ ● Hors ligne │ ← Only if offline
│ Pointage sauvegardé │
│ localement │
│ │
└─────────────────────────┘
360px
Success State (2s auto-dismiss):
┌─────────────────────────┐
│ │
│ │
│ ╭─────────╮ │
│ │ ✓ │ │ ← Animated check
│ │ SCALE │ │ with amber
│ │ BOUNCE │ │ pulse ring
│ ╰─────────╯ │
│ │
│ Pointage enregistré │ ← Large, warm
│ │
│ 08:02 │ ← Huge time display
│ │
│ Arrivée — Site Abidjan│ ← IN/OUT + site name
│ │
│ ● Synchronisé ✓ │ ← or "En attente
│ │ de synchronisation"
│ │
└─────────────────────────┘
Error State:
┌─────────────────────────┐
│ │
│ ╭─────────╮ │
│ │ ✕ │ │ ← Red X with
│ │ │ │ shake animation
│ ╰─────────╯ │
│ │
│ QR code invalide │
│ Contactez les RH │
│ │
│ ┌───────────────────┐ │
│ │ Réessayer │ │ ← Primary CTA
│ └───────────────────┘ │
│ │
└─────────────────────────┘
3.2 Employee Home / Tab "Pointage" (Papillon)¶
Design decisions applied: D3 (bottom tab bar), D8 (offline banner)
┌─────────────────────────┐
│ Bonjour, Aminata 👋 │ ← Warm greeting
│ Lun 01/03/2026 │
├─────────────────────────┤
│ ⚠ Hors ligne — vos │ ← Amber banner
│ pointages seront sync. │ (only if offline)
├─────────────────────────┤
│ │
│ Aujourd'hui │
│ ┌───────────────────┐ │
│ │ ● Arrivée 08:02 │ │ ← Green dot
│ │ Site Abidjan │ │
│ │ ✓ Synchronisé │ │
│ ├───────────────────┤ │
│ │ ○ Départ — │ │ ← Grey dot
│ │ En attente │ │
│ └───────────────────┘ │
│ │
│ ┌───────────────────┐ │
│ │ 📷 Scanner le QR │ │ ← Large CTA
│ │ │ │ 48px height
│ └───────────────────┘ │ amber/gold bg
│ │
│ Heures travaillées │
│ aujourd'hui: 4h23 │
│ Horaire prévu: 8h00 │
│ │
├─────────────────────────┤
│ 📷 📊 📋 ⋯ │ ← Bottom tabs
│Pointage Board Hist. Plus│
└─────────────────────────┘
3.3 Daily Attendance Dashboard — HR View (Papillon)¶
Design decisions applied: D2 (status cards + list), D10 (anomaly badges)
┌─────────────────────────┐
│ Tableau de bord │
│ Lun 01/03/2026 │
├─────────────────────────┤
│ │
│ ┌────┐┌────┐┌────┐┌────┐ ← Horizontal
│ │ 23 ││ 4 ││ 3 ││ 2 │ scroll cards
│ │Prés││Ret.││Abs.││Télé│
│ │ ● ││ ● ││ ● ││ ● │ ← Color dots
│ │vert││amb.││rou.││bleu│
│ └────┘└────┘└────┘└────┘
│ ← scroll → │
│ │
│ 🔍 Rechercher │ ← Search bar
│ [Département ▾] [Site ▾]│ ← Filter chips
│ [Statut ▾] │
│ │
│ ┌───────────────────────┐│
│ │ KONÉ Aminata 08:02 ││ ← Name + time
│ │ Comptabilité ● Prés. ││ ← Dept + status
│ ├───────────────────────┤│
│ │ TOURÉ Ibrahim 08:15 ││
│ │ Logistique ● Retard ││ ← Amber badge
│ │ ⚠ Appareil partagé ││ ← Anomaly badge
│ ├───────────────────────┤│
│ │ DIALLO Fatou — ││
│ │ Marketing ● Absent ││ ← Red badge
│ ├───────────────────────┤│
│ │ BAMBA Moussa — ││
│ │ IT ● Télé. ││ ← Blue badge
│ └───────────────────────┘│
│ │
├─────────────────────────┤
│ 📷 📊 📋 ⋯ │
│Pointage Board Hist. Plus│
└─────────────────────────┘
3.4 Daily Attendance Dashboard — HR View (Enterprise)¶
Design decisions applied: D2 adapted for high-density desktop
┌──────────────────────────────────────────────────────────────────────────┐
│ ALTARYS ENTERPRISE │ QR Attendance 🔔 JD ▾ │
├──────────┬───────────────────────────────────────────────────────────────┤
│ │ Tableau de bord — Lun 01/03/2026 ⟳ Actualiser │
│ ■ T.Bord │ │
│ □ Sites │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌────────┐ │
│ □ Horai. │ │ 156 │ │ 12 │ │ 8 │ │ 14 │ │ 5 │ │
│ □ Régul. │ │ Présents │ │En retard│ │ Absents │ │Télétrav.│ │En congé│ │
│ □ Télé. │ │ ▲3 │ │ ▼2 │ │ = │ │ ▲1 │ │ = │ │
│ □ Rapport│ │vs. hier │ │vs. hier │ │vs. hier │ │vs. hier │ │vs. hier│ │
│ □ Config │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └────────┘ │
│ │ │
│ │ 🔍 Rechercher employé [Département ▾] [Site ▾] [Statut ▾]│
│ │ ☐ Sélectionner tout Export ▾ Actions ▾│
│ │ │
│ │ ┌────┬─────────────┬────────┬────────┬──────┬───────┬──────┐│
│ │ │ ☐ │ Employé │Arrivée │Départ │Heures│Statut │Anom. ││
│ │ ├────┼─────────────┼────────┼────────┼──────┼───────┼──────┤│
│ │ │ ☐ │KONÉ Aminata │ 08:02 │ — │ 4h23 │● Prés.│ ││
│ │ │ ☐ │TOURÉ Ibrahim│ 08:15 │ — │ 3h45 │● Ret. │⚠ App.││
│ │ │ ☐ │DIALLO Fatou │ — │ — │ — │● Abs. │ ││
│ │ │ ☐ │BAMBA Moussa │ — │ — │ 8h00 │● Télé.│ ││
│ │ └────┴─────────────┴────────┴────────┴──────┴───────┴──────┘│
│ │ │
│ │ ◀ 1 2 3 ... 12 ▶ Affichage: 25 │ 50 │ 100 │
└──────────┴───────────────────────────────────────────────────────────────┘
1440px
3.5 Employee Attendance History (Papillon)¶
┌─────────────────────────┐
│ ← Mon historique │
│ Mars 2026 ◀ ▶ │ ← Month picker
├─────────────────────────┤
│ │
│ Résumé du mois │
│ ┌─────────┬──────────┐ │
│ │Travaillé│ Retards │ │
│ │ 152h30 │ 3 │ │
│ ├─────────┼──────────┤ │
│ │H. Supp. │ Absences │ │
│ │ 4h30 │ 1 │ │
│ └─────────┴──────────┘ │
│ │
│ ┌───────────────────┐ │
│ │ Lun 01/03 │ │
│ │ 08:02 → 17:35 │ │
│ │ 8h33 travaillées │ │
│ │ ● Présent │ │
│ ├───────────────────┤ │
│ │ Mar 02/03 │ │
│ │ 08:15 → 17:30 │ │
│ │ 8h15 travaillées │ │
│ │ ● Retard (15 min) │ │ ← Amber badge
│ ├───────────────────┤ │
│ │ Mer 03/03 │ │
│ │ — → — │ │
│ │ ● Absent │ │ ← Red badge
│ │ [Demander régul.] │ │ ← Inline CTA
│ └───────────────────┘ │
│ │
├─────────────────────────┤
│ 📷 📊 📋 ⋯ │
│Pointage Board Hist. Plus│
└─────────────────────────┘
3.6 Regularization Request — Bottom Sheet (Papillon Mobile)¶
Design decisions applied: D4 (wizard bottom sheets)
Step 1: Reason
┌─────────────────────────┐
│ │
│ (dimmed background — │
│ attendance detail) │
│ │
├─━━━━━━━━━━━━━━━━━━━━━━━┤ ← Drag handle
│ Demander une │
│ régularisation │
│ Mer 03/03/2026 │
│ │
│ Quelle est la raison ? │
│ │
│ ○ Oubli de pointage │ ← Radio buttons
│ ○ Problème technique │ 48px touch
│ ○ Mission extérieure │
│ ○ Autre │
│ │
│ ┌───────────────────┐ │
│ │ Suivant → │ │
│ └───────────────────┘ │
└─────────────────────────┘
Step 2: Correct Times
├─━━━━━━━━━━━━━━━━━━━━━━━┤
│ Corriger les heures │
│ Mer 03/03/2026 │
│ │
│ Heure d'arrivée │
│ ┌───────────────────┐ │
│ │ 08 : 00 │ │ ← Time picker
│ └───────────────────┘ │ scrollable
│ │
│ Heure de départ │
│ ┌───────────────────┐ │
│ │ 17 : 30 │ │
│ └───────────────────┘ │
│ │
│ ← Retour │
│ ┌───────────────────┐ │
│ │ Confirmer ✓ │ │
│ └───────────────────┘ │
└─────────────────────────┘
Step 3: Confirmation
├─━━━━━━━━━━━━━━━━━━━━━━━┤
│ │
│ ✓ │ ← Animated check
│ │
│ Demande envoyée │
│ │
│ Votre manager et les │
│ RH seront notifiés. │
│ │
│ Raison: Oubli │ ← Summary
│ Arrivée: 08:00 │
│ Départ: 17:30 │
│ │
│ ┌───────────────────┐ │
│ │ Fermer │ │
│ └───────────────────┘ │
└─────────────────────────┘
3.7 Télétravail Request (Papillon Mobile)¶
┌─────────────────────────┐
│ ← Demande de télétravail│
├─────────────────────────┤
│ │
│ ┌───────────────────┐ │
│ │ MARS 2026 │ │
│ │ L M M J V S D│ │ ← Calendar
│ │ 1 2 3 4│ │
│ │ 5 6 7 8 9 10 11│ │
│ │12 13 14 15 16 17 18│ │
│ │19 20 [21]22 23 24 25│ │ ← Selected date
│ │26 27 28 29 30 31 │ │ highlighted
│ └───────────────────┘ │ amber
│ │
│ Vendredi 21/03/2026 │
│ │
│ Raison (optionnelle) │
│ ┌───────────────────┐ │
│ │ │ │
│ └───────────────────┘ │
│ │
│ ⓘ 1 jour télétravail │ ← Info: counter
│ cette semaine (max 2) │ if limit set
│ │
│ ┌───────────────────┐ │
│ │ Envoyer la demande│ │
│ └───────────────────┘ │
│ │
└─────────────────────────┘
3.8 Approval Screen — Manager/HR (Papillon)¶
┌─────────────────────────┐
│ Demandes en attente 3 │ ← Badge count
├─────────────────────────┤
│ │
│ [Régularisations ▾] │ ← Tab/filter
│ [Télétravail ▾] │
│ │
│ ┌───────────────────────┐│
│ │ KONÉ Aminata ││
│ │ Régularisation ││
│ │ Mer 03/03 — Oubli ││
│ │ Arrivée: 08:00 ││
│ │ Départ: 17:30 ││
│ │ ││
│ │ ┌─────────┐┌─────────┐││
│ │ │✓Approuver││✕Refuser │││ ← Swipeable
│ │ └─────────┘└─────────┘││ or tap
│ └───────────────────────┘│
│ │
│ ┌───────────────────────┐│
│ │ TOURÉ Ibrahim ││
│ │ Télétravail ││
│ │ Ven 21/03 ││
│ │ Raison: — ││
│ │ ⚠ Limite hebdo atteinte││
│ │ ││
│ │ ┌─────────┐┌─────────┐││
│ │ │✓Approuver││✕Refuser │││
│ │ └─────────┘└─────────┘││
│ └───────────────────────┘│
│ │
├─────────────────────────┤
│ 📷 📊 📋 ⋯ │
└─────────────────────────┘
3.9 Site Management — HR (Papillon)¶
┌─────────────────────────┐
│ ← Sites de pointage │
├─────────────────────────┤
│ │
│ ┌───────────────────────┐│
│ │ 📍 Siège Abidjan ││
│ │ Plateau, Rue du Comm. ││
│ │ QR actif depuis ││
│ │ 01/03/2026 ││
│ │ ┌─────────────────┐ ││
│ │ │ Voir le QR │ ││
│ │ └─────────────────┘ ││
│ └───────────────────────┘│
│ │
│ ┌───────────────────────┐│
│ │ 📍 Entrepôt Yopougon ││
│ │ Zone industrielle ││
│ │ QR actif depuis ││
│ │ 01/03/2026 ││
│ │ ┌─────────────────┐ ││
│ │ │ Voir le QR │ ││
│ │ └─────────────────┘ ││
│ └───────────────────────┘│
│ │
│ ┌───────────────────┐ │
│ │ + Nouveau site │ │ ← FAB or inline
│ └───────────────────┘ │
│ │
└─────────────────────────┘
3.10 QR Code Detail / Print Screen¶
┌─────────────────────────┐
│ ← Siège Abidjan │
├─────────────────────────┤
│ │
│ ┌───────────────────┐ │
│ │ │ │
│ │ ██████████ │ │
│ │ █ QR CODE █ │ │ ← Large QR
│ │ █ PREVIEW █ │ │ on elevated
│ │ ██████████ │ │ card with
│ │ │ │ warm shadow
│ │ PAPILLON HR │ │
│ │ Siège Abidjan │ │
│ └───────────────────┘ │
│ │
│ Généré le 01/03/2026 │
│ │
│ ┌───────────────────┐ │
│ │ 📥 Télécharger │ │
│ └───────────────────┘ │
│ ┌───────────────────┐ │
│ │ 🖨 Imprimer │ │
│ └───────────────────┘ │
│ ┌───────────────────┐ │
│ │ 🔄 Régénérer │ │ ← Warning color
│ └───────────────────┘ │
│ │
└─────────────────────────┘
3.11 Work Schedule Configuration — HR¶
┌─────────────────────────┐
│ ← Créer un horaire │
├─────────────────────────┤
│ │
│ Nom de l'horaire │
│ ┌───────────────────┐ │
│ │ Bureau │ │
│ └───────────────────┘ │
│ │
│ Lundi │
│ ☑ Jour travaillé │
│ [08:00] → [17:00] │
│ Pause: [12:00] → [14:00]│
│ ☐ Suivi des pauses │
│ │
│ Mardi │
│ ☑ Jour travaillé │
│ [08:00] → [17:00] │
│ Pause: [12:00] → [14:00]│
│ ☐ Suivi des pauses │
│ │
│ ... (Mer-Sam) │
│ │
│ Dimanche │
│ ☐ Jour travaillé │ ← Off by default
│ │
│ ┌───────────────────┐ │
│ │ Enregistrer │ │
│ └───────────────────┘ │
│ │
└─────────────────────────┘
3.12 Module Activation Onboarding Wizard¶
Design decisions applied: D9 (compliance as onboarding step)
Step 1/3 — Compliance Notice
┌─────────────────────────┐
│ Activation du pointage │
│ Étape 1 / 3 │
│ ━━━━━━━━○○ │ ← Progress bar
├─────────────────────────┤
│ │
│ ⚖️ Information légale │
│ │
│ La mise en place d'un │
│ système de pointage │
│ électronique doit │
│ faire l'objet d'une │
│ consultation des │
│ délégués du personnel │
│ (Art. 16.1 Code du │
│ Travail). │
│ │
│ ☐ Oui, consultation │ ← Checkbox
│ effectuée │
│ │
│ Date (optionnel) │
│ ┌───────────────────┐ │
│ │ JJ/MM/AAAA │ │
│ └───────────────────┘ │
│ │
│ 📎 Joindre le PV │ ← File upload
│ (optionnel) │
│ │
│ ┌───────────────────┐ │
│ │ Continuer → │ │
│ └───────────────────┘ │
│ │
│ ⓘ < 11 salariés ? │ ← Contextual note
│ Cette obligation │ if tenant < 11
│ concerne les entreprises│
│ de 11 salariés et plus. │
│ │
└─────────────────────────┘
3.13 Monthly Report View (Papillon Mobile)¶
Design decisions applied: D6 (in-app preview + export)
┌─────────────────────────┐
│ ← Rapport mensuel │
│ Mars 2026 ◀ ▶ │
├─────────────────────────┤
│ KONÉ Aminata │
│ Comptabilité │
│ │
│ Résumé │
│ ┌─────────┬──────────┐ │
│ │ 168h00 │ 4h30 │ │
│ │Travaillé│ H. supp. │ │
│ ├─────────┼──────────┤ │
│ │ 3 │ 1 │ │
│ │ Retards │ Absence │ │
│ ├─────────┼──────────┤ │
│ │ 2 │ 95% │ │
│ │ Télétrav│ Assiduité│ │
│ └─────────┴──────────┘ │
│ │
│ Détail par jour → │ ← Horizontal
│ ┌─────────────────────┐│ scroll table
│ │ Date │Arr. │Dép.│Hrs ││
│ │──────│─────│────│────││
│ │ 01/03│08:02│17:35│8h33││
│ │ 02/03│08:15│17:30│8h15││ ← amber row
│ │ 03/03│ — │ — │ — ││ ← red row
│ └─────────────────────┘│
│ │
│ ┌───────────────────┐ │
│ │ 📥 Exporter Excel │ │ ← FAB
│ └───────────────────┘ │
│ ┌───────────────────┐ │
│ │ 📥 Exporter CSV │ │
│ └───────────────────┘ │
│ │
└─────────────────────────┘
3.14 Empty States¶
No employees clocked in yet (Dashboard)
┌─────────────────────────┐
│ Tableau de bord │
│ Lun 01/03/2026 │
├─────────────────────────┤
│ │
│ ☀️ │
│ (illustration) │
│ │
│ Aucun pointage │
│ aujourd'hui │
│ │
│ Les pointages │
│ apparaîtront ici dès │
│ que vos employés │
│ scanneront le QR code. │
│ │
│ ┌───────────────────┐ │
│ │ Configurer un site │ │ ← CTA if no sites
│ └───────────────────┘ │
│ │
│ 💡 Astuce: Imprimez le │
│ QR code et affichez-le │
│ à l'entrée du site. │
│ │
└─────────────────────────┘
No schedule configured (Employee)
┌─────────────────────────┐
│ │
│ 📅 │
│ (illustration) │
│ │
│ Pas d'horaire configuré │
│ │
│ Vos heures de travail │
│ ne sont pas encore │
│ définies. Contactez │
│ les RH pour configurer │
│ votre horaire. │
│ │
└─────────────────────────┘
4. Interaction Specifications¶
4.1 QR Scanner¶
| State | Behavior |
|---|---|
| Loading | Camera viewfinder initializing — skeleton shimmer on frame area, helper text: "Démarrage de la caméra..." |
| Ready | Pulsing amber corners on scan frame. Helper text: "Placez le QR code dans le cadre." |
| Scanning | Frame corners lock to detected QR boundary (haptic feedback on detection). |
| Success | Full-screen warm gradient background fades in. Animated checkmark with scale bounce (0→1.2→1.0, 300ms). Time appears with staggered fade-in (50ms delay). Haptic success pattern. Auto-dismiss after 2000ms. |
| Error (invalid QR) | Red shake animation on frame (3x, 200ms). Error message slides up from bottom. Haptic error pattern. "Réessayer" button. |
| Error (terminated) | Same animation as invalid QR. Distinct message: "Compte désactivé — contactez les RH." |
| Duplicate | Friendly info state (amber, not red): "Pointage déjà enregistré à HH:MM." Auto-dismiss 2s. |
| Offline | Scanner works normally. Success state shows amber sync indicator: "⏳ En attente de synchronisation" instead of green check. |
| Empty (no camera) | Full-screen message: "Autorisez l'accès à la caméra pour scanner le QR code." + Button to open settings. |
4.2 Daily Dashboard¶
| State | Behavior |
|---|---|
| Loading | 5 skeleton cards (shimmer) + 5 skeleton list rows. Stagger entrance: cards appear 50ms apart, list rows 30ms apart. |
| Empty (no data today) | Illustration + guidance text (see 3.14). Status cards show 0 with muted appearance. |
| Error (fetch failed) | Inline error card: "Impossible de charger les données. Vérifiez votre connexion." + Retry button. Falls back to cached data if available. |
| Offline | Amber offline banner. Shows cached data with "Dernière mise à jour: HH:MM" timestamp. Status cards from cache. Pull-to-refresh disabled (shows toast: "Vous êtes hors ligne"). |
| Success | Cards animate in with stagger (50ms). List items fade in. WebSocket or 30s polling keeps data fresh. |
Interactions: - Filter chips: Tap to toggle. Active state: filled amber. Inactive: outlined. Multi-select for status; single-select for department/site. - Employee row tap: Slide-right transition to employee day detail. - Anomaly badge tap: Expands inline with 200ms height animation showing anomaly details. - Pull-to-refresh (mobile): Custom amber spinner. Refreshes all data. - Swipe left on employee row (mobile): Reveals quick-action: "Régularisation directe" (HR only).
4.3 Regularization Bottom Sheet¶
| State | Behavior |
|---|---|
| Loading | N/A — form is local. |
| Empty | Pre-filled with the date from context. Reason options visible. |
| Error (validation) | Inline field errors in French. Red border + error text below field. Auto-focus on first error field. |
| Offline | Form works normally. Submit shows "Demande sauvegardée — sera envoyée dès la reconnexion." |
| Success | Step 3: animated checkmark, summary, auto-dismiss after tap on "Fermer". |
Interactions: - Drag handle: Drag down to dismiss (with velocity threshold). - Step navigation: Slide-left animation between steps (300ms, ease-out). - Time picker: Native scroll pickers (hours : minutes). 15-minute increments suggested, any minute selectable. - Back button: Preserves entered data (no data loss).
4.4 Télétravail Request¶
| State | Behavior |
|---|---|
| Loading | Calendar skeleton shimmer. |
| Empty | Calendar with no requests. Today highlighted. Past dates greyed out. |
| Error | Inline validation: "Sélectionnez une date future." |
| Offline | Full form works. "Demande sauvegardée localement." |
| Success | Calendar date gets a pending indicator (amber dot). Toast: "Demande envoyée." |
Calendar interactions: - Date tap: Selected date gets amber circle highlight. Disabled dates (past, holidays) don't respond. - Existing requests: Shown as colored dots under dates (green = approved, amber = pending, red = rejected). - Month navigation: Left/right arrows. Swipe gesture on calendar.
4.5 Approval Actions¶
| State | Behavior |
|---|---|
| Loading | Skeleton cards for pending requests. |
| Empty | "Aucune demande en attente 🎉" with illustration. |
| Error | "Impossible de charger les demandes. Réessayez." |
| Offline | Cached pending requests shown. Approve/Reject available — queued for sync. |
| Success (approve) | Green flash on card → card slides out left with 300ms animation. Counter badge decrements. |
| Success (reject) | Red flash → card slides out. |
Interactions: - Swipe right on card (mobile): Quick approve (green trail animation). - Swipe left on card (mobile): Quick reject (red trail animation). Requires rejection reason in popup. - Tap approve/reject buttons: Standard button interaction with loading spinner. - Undo: Toast with 5-second undo window after approve/reject. "Action annulée" on undo.
4.6 Site & QR Management¶
| State | Behavior |
|---|---|
| Loading | Skeleton cards for sites. |
| Empty | Onboarding illustration + "Créez votre premier site de pointage." |
| Error | Inline retry. |
| Offline | Cached site list. Create/edit disabled with message: "Disponible en ligne." QR download available from cache. |
| Success (create) | New site card slides in from bottom. QR code appears with scale animation. |
QR Regeneration: - Tap "Régénérer" → Confirmation bottom sheet: "L'ancien QR code sera invalidé. Vous devrez imprimer et afficher le nouveau. Continuer ?" - Two buttons: "Annuler" (secondary) + "Régénérer" (warning/amber). - After regeneration: new QR animates in, old fades out. Toast: "Nouveau QR code généré. Pensez à l'imprimer."
4.7 Work Schedule Configuration¶
| State | Behavior |
|---|---|
| Loading | Skeleton for schedule list. |
| Empty | "Aucun horaire configuré. Définissez un horaire pour activer le suivi des retards et heures supplémentaires." |
| Error | Field-level validation. Time conflicts flagged: "L'heure de fin doit être après l'heure de début." |
| Offline | Create/edit disabled: "Disponible en ligne." View cached schedules. |
| Success | Schedule card slides in. Toast: "Horaire créé." |
Interactions: - Day toggle: "Jour travaillé" checkbox toggles time fields visibility (slide animation, 200ms). - Time fields: Appear when day is toggled on. Pre-filled with smart defaults (08:00-17:00, break 12:00-14:00). - Copy to all days: Button "Appliquer à tous les jours" — copies current day's times to all enabled days. - Auto-save: Fields save on blur. Green check appears briefly next to saved field.
5. Responsive Behavior¶
5.1 Breakpoints¶
| Breakpoint | Target | Layout |
|---|---|---|
| 360-599px | Phone (Papillon primary) | Single column, bottom tabs, bottom sheets |
| 600-1023px | Tablet | Two-column where useful, bottom tabs, side panels |
| 1024-1439px | Small desktop | Sidebar nav, multi-column layouts |
| 1440px+ | Desktop (Enterprise primary) | Full sidebar, data tables, keyboard shortcuts |
5.2 Component Adaptation¶
| Component | Phone (360px) | Tablet (600px) | Desktop (1440px) |
|---|---|---|---|
| Navigation | Bottom tab bar (4 tabs) | Bottom tab bar (expanded labels) | Left sidebar (always visible) |
| Dashboard cards | Horizontal scroll, 2 visible | 3 visible, no scroll | 5 in row, no scroll |
| Employee list | Simplified cards (name, time, status) | Cards with more details | Full data table with columns |
| Filters | Stacked chips, collapsible | Single row chips | Inline with search bar |
| Regularization form | Bottom sheet wizard (3 steps) | Bottom sheet (2 steps: reason+times together) | Side panel (all fields visible) |
| Télétravail calendar | Full-width calendar | Calendar + side panel for form | Calendar left, detail right |
| Reports | Horizontal scroll table, 3 col visible | 5 col visible | Full table, all columns |
| QR code display | Full-width card | Centered card, 50% width | Centered card, 33% width |
| Approval cards | Full-width stacked | 2-column grid | 3-column grid or table view |
| Scanner | Full-screen | Full-screen | Centered modal (60% width) |
5.3 Enterprise-Specific Desktop Enhancements¶
| Feature | Description |
|---|---|
| Keyboard shortcuts | S = search, F = filter, R = refresh, E = export, N = new. Keyboard shortcut legend in ? modal. |
| Batch operations | Checkbox column on tables. Select all/page. Batch approve regularizations. |
| Advanced filters | Date range picker, department multi-select, site multi-select, status multi-select, overtime threshold. Saved filter presets. |
| Data table features | Sortable columns (click header), resizable columns (drag border), column visibility toggle, frozen first column on scroll. |
| Right-click context menu | On employee row: View detail, Create regularization, Assign schedule, View report. |
| Split-view | Dashboard can split: list left, detail right (no page navigation). |
| CSV/Excel/PDF export | Available on every table/report. PDF includes company header and signature line. |
| Density toggle | Compact / Comfortable / Spacious (Papillon locked to Spacious). |
6. Offline Behavior¶
6.1 Offline Capability Matrix¶
| Feature | Offline Capability | Sync Strategy |
|---|---|---|
| QR Scanning | ✅ Full — validates against cached tokens | FIFO queue, sync within 30s of reconnection |
| Clock event recording | ✅ Full — stored in IndexedDB | Background sync, exponential backoff on failure |
| View own attendance history | ✅ Read — cached data from last sync | Auto-refresh on reconnect |
| Regularization request | ✅ Full — draft and submit offline | Queue with createdAt from device clock |
| Télétravail request | ✅ Full — draft and submit offline | Queue with createdAt from device clock |
| Dashboard (HR) | ⚠️ Partial — shows cached data | "Dernière sync: HH:MM" indicator. No real-time updates. |
| Reports | ⚠️ Partial — cached summaries only | Full report requires server for generation |
| Site management | ❌ Read-only — view cached sites, download cached QR | Create/edit requires server |
| Schedule management | ❌ Read-only — view cached schedules | Create/edit requires server |
| Approvals | ✅ Full — approve/reject queued | Queue with actionAt from device clock |
| QR regeneration | ❌ Requires server | N/A |
6.2 Sync Indicator States¶
┌─────────────────────────────────────────┐
│ State │ Visual │
├──────────────┼───────────────────────────┤
│ Online │ ● vert (subtle, top bar) │
│ Syncing │ ● amber pulsing │
│ Offline │ ● gris + banner amber │
│ Sync failed │ ● rouge + message d'erreur│
│ Queue count │ "3 pointages en attente" │
└─────────────────────────────────────────┘
6.3 Sync Conflict Resolution¶
Scenario: Employee submits regularization offline. Meanwhile, HR creates a direct regularization for the same day online.
Resolution UI:
┌─────────────────────────┐
│ ⚠ Conflit détecté │
│ │
│ Votre demande │
│ ┌───────────────────┐ │
│ │ Mer 03/03 │ │
│ │ Arrivée: 08:00 │ │
│ │ Départ: 17:30 │ │
│ │ Raison: Oubli │ │
│ └───────────────────┘ │
│ │
│ Modification RH │
│ ┌───────────────────┐ │
│ │ Mer 03/03 │ │
│ │ Arrivée: 08:00 │ │
│ │ Départ: 18:00 │ │
│ │ Par: Mme OUATTARA │ │
│ └───────────────────┘ │
│ │
│ ┌───────────────────┐ │
│ │ Garder la version │ │ ← Primary
│ │ RH (recommandé) │ │
│ └───────────────────┘ │
│ ┌───────────────────┐ │
│ │ Garder ma version │ │ ← Secondary
│ └───────────────────┘ │
│ │
└─────────────────────────┘
6.4 Offline Data Prefetch Strategy¶
On every successful sync, prefetch: - Employee's own attendance history (current month + previous month) - Tenant's site/token pairs (for QR validation) - Employee's schedule assignment - Public holiday calendar (current year) - Pending approval count (managers/HR) - Company non-working days
Storage budget: ~5 MB per employee (30 days × attendance records + site data + schedules).
7. French Micro-copy¶
7.1 Navigation & Headers¶
| Key | Text |
|---|---|
nav.clockIn |
Pointage |
nav.dashboard |
Tableau de bord |
nav.history |
Historique |
nav.more |
Plus |
header.dailyDashboard |
Tableau de bord |
header.myHistory |
Mon historique |
header.sites |
Sites de pointage |
header.schedules |
Horaires de travail |
header.reports |
Rapports |
header.config |
Configuration |
header.approvals |
Demandes en attente |
header.teletravail |
Télétravail |
7.2 Clock Events¶
| Key | Text |
|---|---|
clock.scanPrompt |
Placez le QR code dans le cadre |
clock.cameraLoading |
Démarrage de la caméra... |
clock.success |
Pointage enregistré |
clock.arrival |
Arrivée |
clock.departure |
Départ |
clock.breakOut |
Début de pause |
clock.breakIn |
Fin de pause |
clock.synced |
Synchronisé |
clock.pendingSync |
En attente de synchronisation |
clock.duplicate |
Pointage déjà enregistré à {time} |
clock.invalidQR |
QR code invalide. Contactez les RH. |
clock.accountDisabled |
Compte désactivé — contactez les RH |
clock.offlineQR |
QR code non reconnu hors ligne. Réessayez en ligne. |
clock.syncFailed |
Pointage du {datetime} n'a pas pu être synchronisé. Contactez les RH. |
7.3 Statuses¶
| Key | Text |
|---|---|
status.present |
Présent |
status.late |
En retard |
status.absent |
Absent |
status.absentUnjustified |
Absent sans justification |
status.absentPending |
Absent en attente de validation |
status.teletravail |
Télétravail |
status.onLeave |
En congé |
status.publicHoliday |
Jour férié |
status.nonWorkingDay |
Jour non travaillé |
status.earlyDeparture |
Départ anticipé |
status.incomplete |
Pointage incomplet |
status.autoClosed |
Fermeture automatique |
status.regularized |
Régularisé |
7.4 Dashboard¶
| Key | Text |
|---|---|
dashboard.present |
Présents |
dashboard.late |
En retard |
dashboard.absent |
Absents |
dashboard.teletravail |
Télétravail |
dashboard.onLeave |
En congé |
dashboard.searchPlaceholder |
Rechercher un employé |
dashboard.filterDepartment |
Département |
dashboard.filterSite |
Site |
dashboard.filterStatus |
Statut |
dashboard.lastSync |
Dernière mise à jour : {time} |
dashboard.vsYesterday |
vs. hier |
dashboard.anomalySharedDevice |
Alerte : appareil partagé |
dashboard.anomalyAutoClose |
Pointage incomplet (fermeture automatique) |
dashboard.anomalyNoSchedule |
Pas d'horaire configuré pour {name} |
7.5 Regularization¶
| Key | Text |
|---|---|
reg.title |
Demander une régularisation |
reg.directTitle |
Régularisation directe |
reg.reasonLabel |
Quelle est la raison ? |
reg.reasonForgot |
Oubli de pointage |
reg.reasonTechnical |
Problème technique |
reg.reasonMission |
Mission extérieure |
reg.reasonOther |
Autre |
reg.reasonDetailLabel |
Précisez la raison |
reg.clockInLabel |
Heure d'arrivée |
reg.clockOutLabel |
Heure de départ |
reg.submit |
Confirmer |
reg.success |
Demande envoyée |
reg.successHR |
Régularisation enregistrée |
reg.managerAndHRNotified |
Votre manager et les RH seront notifiés. |
reg.employeeNotified |
L'employé sera notifié de la correction. |
reg.oneTimeRequired |
Indiquez au moins une heure corrigée. |
7.6 Télétravail¶
| Key | Text |
|---|---|
tele.title |
Demande de télétravail |
tele.selectDate |
Sélectionnez une date |
tele.reasonLabel |
Raison |
tele.reasonRequired |
Raison obligatoire pour les demandes de dernière minute |
tele.reasonOptional |
Raison (optionnelle) |
tele.weeklyLimit |
Limite de {count} jour(s)/semaine atteinte |
tele.monthlyLimit |
Limite de {count} jour(s)/mois atteinte |
tele.limitWarning |
Votre demande sera soumise à validation. |
tele.submit |
Envoyer la demande |
tele.success |
Demande soumise |
tele.cancel |
Annuler la demande |
tele.cancelConfirm |
Êtes-vous sûr de vouloir annuler cette demande ? |
7.7 Approvals¶
| Key | Text |
|---|---|
approval.approve |
Approuver |
approval.reject |
Refuser |
approval.approved |
Approuvé |
approval.rejected |
Refusé |
approval.rejectReasonLabel |
Motif du refus |
approval.overrideTitle |
Modifier la décision |
approval.overrideWarning |
Cette régularisation a été approuvée par {manager}. Souhaitez-vous l'annuler ? |
approval.undoToast |
Action annulée |
approval.undoTimer |
Annuler ({seconds}s) |
7.8 Reports¶
| Key | Text |
|---|---|
report.monthly |
Rapport mensuel |
report.overtime |
Rapport heures supplémentaires |
report.department |
Résumé département |
report.exportExcel |
Exporter Excel |
report.exportCSV |
Exporter CSV |
report.totalWorked |
Total travaillé |
report.totalOvertime |
Total heures supp. |
report.totalLate |
Total retards |
report.totalAbsences |
Total absences |
report.attendanceRate |
Taux d'assiduité |
report.band1 |
Tranche 1 (41e-46e h) |
report.band2 |
Tranche 2 (47e-48e h) |
report.band3 |
Tranche 3 (au-delà de 48h) |
report.night |
Heures de nuit |
report.sundayHoliday |
Dimanche et jours fériés |
7.9 Sites & Schedules¶
| Key | Text |
|---|---|
site.title |
Sites de pointage |
site.new |
Nouveau site |
site.nameLabel |
Nom du site |
site.addressLabel |
Adresse (optionnelle) |
site.qrActive |
QR actif depuis {date} |
site.viewQR |
Voir le QR code |
site.downloadQR |
Télécharger |
site.printQR |
Imprimer |
site.regenerateQR |
Régénérer le QR code |
site.regenerateWarning |
L'ancien QR code sera invalidé. Vous devrez imprimer et afficher le nouveau. Continuer ? |
site.duplicateName |
Un site avec ce nom existe déjà. |
schedule.title |
Horaires de travail |
schedule.new |
Nouvel horaire |
schedule.nameLabel |
Nom de l'horaire |
schedule.workingDay |
Jour travaillé |
schedule.startTime |
Heure de début |
schedule.endTime |
Heure de fin |
schedule.breakStart |
Début de pause |
schedule.breakEnd |
Fin de pause |
schedule.breakTracking |
Suivi des pauses (4 pointages/jour) |
schedule.applyToAll |
Appliquer à tous les jours |
schedule.assign |
Assigner à un employé ou département |
7.10 Onboarding & Compliance¶
| Key | Text |
|---|---|
onboarding.step |
Étape {current} / {total} |
onboarding.complianceTitle |
Information légale |
onboarding.complianceText |
La mise en place d'un système de pointage électronique doit faire l'objet d'une consultation des délégués du personnel (Art. 16.1 Code du Travail). |
onboarding.consultationDone |
Oui, consultation effectuée |
onboarding.consultationDate |
Date de la consultation |
onboarding.consultationPV |
Joindre le PV (optionnel) |
onboarding.smallCompanyNote |
Cette obligation concerne les entreprises de 11 salariés et plus. |
onboarding.continue |
Continuer |
onboarding.createFirstSite |
Créez votre premier site |
onboarding.createFirstSchedule |
Définissez un horaire de travail |
onboarding.done |
Module prêt ! |
onboarding.doneText |
Le pointage QR est activé. Imprimez le QR code et affichez-le sur vos sites. |
7.11 Offline & Errors¶
| Key | Text |
|---|---|
offline.banner |
Hors ligne — vos pointages seront synchronisés |
offline.lastSync |
Dernière synchronisation : {datetime} |
offline.queueCount |
{count} élément(s) en attente de synchronisation |
offline.savedLocally |
Sauvegardé localement |
offline.onlineRequired |
Disponible en ligne uniquement |
error.generic |
Une erreur est survenue. Réessayez. |
error.networkFailed |
Impossible de se connecter au serveur. |
error.retry |
Réessayer |
error.loadFailed |
Impossible de charger les données. |
greeting.morning |
Bonjour, {name} |
greeting.afternoon |
Bon après-midi, {name} |
greeting.evening |
Bonsoir, {name} |
8. Component Specifications¶
8.1 Existing Components (from design system)¶
| Component | Usage in Module | Variant |
|---|---|---|
Button |
All CTAs, approve/reject | variant=primary size=lg (scanner CTA), variant=success (approve), variant=danger (reject) |
Card |
Dashboard status cards, employee rows, site cards | variant=elevated (status cards), variant=flat (list items) |
Badge |
Status indicators, anomaly flags, pending count | variant=success (présent), variant=warning (retard), variant=danger (absent), variant=info (télétravail) |
BottomSheet |
Regularization wizard, confirmations | variant=stepped (multi-step), variant=simple (confirmations) |
TextField |
Form inputs | variant=outlined, size=lg (mobile) |
Select |
Filters (department, site, status) | variant=chip (filters), variant=dropdown (forms) |
Toast |
Success/error messages, undo | variant=success, variant=error, variant=undo (with timer) |
SkeletonLoader |
All loading states | variant=card, variant=row, variant=text |
EmptyState |
No data scenarios | variant=onboarding (with CTA), variant=info (without CTA) |
SyncIndicator |
Global sync status | Persistent in top bar |
OfflineBanner |
Offline notification | Persistent below top bar |
DataTable |
Enterprise table views | With sorting, pagination, column management |
SidePanel |
Desktop forms, detail views | variant=form, variant=detail |
Calendar |
Télétravail date picker | With dot indicators |
8.2 New Components¶
QRScanner¶
Purpose: Full-screen camera QR code scanner with visual feedback.
| Prop | Type | Description |
|---|---|---|
onScan |
(payload: QRPayload) => void |
Callback when QR is successfully decoded |
onError |
(error: ScanError) => void |
Callback on scan error |
isOffline |
boolean |
Shows offline indicator |
torchEnabled |
boolean |
Controls flashlight |
States: initializing | ready | scanning | success | error
Accessibility:
- role="application" on scanner container
- aria-label="Scanner de QR code" on viewfinder
- aria-live="assertive" on result announcement
- Torch button: aria-label="Activer/désactiver la lampe torche"
- Screen reader announces: "Pointage enregistré à {time}" on success
Motion: - Frame corners: continuous amber pulse (1.5s cycle, ease-in-out) - On QR detection: corners snap to QR boundary (200ms, spring) - Success: warm gradient fade-in (300ms) + checkmark scale bounce (300ms) + time fade-in (200ms, 50ms stagger) - Error: shake animation (3x, 200ms each, translateX ±10px)
ClockConfirmation¶
Purpose: Full-screen success/error display after scan.
| Prop | Type | Description |
|---|---|---|
type |
'success' \| 'error' \| 'duplicate' \| 'disabled' |
Result type |
time |
string |
Display time (HH:MM) |
eventType |
'IN' \| 'OUT' |
Clock-in or clock-out |
siteName |
string |
Site name for display |
isSynced |
boolean |
Whether event was synced |
autoDismissMs |
number |
Auto-dismiss delay (default 2000) |
onDismiss |
() => void |
Callback on dismiss |
Accessibility:
- role="alert" for error states
- role="status" for success states
- Auto-focus to result announcement
- aria-live="assertive" on result text
StatusSummaryCard¶
Purpose: Dashboard KPI card showing count + label + trend.
| Prop | Type | Description |
|---|---|---|
count |
number |
Primary metric |
label |
string |
Status label |
trend |
{ direction: 'up' \| 'down' \| 'equal', value: number } |
Optional vs-yesterday trend |
color |
'success' \| 'warning' \| 'danger' \| 'info' \| 'muted' |
Status color |
onClick |
() => void |
Optional filter shortcut |
Accessibility:
- role="button" when clickable (filters by status)
- aria-label="{count} employés {label}" (e.g., "23 employés présents")
ApprovalCard¶
Purpose: Swipeable card for pending approval actions.
| Prop | Type | Description |
|---|---|---|
request |
RegularizationRequest \| TeletravailRequest |
Request data |
requestType |
'regularization' \| 'teletravail' |
Type |
onApprove |
(id: string) => void |
Approve callback |
onReject |
(id: string, reason?: string) => void |
Reject callback |
swipeable |
boolean |
Enable swipe gestures (mobile) |
Accessibility:
- role="article" with aria-label="Demande de {type} de {name}"
- Approve/reject buttons with clear labels
- Swipe gestures have button alternatives
OnboardingWizard¶
Purpose: Multi-step module activation wizard.
| Prop | Type | Description |
|---|---|---|
steps |
WizardStep[] |
Array of step configurations |
currentStep |
number |
Active step index |
onComplete |
() => void |
Callback when all steps done |
canSkipStep |
(step: number) => boolean |
Whether a step can be skipped |
Accessibility:
- Progress bar: role="progressbar" with aria-valuenow, aria-valuemin, aria-valuemax
- Step navigation announced to screen readers
- Focus management: auto-focus first interactive element in each step
9. Brand Compliance Checklist¶
9.1 Papillon HR Suite¶
| Requirement | Status | Implementation |
|---|---|---|
| Amber/gold primary (#F59E0B) | ✅ | Scanner frame pulse, CTAs, active states, status cards accents |
| Mobile-first 360px | ✅ | All wireframes designed at 360px first |
| Offline states for all writes | ✅ | Clock events, regularizations, télétravail requests, approvals — all work offline |
| 48px touch targets | ✅ | All buttons, cards, radio buttons, checkboxes meet 48px minimum |
| Warm French copy | ✅ | Greeting by name, encouraging empty states, non-technical error messages |
| Loading skeletons | ✅ | Every screen has skeleton loading state — no spinners |
| Generous whitespace | ✅ | Single-column mobile, card-based layouts with 16px+ gaps |
| Celebration animations | ✅ | Clock-in success: scale bounce + amber pulse ring. Approval: card slide-out. |
| Warm gradient backgrounds | ✅ | Scanner success screen, onboarding wizard header, dashboard card accents |
| Dark mode support | ✅ | All color references use semantic tokens (not hardcoded). Dark mode inverts to warm dark amber tones. |
| 16px body minimum | ✅ | Body text 16px, labels 14px min, headings 20-32px |
| Distinctive heading font | ✅ | Display/heading font: warm serif or semi-serif (NOT Inter for headings). Body: warm sans-serif. |
9.2 ALTARYS ENTERPRISE HR Suite¶
| Requirement | Status | Implementation |
|---|---|---|
| Navy/corporate primary (#1E3A5F) | ✅ | Sidebar, headers, primary buttons |
| Desktop-first 1440px | ✅ | Enterprise wireframe designed at 1440px |
| Information density | ✅ | Full data tables, 5 KPI cards in row, compact list rows |
| Batch operations | ✅ | Checkbox column, select all, batch approve, batch export |
| Keyboard shortcuts | ✅ | S (search), F (filter), R (refresh), E (export), N (new), ? (help) |
| Advanced filters | ✅ | Multi-select departments, sites, statuses. Date range. Saved presets. |
| CSV/Excel/PDF export | ✅ | All reports and table views exportable in 3 formats |
| Right-click context menus | ✅ | Employee rows, table cells |
| Sortable/resizable tables | ✅ | Click header to sort, drag border to resize, column visibility toggle |
| Split-view layouts | ✅ | Dashboard: list left, detail right |
| Density toggle | ✅ | Compact / Comfortable / Spacious |
| Comparison trends (vs. yesterday) | ✅ | KPI cards show ▲/▼/= trend indicators |
Motion Choreography Summary¶
Screen Entrance Animations¶
| Screen | Animation | Duration | Stagger |
|---|---|---|---|
| Dashboard | Status cards slide up + fade | 300ms | 50ms between cards |
| Employee list | Rows fade in from bottom | 200ms | 30ms between rows |
| Scanner | Viewfinder corners animate from center outward | 400ms | — |
| Scanner success | Gradient background + check + time (sequenced) | 300+300+200ms | Sequential |
| Bottom sheet | Slide up from bottom edge | 300ms | ease-out |
| Side panel (desktop) | Slide in from right edge | 250ms | ease-out |
| Approval card removal | Slide out + height collapse | 300ms + 200ms | Sequential |
| Onboarding wizard step | Current slides left, new slides from right | 300ms | ease-in-out |
Loading States¶
| Element | Loading Treatment |
|---|---|
| Dashboard cards | Skeleton shimmer (warm amber undertone) |
| Employee list rows | Skeleton shimmer with name/time/badge placeholders |
| Calendar | Skeleton shimmer on calendar grid |
| Report table | Skeleton shimmer on table cells |
| QR code image | Skeleton shimmer on square placeholder |
Background & Depth¶
| Element | Background Treatment |
|---|---|
| Scanner screen | Full-bleed camera view, no chrome |
| Scanner success | Warm gradient: off-white → subtle amber → off-white (3 stops) |
| Dashboard | Warm off-white background with subtle gradient |
| Cards (resting) | Warm shadow: 0 2px 8px rgba(245,158,11,0.08) |
| Cards (hover/press) | Elevated shadow: 0 4px 16px rgba(245,158,11,0.15) |
| Bottom sheets | Frosted glass effect on overlay (backdrop-blur) |
| Enterprise sidebar | Deep navy gradient (top to bottom), subtle shine |
End of QR Attendance Design Specification