Files
flux/lib/features/customers/ui/customer_form_screen.dart

194 lines
6.9 KiB
Dart
Raw Normal View History

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';
import 'package:flux/core/widgets/shared_forms/attachments_section.dart';
import 'package:flux/features/attachments/blocs/attachments_bloc.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 CustomerFormScreen extends StatefulWidget {
2026-05-18 19:20:38 +02:00
final CustomerModel? customer;
final String? customerId;
2026-04-10 11:11:55 +02:00
const CustomerFormScreen({super.key, this.customer, this.customerId});
2026-04-10 11:11:55 +02:00
@override
State<CustomerFormScreen> createState() => _CustomerFormScreenState();
2026-04-10 11:11:55 +02:00
}
class _CustomerFormScreenState extends State<CustomerFormScreen> {
2026-04-10 11:11:55 +02:00
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();
// 1. Lanciamo l'inizializzazione (che se è sincrona, finirà istantaneamente)
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
);
// 2. Leggiamo lo stato SUBITO DOPO. Se è già ready, non aspettiamo il listener!
final currentState = context.read<CustomerFormCubit>().state;
if (currentState.status == CustomerFormStatus.ready && !_isInitialized) {
_syncTextControllers(currentState.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 Divider(height: 32),
BlocProvider<AttachmentsBloc>(
create: (context) => AttachmentsBloc(
parentType: AttachmentParentType.customer,
parentId: state.customer.id,
),
child: SharedAttachmentsSection(
parentType: AttachmentParentType.customer,
parentId: state.customer.id,
),
),
2026-05-18 19:20:38 +02:00
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
);
}
}