2026-04-10 11:11:55 +02:00
|
|
|
import 'package:flutter/material.dart';
|
2026-05-18 19:20:38 +02:00
|
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
2026-04-10 11:11:55 +02:00
|
|
|
import 'package:flux/core/widgets/flux_text_field.dart';
|
2026-05-18 19:20:38 +02:00
|
|
|
import 'package:flux/features/customers/blocs/customer_form_cubit.dart';
|
2026-04-10 11:11:55 +02:00
|
|
|
import 'package:flux/features/customers/models/customer_model.dart'; // Uso il tuo widget!
|
|
|
|
|
|
|
|
|
|
class CustomerForm extends StatefulWidget {
|
2026-05-18 19:20:38 +02:00
|
|
|
final CustomerModel? customer;
|
|
|
|
|
final String? customerId;
|
2026-04-10 11:11:55 +02:00
|
|
|
|
2026-05-18 19:20:38 +02:00
|
|
|
const CustomerForm({super.key, this.customer, this.customerId});
|
2026-04-10 11:11:55 +02:00
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
State<CustomerForm> createState() => _CustomerFormState();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class _CustomerFormState extends State<CustomerForm> {
|
|
|
|
|
final _formKey = GlobalKey<FormState>();
|
|
|
|
|
|
|
|
|
|
// Controller inizializzati con i dati del cliente (se presenti)
|
2026-05-18 19:20:38 +02:00
|
|
|
final TextEditingController _nomeController = TextEditingController();
|
|
|
|
|
final TextEditingController _telefonoController = TextEditingController();
|
|
|
|
|
final TextEditingController _emailController = TextEditingController();
|
|
|
|
|
final TextEditingController _noteController = TextEditingController();
|
|
|
|
|
bool _isInitialized = false;
|
2026-04-10 11:11:55 +02:00
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
void initState() {
|
|
|
|
|
super.initState();
|
2026-05-18 19:20:38 +02:00
|
|
|
context.read<CustomerFormCubit>().initForm(
|
|
|
|
|
customerId: widget.customerId,
|
|
|
|
|
existingCustomer: widget.customer,
|
2026-04-10 11:11:55 +02:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
void dispose() {
|
|
|
|
|
_nomeController.dispose();
|
|
|
|
|
_telefonoController.dispose();
|
|
|
|
|
_emailController.dispose();
|
|
|
|
|
_noteController.dispose();
|
|
|
|
|
super.dispose();
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-18 19:20:38 +02:00
|
|
|
void _syncTextControllers(CustomerModel customer) {
|
|
|
|
|
if (_nomeController.text.isEmpty) {
|
|
|
|
|
_nomeController.text = customer.name;
|
|
|
|
|
}
|
|
|
|
|
if (_telefonoController.text.isEmpty) {
|
|
|
|
|
_telefonoController.text = customer.phoneNumber;
|
|
|
|
|
}
|
|
|
|
|
if (_emailController.text.isEmpty) {
|
|
|
|
|
_emailController.text = customer.email;
|
|
|
|
|
}
|
|
|
|
|
if (_noteController.text.isEmpty) {
|
|
|
|
|
_noteController.text = customer.note;
|
|
|
|
|
}
|
|
|
|
|
_isInitialized = true;
|
|
|
|
|
}
|
2026-04-10 11:11:55 +02:00
|
|
|
|
2026-05-18 19:20:38 +02:00
|
|
|
void _flushControllersToCubit() {
|
|
|
|
|
context.read<CustomerFormCubit>().updateFields(
|
|
|
|
|
name: _nomeController.text.trim(),
|
|
|
|
|
phoneNumber: _telefonoController.text.trim(),
|
|
|
|
|
email: _emailController.text.trim(),
|
|
|
|
|
note: _noteController.text.trim(),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void _saveCustomer() {
|
|
|
|
|
if (_formKey.currentState!.validate()) {
|
|
|
|
|
_flushControllersToCubit();
|
|
|
|
|
context.read<CustomerFormCubit>().saveCustomer();
|
2026-04-10 11:11:55 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Widget build(BuildContext context) {
|
2026-05-18 19:20:38 +02:00
|
|
|
return BlocConsumer<CustomerFormCubit, CustomerFormState>(
|
|
|
|
|
listenWhen: (previous, current) => previous.status != current.status,
|
|
|
|
|
listener: (context, state) {
|
|
|
|
|
if (state.status == CustomerFormStatus.ready && !_isInitialized) {
|
|
|
|
|
_syncTextControllers(state.customer);
|
|
|
|
|
}
|
|
|
|
|
if (state.status == CustomerFormStatus.success) {
|
|
|
|
|
Navigator.of(context).pop(state.customer);
|
|
|
|
|
} else if (state.status == CustomerFormStatus.failure) {
|
|
|
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
|
|
|
SnackBar(content: Text(state.errorMessage ?? 'Errore sconosciuto')),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
builder: (context, state) {
|
|
|
|
|
return Scaffold(
|
|
|
|
|
appBar: AppBar(
|
|
|
|
|
title: Text(
|
|
|
|
|
state.customer.id == null
|
|
|
|
|
? 'Nuovo Cliente'
|
|
|
|
|
: 'Modifica ${state.customer.name}',
|
2026-04-10 11:11:55 +02:00
|
|
|
),
|
2026-05-18 19:20:38 +02:00
|
|
|
actions: [],
|
|
|
|
|
),
|
|
|
|
|
body: Padding(
|
|
|
|
|
padding: const EdgeInsets.all(8.0),
|
|
|
|
|
child: Form(
|
|
|
|
|
key: _formKey,
|
|
|
|
|
child: SingleChildScrollView(
|
|
|
|
|
child: Column(
|
|
|
|
|
mainAxisSize: MainAxisSize.min,
|
|
|
|
|
children: [
|
|
|
|
|
FluxTextField(
|
|
|
|
|
label: 'Nome Completo',
|
|
|
|
|
autoFocus: true,
|
|
|
|
|
icon: Icons.person_outline,
|
|
|
|
|
controller: _nomeController,
|
|
|
|
|
keyboardType: TextInputType.name,
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(height: 16),
|
|
|
|
|
FluxTextField(
|
|
|
|
|
label: 'Telefono',
|
|
|
|
|
icon: Icons.phone_android_outlined,
|
|
|
|
|
controller: _telefonoController,
|
|
|
|
|
keyboardType: TextInputType.phone,
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(height: 16),
|
|
|
|
|
FluxTextField(
|
|
|
|
|
label: 'Email',
|
|
|
|
|
icon: Icons.alternate_email_outlined,
|
|
|
|
|
controller: _emailController,
|
|
|
|
|
keyboardType: TextInputType.emailAddress,
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(height: 16),
|
|
|
|
|
FluxTextField(
|
|
|
|
|
label: 'Note',
|
|
|
|
|
icon: Icons.notes_outlined,
|
|
|
|
|
controller: _noteController,
|
|
|
|
|
minLines: 3,
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(height: 8),
|
|
|
|
|
SwitchListTile(
|
|
|
|
|
title: const Text('Non disturbare'),
|
|
|
|
|
value: state.customer.doNotDisturb,
|
|
|
|
|
onChanged: (v) => context
|
|
|
|
|
.read<CustomerFormCubit>()
|
|
|
|
|
.updateDoNotDisturb(v),
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(height: 24),
|
|
|
|
|
SizedBox(
|
|
|
|
|
width: double.infinity,
|
|
|
|
|
height: 50,
|
|
|
|
|
child: ElevatedButton(
|
|
|
|
|
onPressed: _saveCustomer,
|
|
|
|
|
style: ElevatedButton.styleFrom(
|
|
|
|
|
backgroundColor: Theme.of(context).primaryColor,
|
|
|
|
|
foregroundColor: Colors.white,
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
child: Text(
|
|
|
|
|
widget.customer == null ? 'SALVA' : 'AGGIORNA',
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
2026-04-10 11:11:55 +02:00
|
|
|
),
|
|
|
|
|
),
|
2026-05-18 19:20:38 +02:00
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
},
|
2026-04-10 11:11:55 +02:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|