Files
flux/lib/features/onboarding/ui/onboarding_view.dart
2026-04-20 23:52:00 +02:00

212 lines
6.9 KiB
Dart

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/widgets/flux_text_field.dart';
import 'package:flux/features/onboarding/blocs/onboarding_cubit.dart';
import 'package:flux/features/onboarding/blocs/onboarding_state.dart';
// Importa i tuoi file (cubit, modelli, ecc.)
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();
// Inizializziamo il controller sulla pagina giusta.
// L'indice parte da 0. company=0, store=1, staff=2.
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 solo quando cambia lo step per animare la pagina
listenWhen: (previous, current) => previous.step != current.step,
listener: (context, state) {
if (state.step == OnboardingStep.completed) {
// Il SessionCubit prenderà il controllo e farà il redirect,
// qui potremmo mostrare un bel toast di successo.
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("Configurazione completata! 🚀")),
);
return;
}
final targetPage = _getPageIndex(state.step);
_pageController.animateToPage(
targetPage,
duration: const Duration(milliseconds: 500),
curve: Curves.easeInOut,
);
},
builder: (context, state) {
return Scaffold(
body: SafeArea(
child: Stack(
children: [
// Il PageView disabilita lo scorrimento manuale con NeverScrollableScrollPhysics
PageView(
controller: _pageController,
physics: const NeverScrollableScrollPhysics(),
children: [
_buildCompanyForm(context, state),
_buildStoreForm(context, state),
_buildStaffForm(
context,
state,
), // Qui c'è la magia paranoica
],
),
// Overlay di caricamento universale
if (state.isLoading)
Container(
color: Colors.black.withValues(alpha: 0.5),
child: const Center(child: CircularProgressIndicator()),
),
],
),
),
);
},
);
}
// --- I METODI DEI FORM ---
// (Nella realtà li metterai in file separati o widget custom per pulizia)
Widget _buildCompanyForm(BuildContext context, OnboardingState state) {
// Controller e chiavi del form...
return Padding(
padding: const EdgeInsets.all(24.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const Text(
"Step 1: La tua Azienda",
style: TextStyle(fontSize: 28, fontWeight: FontWeight.bold),
),
const SizedBox(height: 8),
const Text("Inserisci i dati della tua attività."),
const SizedBox(height: 32),
// Esempio usando la tua FluxTextField
FluxTextField(label: 'Ragione Sociale / Nome Azienda'),
const SizedBox(height: 16),
FluxTextField(label: 'Partita IVA'),
const Spacer(),
ElevatedButton(
onPressed: () {
// 1. Valida il form
// 2. Crea il CompanyModel
// 3. Chiama il Cubit:
// context.read<OnboardingCubit>().saveCompany(newCompany);
},
child: const Text("Salva e prosegui"),
),
],
),
);
}
Widget _buildStoreForm(BuildContext context, OnboardingState state) {
return Padding(
padding: const EdgeInsets.all(24.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const Text(
"Step 2: Il primo Negozio",
style: TextStyle(fontSize: 28, fontWeight: FontWeight.bold),
),
const SizedBox(height: 8),
const Text("Dove si trova il tuo punto vendita principale?"),
const SizedBox(height: 32),
FluxTextField(label: 'Nome Negozio (es. Sede Centrale)'),
const SizedBox(height: 16),
FluxTextField(label: 'Indirizzo'),
const Spacer(),
ElevatedButton(
onPressed: () {
// context.read<OnboardingCubit>().saveStore(newStore);
},
child: const Text("Salva Negozio"),
),
],
),
);
}
Widget _buildStaffForm(BuildContext context, OnboardingState state) {
// NOTA PARANOICA: Qui chiediamo jobTitle (Testo libero),
// ma NON diamo modo di scegliere il system_role!
return Padding(
padding: const EdgeInsets.all(24.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const Text(
"Step 3: Il tuo Profilo",
style: TextStyle(fontSize: 28, fontWeight: FontWeight.bold),
),
const SizedBox(height: 8),
const Text("Crea il tuo profilo operativo per iniziare a lavorare."),
const SizedBox(height: 32),
FluxTextField(label: 'Nome'),
const SizedBox(height: 16),
FluxTextField(label: 'Cognome'),
const SizedBox(height: 16),
// TESTO LIBERO! Il cliente ci scrive quello che vuole ("CEO", "Boss", "Stagista")
FluxTextField(label: 'Ruolo / Etichetta (es. Titolare)'),
const Spacer(),
ElevatedButton(
onPressed: () {
// Quando chiami il Cubit, passi i dati della UI.
// Ti ricordi? L'OnboardingCubit forzerà `system_role = SystemRole.admin`
// dietro le quinte!
// context.read<OnboardingCubit>().saveStaff(newStaff);
},
child: const Text("Inizia a usare Flux!"),
),
],
),
);
}
}