2026-04-20 23:52:00 +02:00
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
|
|
|
import 'package:flux/core/blocs/session/session_cubit.dart';
|
|
|
|
|
import 'package:flux/features/onboarding/blocs/onboarding_cubit.dart';
|
|
|
|
|
import 'package:flux/features/onboarding/blocs/onboarding_state.dart';
|
2026-04-21 11:26:42 +02:00
|
|
|
import 'package:flux/features/onboarding/ui/company_onboarding_form.dart';
|
2026-04-22 11:05:01 +02:00
|
|
|
import 'package:flux/features/onboarding/ui/staff_onboarding_form.dart';
|
2026-04-21 19:16:41 +02:00
|
|
|
import 'package:flux/features/onboarding/ui/store_onboarding_form.dart';
|
2026-04-20 23:52:00 +02:00
|
|
|
|
|
|
|
|
class OnboardingScreen extends StatefulWidget {
|
|
|
|
|
const OnboardingScreen({super.key});
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
State<OnboardingScreen> createState() => _OnboardingScreenState();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class _OnboardingScreenState extends State<OnboardingScreen> {
|
|
|
|
|
late PageController _pageController;
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
void initState() {
|
|
|
|
|
super.initState();
|
|
|
|
|
// Calcoliamo la pagina iniziale in base allo step salvato nel Cubit
|
|
|
|
|
final initialStep = context.read<OnboardingCubit>().state.step;
|
|
|
|
|
_pageController = PageController(initialPage: _getPageIndex(initialStep));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
void dispose() {
|
|
|
|
|
_pageController.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<OnboardingCubit, OnboardingState>(
|
|
|
|
|
// 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: [
|
2026-04-22 11:05:01 +02:00
|
|
|
CompanyOnboardingForm(state: state),
|
2026-04-21 19:16:41 +02:00
|
|
|
StoreOnboardingForm(state: state),
|
2026-04-22 11:05:01 +02:00
|
|
|
StaffOnboardingForm(),
|
2026-04-20 23:52:00 +02:00
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
// OVERLAY CARICAMENTO
|
|
|
|
|
if (state.isLoading)
|
|
|
|
|
Container(
|
|
|
|
|
color: Colors.black.withValues(alpha: 0.4),
|
|
|
|
|
child: const Center(child: CircularProgressIndicator()),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|