import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../providers/database_provider.dart'; import '../dashboard/dashboard_screen.dart'; import 'onboarding_state.dart'; import 'steps/child_step.dart'; import 'steps/pin_step.dart'; import 'steps/rules_step.dart'; import 'steps/welcome_step.dart'; class OnboardingFlow extends ConsumerStatefulWidget { const OnboardingFlow({super.key}); @override ConsumerState createState() => _OnboardingFlowState(); } class _OnboardingFlowState extends ConsumerState { final _pageController = PageController(); bool _isSaving = false; @override void dispose() { _pageController.dispose(); super.dispose(); } void _goTo(int page) { _pageController.animateToPage( page, duration: const Duration(milliseconds: 300), curve: Curves.easeInOut, ); } Future _finish() async { final draft = ref.read(onboardingDraftProvider); if (draft.childName.trim().isEmpty) { _showError('Indiquez le prénom de l\'enfant.'); _goTo(1); return; } if (draft.pin.length < 4) { _showError('Le PIN doit contenir au moins 4 chiffres.'); _goTo(2); return; } if (draft.pin != draft.pinConfirm) { _showError('Les deux PIN ne correspondent pas.'); _goTo(2); return; } setState(() => _isSaving = true); try { final repo = ref.read(onboardingRepositoryProvider); await repo.finish( childName: draft.childName, color: draft.color, pin: draft.pin, importDefaultRules: draft.importDefaultRules, ); ref.invalidate(onboardingCompleteProvider); ref.invalidate(childrenProvider); if (!mounted) return; Navigator.of(context).pushReplacement( MaterialPageRoute(builder: (_) => const DashboardScreen()), ); } catch (e) { _showError('Erreur lors de l\'enregistrement. Réessayez.'); } finally { if (mounted) setState(() => _isSaving = false); } } void _showError(String message) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(message), backgroundColor: Colors.red.shade700), ); } @override Widget build(BuildContext context) { return PageView( controller: _pageController, physics: const NeverScrollableScrollPhysics(), onPageChanged: (_) {}, children: [ WelcomeStep(onNext: () => _goTo(1)), ChildStep( step: 2, onBack: () => _goTo(0), onNext: () { final name = ref.read(onboardingDraftProvider).childName.trim(); if (name.isEmpty) { _showError('Indiquez le prénom de l\'enfant.'); return; } _goTo(2); }, ), PinStep( step: 3, onBack: () => _goTo(1), onNext: () { final draft = ref.read(onboardingDraftProvider); if (draft.pin.length < 4) { _showError('Le PIN doit contenir au moins 4 chiffres.'); return; } if (draft.pin != draft.pinConfirm) { _showError('Les deux PIN ne correspondent pas.'); return; } _goTo(3); }, ), RulesStep( step: 4, isSaving: _isSaving, onBack: () => _goTo(2), onFinish: _finish, ), ], ); } }