import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flux/core/blocs/session/session_cubit.dart'; import 'package:flux/core/utils/validators.dart'; import 'package:flux/features/company/models/company_model.dart'; import 'package:flux/features/master_data/store/models/store_model.dart'; import 'package:flux/features/master_data/staff/models/staff_member_model.dart'; import 'package:flux/features/onboarding/blocs/onboarding_cubit.dart'; // Sostituisci con il percorso corretto della tua FluxTextField import 'package:flux/core/widgets/flux_text_field.dart'; import 'package:flux/features/onboarding/blocs/onboarding_state.dart'; import 'package:flux/features/onboarding/ui/company_onboarding_form.dart'; class OnboardingScreen extends StatefulWidget { const OnboardingScreen({super.key}); @override State createState() => _OnboardingScreenState(); } class _OnboardingScreenState extends State { late PageController _pageController; // --- CHIAVI DEI FORM (Per la validazione indipendente di ogni step) --- final _storeFormKey = GlobalKey(); final _staffFormKey = GlobalKey(); // --- CONTROLLERS: STEP 2 (Store) --- final _storeNameCtrl = TextEditingController(); final _storeAddressCtrl = TextEditingController(); // --- CONTROLLERS: STEP 3 (Staff) --- final _staffFirstNameCtrl = TextEditingController(); final _staffLastNameCtrl = TextEditingController(); final _staffJobTitleCtrl = TextEditingController(); @override void initState() { super.initState(); // Calcoliamo la pagina iniziale in base allo step salvato nel Cubit final initialStep = context.read().state.step; _pageController = PageController(initialPage: _getPageIndex(initialStep)); } @override void dispose() { _pageController.dispose(); _storeNameCtrl.dispose(); _storeAddressCtrl.dispose(); _staffFirstNameCtrl.dispose(); _staffLastNameCtrl.dispose(); _staffJobTitleCtrl.dispose(); super.dispose(); } int _getPageIndex(OnboardingStep step) { switch (step) { case OnboardingStep.company: return 0; case OnboardingStep.store: return 1; case OnboardingStep.staff: return 2; default: return 0; } } @override Widget build(BuildContext context) { return BlocConsumer( // Ascoltiamo i cambi di stato per animare la pagina e mostrare errori listenWhen: (previous, current) => previous.step != current.step || previous.error != current.error, listener: (context, state) { // Gestione Errori if (state.error != null) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(state.error!), backgroundColor: Colors.red), ); } // Se ha finito, non animiamo nulla: il GoRouter prenderà il controllo a breve! if (state.step == OnboardingStep.completed) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text("Configurazione completata! Benvenuto a bordo 🚀"), backgroundColor: Colors.green, ), ); return; } // Animazione cambio pagina if (state.step != OnboardingStep.completed) { final targetPage = _getPageIndex(state.step); if (_pageController.hasClients && _pageController.page?.round() != targetPage) { _pageController.animateToPage( targetPage, duration: const Duration(milliseconds: 600), curve: Curves.easeInOutCubic, // Animazione super fluida ); } } }, builder: (context, state) { return Scaffold( body: SafeArea( child: Stack( children: [ // IL PAGEVIEW CORAZZATO PageView( controller: _pageController, physics: const NeverScrollableScrollPhysics(), // Vietato lo swipe manuale! children: [ CompanyOnboardingForm(state: state), // Step 1: Company _buildStoreForm(context, state), _buildStaffForm(context, state), ], ), // OVERLAY CARICAMENTO if (state.isLoading) Container( color: Colors.black.withValues(alpha: 0.4), child: const Center(child: CircularProgressIndicator()), ), ], ), ), ); }, ); } Widget _buildStoreForm(BuildContext context, OnboardingState state) { return Padding( padding: const EdgeInsets.all(32.0), child: Form( key: _storeFormKey, child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ const Text( "Il tuo Negozio 🏪", style: TextStyle(fontSize: 32, fontWeight: FontWeight.bold), ), const SizedBox(height: 8), const Text( "Dove si trova il tuo punto vendita principale? (Potrai aggiungerne altri in seguito).", style: TextStyle(fontSize: 16, color: Colors.grey), ), const SizedBox(height: 48), FluxTextField( label: 'Nome Negozio (es. Sede Centrale)', controller: _storeNameCtrl, validator: notEmptyValidator, ), const SizedBox(height: 16), FluxTextField( label: 'Indirizzo completo', controller: _storeAddressCtrl, validator: notEmptyValidator, ), const Spacer(), ElevatedButton( style: ElevatedButton.styleFrom( padding: const EdgeInsets.symmetric(vertical: 16), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), ), onPressed: () { if (_storeFormKey.currentState!.validate()) { final newStore = StoreModel.empty().copyWith( nome: _storeNameCtrl.text.trim(), indirizzo: _storeAddressCtrl.text.trim(), ); context.read().saveStore(newStore); } }, child: const Text( "Salva Negozio", style: TextStyle(fontSize: 16), ), ), const SizedBox(height: 16), ], ), ), ); } Widget _buildStaffForm(BuildContext context, OnboardingState state) { return Padding( padding: const EdgeInsets.all(32.0), child: Form( key: _staffFormKey, child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ const Text( "Il tuo Profilo 👤", style: TextStyle(fontSize: 32, fontWeight: FontWeight.bold), ), const SizedBox(height: 8), const Text( "Ultimo step! Crea il tuo profilo operativo per iniziare a usare FLUX.", style: TextStyle(fontSize: 16, color: Colors.grey), ), const SizedBox(height: 48), FluxTextField( label: 'Nome', controller: _staffFirstNameCtrl, validator: notEmptyValidator, ), const SizedBox(height: 16), FluxTextField( label: 'Cognome', controller: _staffLastNameCtrl, validator: notEmptyValidator, ), const SizedBox(height: 16), FluxTextField( label: 'Etichetta Ruolo (es. Titolare, Manager)', controller: _staffJobTitleCtrl, // Il jobTitle può anche essere opzionale, decidi tu! ), const Spacer(), ElevatedButton( style: ElevatedButton.styleFrom( padding: const EdgeInsets.symmetric(vertical: 16), backgroundColor: Colors.black, // O il tuo context.accent foregroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), ), onPressed: () { if (_staffFormKey.currentState!.validate()) { final newStaff = StaffMemberModel.empty().copyWith( name: _staffFirstNameCtrl.text.trim(), jobTitle: _staffJobTitleCtrl.text.trim(), ); context.read().saveStaff(newStaff); } }, child: const Text( "Entra in FLUX", style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), ), ), const SizedBox(height: 16), ], ), ), ); } }