|
|
| import React, { useState } from 'react'; |
| import { |
| ChevronRight, |
| ChevronLeft, |
| User, |
| ShieldCheck, |
| ArrowRight, |
| Database, |
| Globe |
| } from 'lucide-react'; |
| import { AppSettings } from '../types'; |
|
|
| interface OnboardingProps { |
| onComplete: (settings: AppSettings) => Promise<void>; |
| } |
|
|
| const Onboarding: React.FC<OnboardingProps> = ({ onComplete }) => { |
| const [step, setStep] = useState(1); |
| const [inspectorName, setInspectorName] = useState(''); |
| const [isFinishing, setIsFinishing] = useState(false); |
|
|
| const totalSteps = 2; |
|
|
| const handleNext = async () => { |
| if (step === 1 && !inspectorName.trim()) { |
| alert("Votre nom d'inspecteur est requis."); |
| return; |
| } |
| if (step < totalSteps) { |
| setStep(step + 1); |
| } else { |
| setIsFinishing(true); |
| await onComplete({ |
| inspectorName, |
| webhookUrl: '', |
| sheetId: '', |
| onboardingComplete: true |
| }); |
| } |
| }; |
|
|
| return ( |
| <div className="fixed inset-0 bg-white z-50 flex flex-col items-center justify-center p-6 sm:p-12 overflow-y-auto"> |
| <div className="max-w-md w-full space-y-12 animate-in fade-in duration-700"> |
| <div className="flex justify-center gap-3"> |
| {[1, 2].map((s) => ( |
| <div |
| key={s} |
| className={`h-2 rounded-full transition-all duration-700 ${ |
| s === step ? 'w-12 bg-indigo-600' : 'w-2 bg-slate-100' |
| }`} |
| /> |
| ))} |
| </div> |
| |
| <div className="min-h-[400px] flex flex-col items-center text-center space-y-8"> |
| {step === 1 && ( |
| <div className="space-y-8 animate-in slide-in-from-bottom-8 duration-500"> |
| <div className="bg-indigo-600 text-white p-8 rounded-[2rem] inline-block shadow-2xl rotate-2"> |
| <User size={56} /> |
| </div> |
| <div className="space-y-4"> |
| <h1 className="text-4xl font-black text-slate-900 tracking-tight">Votre Identité</h1> |
| <p className="text-slate-500 font-bold"> |
| Ce nom figurera sur tous vos rapports. |
| </p> |
| </div> |
| <div className="w-full"> |
| <input |
| type="text" |
| value={inspectorName} |
| onChange={(e) => setInspectorName(e.target.value)} |
| placeholder="Nom & Prénom" |
| className="w-full bg-slate-50 border-4 border-slate-100 rounded-[1.5rem] p-6 text-center text-2xl font-black text-slate-800 focus:border-indigo-600 focus:bg-white outline-none transition-all shadow-inner" |
| autoFocus |
| /> |
| </div> |
| </div> |
| )} |
| |
| {step === 2 && ( |
| <div className="w-full space-y-8 animate-in slide-in-from-right-12 duration-500"> |
| <div className="bg-emerald-500 text-white p-8 rounded-[2rem] inline-block shadow-2xl -rotate-2"> |
| <ShieldCheck size={56} /> |
| </div> |
| <div className="space-y-4"> |
| <h2 className="text-3xl font-black text-slate-900 tracking-tight">Souveraineté Totale</h2> |
| <p className="text-slate-500 font-bold leading-relaxed"> |
| Pas de comptes. Pas de serveurs. Tout reste dans votre navigateur. |
| </p> |
| </div> |
| |
| <div className="grid grid-cols-1 gap-4 pt-4"> |
| <div className="p-6 bg-slate-50 rounded-3xl border border-slate-100 flex items-center gap-5 text-left"> |
| <Database className="text-indigo-600 shrink-0" size={24} /> |
| <div> |
| <h4 className="font-black text-slate-800 text-sm uppercase">Stockage Local</h4> |
| <p className="text-xs text-slate-500 font-bold">Sauvegardez votre Clé (.auditpro) pour ne jamais rien perdre.</p> |
| </div> |
| </div> |
| <div className="p-6 bg-slate-50 rounded-3xl border border-slate-100 flex items-center gap-5 text-left"> |
| <Globe className="text-emerald-500 shrink-0" size={24} /> |
| <div> |
| <h4 className="font-black text-slate-800 text-sm uppercase">Liaison Optionnelle</h4> |
| <p className="text-xs text-slate-500 font-bold">Connectez une Google Sheet pour synchroniser vos rapports.</p> |
| </div> |
| </div> |
| </div> |
| </div> |
| )} |
| </div> |
| |
| <div className="flex gap-4 pt-8"> |
| {step > 1 && !isFinishing && ( |
| <button |
| onClick={() => setStep(step - 1)} |
| className="flex-1 py-5 px-8 rounded-3xl border-2 border-slate-100 text-slate-400 font-black hover:bg-slate-50 transition-all flex items-center justify-center gap-2" |
| > |
| <ChevronLeft size={24} /> |
| </button> |
| )} |
| <button |
| onClick={handleNext} |
| disabled={isFinishing} |
| className={`flex-[3] py-5 px-10 bg-indigo-600 text-white rounded-3xl font-black hover:bg-indigo-700 shadow-2xl transition-all flex items-center justify-center gap-3 group active:scale-95 ${isFinishing ? 'opacity-50 cursor-not-allowed' : ''}`} |
| > |
| {isFinishing ? 'CHARGEMENT...' : (step === totalSteps ? 'CRÉER MON ESPACE' : 'CONTINUER')} |
| {!isFinishing && <ArrowRight size={24} className="group-hover:translate-x-2 transition-transform" />} |
| </button> |
| </div> |
| </div> |
| </div> |
| ); |
| }; |
|
|
| export default Onboarding; |
|
|