import React, { useState, useEffect, useRef } from ‘react’;
import { CheckCircle2, Lock, Download, Eye, X, Save, ChevronRight } from ‘lucide-react’;
const COLORS = {
beige: ‘#E7E2DC’,
taupe: ‘#968A7E’,
noir: ‘#0A0A0A’,
blanc: ‘#FFFFFF’,
beigeLight: ‘#F4F1ED’,
};
const ADMIN_PASSWORD = ‘Celia2026’;
const QUESTIONS = [
{ num: 1, text: « Cite une pensée liée au manque de légitimité que tu pourrais avoir (ou que tu as déjà eue). », help: « Explique précisément pourquoi cette pensée est fausse dans la réalité du métier. » },
{ num: 2, text: « Pourquoi attendre de \ »tout maîtriser\ » avant de te lancer est une erreur dans ce métier ? », help: « Appuie ta réponse sur la réalité du rôle d’une Home Organizer. » },
{ num: 3, text: « Si tu devais expliquer à quelqu’un pourquoi tu es légitime aujourd’hui (même en début de parcours), que dirais-tu ? », help: « Ta réponse doit être concrète et assumée. » },
{ num: 4, text: « Avec tes mots, explique clairement ce qu’est le métier de Home Organizer aujourd’hui. », help: « Ta réponse doit permettre à une personne extérieure de comprendre la vraie valeur de ce métier. » },
{ num: 5, text: « Explique précisément pourquoi le Home Organizing n’est ni du ménage ni simplement du rangement. », help: « » },
{ num: 6, text: « Une cliente te dit : « J’ai juste besoin que quelqu’un vienne ranger chez moi ». En tant que Home Organizer, comment reformules-tu son besoin et quelle approche proposes-tu ? », help: « » },
{ num: 7, text: « Pourquoi l’objectif n’est-il pas d’avoir une maison parfaite mais une maison fonctionnelle ? », help: « Donne une explication + un exemple concret. » },
{ num: 8, text: « Après ton intervention, quel doit être le résultat pour le client dans sa manière de gérer son intérieur ? », help: « » },
{ num: 9, text: « Pourquoi le Home Organizing est-il avant tout un travail avec des personnes et pas uniquement avec des objets ? », help: « Appuie ta réponse sur ce que représente réellement un intérieur. » },
{ num: 10, text: « Quelles émotions une cliente peut-elle ressentir avant de faire appel à une Home Organizer ? », help: « Explique pourquoi ces émotions sont présentes. » },
{ num: 11, text: « Pourquoi peut-on dire que le désordre est souvent lié à un « trop-plein » et non à un manque de capacité ? », help: « Donne une explication claire. » },
{ num: 12, text: « En quoi la posture du Home Organizer est-elle déterminante dans l’accompagnement ? », help: « Explique concrètement ce que cela implique. » },
{ num: 13, text: « Une cliente montre des blocages ou des émotions pendant une séance de tri. Comment réagis-tu en tant que Home Organizer et pourquoi ? », help: « » },
{ num: 14, text: « Une cliente te dit : « J’ai honte de l’état de ma maison ». Quelle est ta réaction immédiate (attitude + mots) pour instaurer un climat de confiance ? », help: « » },
{ num: 15, text: « Quelle est la différence concrète entre accompagner une cliente et imposer une organisation ? », help: « Donne un exemple précis. » },
{ num: 16, text: « Quels sont les 3 piliers de la posture AWL et pourquoi sont-ils essentiels dans l’accompagnement d’une cliente ? », help: « » },
{ num: 17, text: « Pourquoi peut-on dire que le désordre n’est pas le problème, mais un symptôme ? », help: « Ta réponse doit montrer ce qu’il révèle réellement chez la cliente. » },
{ num: 18, text: « Explique le lien entre charge mentale et désordre. », help: « Concrètement, qu’est-ce qui se passe dans le quotidien de la cliente ? » },
{ num: 19, text: « Pourquoi est-il essentiel de comprendre la situation de la cliente avant d’agir sur son espace ? », help: « Explique ce qui peut se passer si ce n’est pas le cas. » },
{ num: 20, text: « Pourquoi une organisation ne peut-elle pas être efficace si elle n’est pas adaptée au logement et à ses contraintes ? », help: « Explique ce que doit analyser une Home Organizer avant de proposer des solutions. » },
{ num: 21, text: « Pourquoi peut-on dire que « le désordre est un langage » ? », help: « Explique ce qu’un Home Organizer doit être capable de comprendre avant d’intervenir. » },
{ num: 22, text: « Pourquoi est-il important de comprendre que certaines situations de désordre relèvent de mécanismes psychologiques et pas seulement d’un manque d’organisation ? », help: « Explique ce que ça change concrètement pour toi. » },
{ num: 23, text: « Pourquoi le tri peut-il être difficile pour une cliente, même si elle veut vraiment changer ? », help: « Appuie ta réponse sur la fatigue décisionnelle ou la charge émotionnelle. » },
{ num: 24, text: « Pourquoi peut-on dire que la santé physique et mentale peut impacter directement la capacité d’une personne à organiser son intérieur ? », help: « Explique le lien entre l’état de la personne et son environnement. » },
{ num: 25, text: « En quoi comprendre l’état de santé général (physique et émotionnel) d’une cliente change-t-il ta manière de l’accompagner en tant que Home Organizer ? », help: « Ta réponse doit montrer une adaptation concrète de ta posture. » },
];
export default function FormulaireAWL() {
const [view, setView] = useState(‘welcome’);
const [name, setName] = useState( »);
const [email, setEmail] = useState( »);
const [answers, setAnswers] = useState(() => Array(25).fill( »));
const [submitting, setSubmitting] = useState(false);
const [saveStatus, setSaveStatus] = useState( »);
const [submissions, setSubmissions] = useState([]);
const [selectedSub, setSelectedSub] = useState(null);
const [adminInput, setAdminInput] = useState( »);
const [loginError, setLoginError] = useState( »);
const [loadingDraft, setLoadingDraft] = useState(true);
const initialLoadDone = useRef(false);
// Charger le brouillon au démarrage
useEffect(() => {
(async () => {
try {
const r = await window.storage.get(‘draft’);
if (r && r.value) {
const d = JSON.parse(r.value);
setName(d.name || »);
setEmail(d.email || »);
setAnswers(d.answers && d.answers.length === 25 ? d.answers : Array(25).fill( »));
}
} catch (e) {}
setLoadingDraft(false);
initialLoadDone.current = true;
})();
}, []);
// Auto-save toutes les secondes après modif
useEffect(() => {
if (!initialLoadDone.current) return;
if (view !== ‘form’) return;
const t = setTimeout(async () => {
try {
await window.storage.set(‘draft’, JSON.stringify({ name, email, answers }));
setSaveStatus(‘Brouillon enregistré’);
setTimeout(() => setSaveStatus( »), 2500);
} catch (e) {}
}, 1000);
return () => clearTimeout(t);
}, [name, email, answers, view]);
const updateAnswer = (i, val) => {
setAnswers(prev => {
const next = […prev];
next[i] = val;
return next;
});
};
const handleSubmit = async () => {
if (!name.trim()) {
alert(‘Merci d\’indiquer ton prénom et ton nom.’);
document.getElementById(‘field-name’)?.focus();
return;
}
if (!email.trim() || !email.includes(‘@’)) {
alert(‘Merci d\’indiquer un email valide.’);
document.getElementById(‘field-email’)?.focus();
return;
}
const missing = answers.findIndex(a => !a.trim());
if (missing !== -1) {
alert(`Il manque la réponse à la question ${missing + 1}.`);
const el = document.getElementById(`q-${missing + 1}`);
if (el) {
el.scrollIntoView({ behavior: ‘smooth’, block: ‘center’ });
const textarea = el.querySelector(‘textarea’);
if (textarea) setTimeout(() => textarea.focus(), 500);
}
return;
}
setSubmitting(true);
try {
const submission = {
name: name.trim(),
email: email.trim(),
answers,
submittedAt: new Date().toISOString(),
};
const slug = name.trim().replace(/\s+/g, ‘_’).replace(/[^a-zA-Z0-9_]/g, »).slice(0, 30);
const key = `submission:${Date.now()}_${slug}`;
await window.storage.set(key, JSON.stringify(submission), true);
try { await window.storage.delete(‘draft’); } catch (e) {}
setView(‘thanks’);
window.scrollTo({ top: 0, behavior: ‘smooth’ });
} catch (e) {
alert(‘Une erreur est survenue lors de l\’envoi. Réessaie dans quelques secondes — tes réponses sont sauvegardées.’);
} finally {
setSubmitting(false);
}
};
const loadSubmissions = async () => {
try {
const list = await window.storage.list(‘submission:’, true);
const keys = (list && list.keys) || [];
const subs = [];
for (const key of keys) {
try {
const r = await window.storage.get(key, true);
if (r && r.value) subs.push({ key, …JSON.parse(r.value) });
} catch (e) {}
}
subs.sort((a, b) => new Date(b.submittedAt) – new Date(a.submittedAt));
setSubmissions(subs);
} catch (e) {
setSubmissions([]);
}
};
const handleLogin = () => {
if (adminInput === ADMIN_PASSWORD) {
setLoginError( »);
setAdminInput( »);
setView(‘admin’);
loadSubmissions();
} else {
setLoginError(‘Mot de passe incorrect.’);
}
};
const exportCSV = () => {
const esc = (v) => ` »${String(v || »).replace(/ »/g, ‘ » »‘)} »`;
const headers = [‘Date’, ‘Prénom Nom’, ‘Email’, …QUESTIONS.map(q => `Q${q.num}`)];
const rows = submissions.map(s => [
esc(new Date(s.submittedAt).toLocaleString(‘fr-FR’)),
esc(s.name),
esc(s.email),
…s.answers.map(esc),
].join(‘,’));
const csv = [headers.map(esc).join(‘,’), …rows].join(‘\n’);
const blob = new Blob([‘\ufeff’ + csv], { type: ‘text/csv;charset=utf-8’ });
const url = URL.createObjectURL(blob);
const a = document.createElement(‘a’);
a.href = url;
a.download = `Reponses_AWL_${new Date().toISOString().split(‘T’)[0]}.csv`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
};
const fontStyle = { fontFamily: « ‘Montserrat’, system-ui, -apple-system, sans-serif » };
const completedCount = answers.filter(a => a.trim().length > 0).length;
const progressPct = Math.round((completedCount / 25) * 100);
// ===== ADMIN VIEW =====
if (view === ‘admin’) {
return (
{completedCount === 25 ? ‘Tu as répondu à toutes les questions.’ : `Il te reste ${25 – completedCount} question${25 – completedCount > 1 ? ‘s’ : »} à compléter.`}
Une fois envoyé, tu ne pourras plus modifier tes réponses.