refactor(marketing): reproduit fidèlement DashboardHolographique de dictai-narrative.tsx (6 modes uniques + auto-cycle 900ms)

Remplace la section "Comment ça marche" (réacteur orbital générique du commit
03f6e56) par une reproduction fidèle du composant DashboardHolographique
défini dans Website-Sanity/components/sections/dictai-narrative.tsx.

Architecture : container "phone" central (border-radius 44px, color tinting
selon feature active) + 6 modes uniques (Transcription upload+words,
Diarisation conversation Sophie/Marc/Julie, 99+ langues grille staggered,
Exports 7 file icons, Users avatars 1→20, Share folders+tags+files) +
IA Mistral 7B premium card + grid 3 cols × 6 features cliquables.

Auto-cycle 900 ms (1→6→1, skip IA index 0) avec click manuel → isManual
pendant 4500 ms puis reprise auto. Animations Framer Motion → CSS
keyframes + Alpine setInterval (preserves prefers-reduced-motion guard,
aria-live, aria-pressed).

Couleurs source spécifiques préservées (#A78BFA #22D3EE #6B9FFF #34D399
#F59E0B) — identifient les features et restent indépendantes de la palette
brand globale b1/b2/b3.

Test test_fonctionnalites_how_it_works_reactor_section adapté à la nouvelle
structure (dictiaDashboard, 5 sub-data fns, 6 modes par signature unique,
IA premium card animations, auto-cycle 900ms / 4500ms manual reset).
This commit is contained in:
Allison
2026-04-29 09:37:09 -04:00
parent 03f6e56f04
commit 7aaedf2cdf
2 changed files with 663 additions and 183 deletions

View File

@@ -132,10 +132,11 @@ def test_fonctionnalites_renders_6_bento_cards():
def test_fonctionnalites_how_it_works_reactor_section():
"""New 'Comment ça marche' interactive reactor section (post-6-features, pre-integrations).
"""'Comment ça marche' interactive section — fidèle reproduction du composant
DashboardHolographique (Website-Sanity/dictai-narrative.tsx).
Validates structure (heading + reactor + spec list + Mistral card), 6 cycling features,
canonical content, and a11y signals (aria-labelledby + aria-live status panel).
Validates structure (phone container + 6 modes + IA Mistral card + 6 feature grid),
auto-cycle + manual click logic, canonical content, and a11y signals.
"""
client = app.test_client()
body = client.get('/fonctionnalites').data.decode('utf-8')
@@ -147,37 +148,58 @@ def test_fonctionnalites_how_it_works_reactor_section():
assert 'en temps réel' in body
assert 'Survolez une fonctionnalité pour voir la machine en action' in body
# 6 cycling features (canonical names)
# 6 cycling features (canonical names — appears in FEATURES JS array)
for feat in ['Transcription', 'Diarisation', '99+ langues', 'Exports',
'Utilisateurs illimités', 'Partage & Classement']:
'Utilisateurs illimités']:
assert feat in body, f"Missing cycling feature: {feat}"
# Partage & Classement (avec & littéral dans le JS)
assert "'Partage & Classement'" in body, "Missing Partage & Classement feature"
# Reactor visual: rings, orbits, wordmark, Auto badge
assert 'reactor-ring' in body and 'ring-outer' in body and 'ring-mid' in body and 'ring-inner' in body
assert 'orbit orbit-1' in body and 'orbit orbit-8' in body, "Missing 8 orbital particles"
assert '>DictIA<' in body, "Missing reactor centre wordmark"
# Phone container : Alpine root + features + Mic pulsing + DictIA logo
assert 'dictiaDashboard()' in body, "Missing dictiaDashboard Alpine root"
assert 'dictia-mic-pulse' in body, "Missing pulsing Mic animation class"
assert 'dictia-logo-nom.png' in body, "Missing DictIA logo image"
# Mistral 7B IA intégrée card with 3 canonical bullets
# 6 modes uniques (chacun a son sub-data function ou sa signature unique)
assert 'trModeData()' in body, "Missing Mode 1 (Transcription) data function"
assert 'reunion-jan14.mp3' in body, "Missing transcription upload filename"
assert 'diaModeData()' in body, "Missing Mode 2 (Diarisation) data function"
assert 'Sophie' in body and 'Marc' in body and 'Julie' in body, "Missing diarisation speakers"
assert 'langModeData()' in body, "Missing Mode 3 (Langues) data function"
assert '99+ langues détectées' in body, "Missing langues subtitle"
assert 'expModeData()' in body, "Missing Mode 4 (Exports) data function"
assert 'usersModeData()' in body, "Missing Mode 5 (Users) data function"
assert 'iaModeData()' in body, "Missing Mode 0 (IA chat) data function"
assert 'MISTRAL 7B · LOCAL' in body, "Missing IA chat header label"
# Mode 6 (Share) : folders + tags + files
assert 'CR-Réunion-Jan14' in body, "Missing share file name"
assert '#Confidentiel' in body, "Missing share tag"
assert 'partage sécurisé' in body, "Missing share footer text"
# IA Mistral 7B premium card avec 3 bullets souveraineté
assert 'Mistral 7B' in body
assert 'IA intégrée' in body
assert 'Données hébergées sur VOS serveurs' in body
assert 'Zéro connexion OpenAI' in body
assert 'Inférence hors-ligne' in body
assert 'ia-ambient-glow' in body, "Missing IA ambient glow animation"
assert 'ia-brain-glow' in body, "Missing IA brain glow animation"
assert 'ia-local-badge' in body, "Missing LOCAL badge pulsing animation"
# Alpine reactor data + auto-cycle + hover/focus stop logic
assert "active: \"Transcription\"" in body
assert 'isHovered' in body
assert 'setActive(feat)' in body
assert 'resumeCycle()' in body
# Hover, focus + blur listeners on each list item
assert '@mouseenter="setActive(feat)"' in body
assert '@mouseleave="resumeCycle()"' in body
assert '@focus="setActive(feat)"' in body
assert '@blur="resumeCycle()"' in body
# Auto-cycle + manual select logic
assert 'startAutoCycle' in body, "Missing auto-cycle function"
assert 'handleManualSelect' in body, "Missing manual select handler"
assert '900' in body, "Missing 900ms cycle interval"
assert '4500' in body, "Missing 4500ms manual reset timer"
# Auto / Manual status text
assert 'Auto' in body, "Missing Auto status indicator"
assert 'Auto reprend bientôt' in body, "Missing manual mode hint"
# Accessibility: aria-live status panel, prefers-reduced-motion guard
assert 'aria-live="polite"' in body
assert 'prefers-reduced-motion' in body, "Reduced-motion guard missing"
assert 'aria-pressed' in body, "Missing aria-pressed on feature buttons"
def test_fonctionnalites_export_formats_section():