sistemato deeplinking alla serviceformscreen, aggiunto logout e sistemate altre cose
This commit is contained in:
@@ -41,7 +41,7 @@ class CustomerCubit extends Cubit<CustomerState> {
|
||||
Future<void> createCustomer(CustomerModel customer) async {
|
||||
emit(state.copyWith(status: CustomerStatus.loading));
|
||||
try {
|
||||
final newCustomer = await _repository.createCustomer(customer);
|
||||
final newCustomer = await _repository.saveCustomer(customer);
|
||||
|
||||
// Aggiorniamo la lista locale aggiungendo il nuovo cliente in cima
|
||||
final updatedList = List<CustomerModel>.from(state.customers)
|
||||
@@ -128,6 +128,29 @@ class CustomerCubit extends Cubit<CustomerState> {
|
||||
});
|
||||
}
|
||||
|
||||
Future<CustomerModel?> quickCreateCustomer({
|
||||
required String name,
|
||||
String? phone,
|
||||
String? email,
|
||||
}) async {
|
||||
final newCustomer = CustomerModel(
|
||||
nome: name,
|
||||
telefono: phone ?? '',
|
||||
email: email ?? '',
|
||||
companyId: _sessionBloc.state.company!.id,
|
||||
note: '',
|
||||
);
|
||||
|
||||
try {
|
||||
final saved = await _repository.saveCustomer(newCustomer);
|
||||
// Lo aggiungiamo in cima ai suggerimenti
|
||||
emit(state.copyWith(customers: [saved, ...state.customers]));
|
||||
return saved;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Pulizia della memoria quando il Cubit viene distrutto
|
||||
@override
|
||||
Future<void> close() {
|
||||
|
||||
@@ -10,16 +10,16 @@ class CustomerRepository {
|
||||
final SupabaseClient _client = GetIt.I<SupabaseClient>();
|
||||
|
||||
// Crea un nuovo cliente
|
||||
Future<CustomerModel> createCustomer(CustomerModel customer) async {
|
||||
Future<CustomerModel> saveCustomer(CustomerModel customer) async {
|
||||
try {
|
||||
final response = await _client
|
||||
.from('customer')
|
||||
.insert(customer.toJson())
|
||||
.upsert(customer.toJson())
|
||||
.select()
|
||||
.single();
|
||||
return CustomerModel.fromJson(response);
|
||||
} catch (e) {
|
||||
throw 'Errore durante la creazione del cliente: $e';
|
||||
throw 'Errore durante il salvataggio del cliente: $e';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flux/features/customers/blocs/customer_cubit.dart';
|
||||
import 'package:flux/features/customers/models/customer_model.dart';
|
||||
import 'package:flux/features/customers/ui/quick_customer_dialog.dart';
|
||||
import 'package:flux/features/services/blocs/services_cubit.dart';
|
||||
|
||||
class CustomerSearchSheet extends StatefulWidget {
|
||||
@@ -86,18 +88,29 @@ class _CustomerSearchSheetState extends State<CustomerSearchSheet> {
|
||||
// --- TASTO NUOVO CLIENTE ---
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
child: OutlinedButton.icon(
|
||||
onPressed: () {
|
||||
// TODO: Naviga alla pagina "Crea Cliente".
|
||||
},
|
||||
child: IconButton(
|
||||
icon: const Icon(Icons.person_add),
|
||||
label: const Text("Crea Nuovo Cliente"),
|
||||
style: OutlinedButton.styleFrom(
|
||||
padding: const EdgeInsets.symmetric(vertical: 12),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
),
|
||||
onPressed: () async {
|
||||
final servicesCubit = context.read<ServicesCubit>();
|
||||
// Apriamo la dialog passando la query attuale
|
||||
final CustomerModel? nuovoCliente = await showDialog(
|
||||
context: context,
|
||||
builder: (context) => QuickCustomerDialog(
|
||||
initialQuery: _searchController.text,
|
||||
),
|
||||
);
|
||||
|
||||
if (nuovoCliente != null) {
|
||||
servicesCubit.updateField(
|
||||
customerId: nuovoCliente.id,
|
||||
customerDisplayName: nuovoCliente.nome,
|
||||
);
|
||||
|
||||
setState(() {
|
||||
_searchController.clear();
|
||||
});
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
|
||||
117
lib/features/customers/ui/quick_customer_dialog.dart
Normal file
117
lib/features/customers/ui/quick_customer_dialog.dart
Normal file
@@ -0,0 +1,117 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flux/features/customers/blocs/customer_cubit.dart';
|
||||
|
||||
class QuickCustomerDialog extends StatefulWidget {
|
||||
final String initialQuery;
|
||||
|
||||
const QuickCustomerDialog({super.key, required this.initialQuery});
|
||||
|
||||
@override
|
||||
State<QuickCustomerDialog> createState() => _QuickCustomerDialogState();
|
||||
}
|
||||
|
||||
class _QuickCustomerDialogState extends State<QuickCustomerDialog> {
|
||||
late final TextEditingController _nameCtrl;
|
||||
final _phoneCtrl = TextEditingController();
|
||||
final _emailCtrl = TextEditingController();
|
||||
final _noteCtrl = TextEditingController();
|
||||
|
||||
bool _isLoading = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
// Prendiamo tutta la stringa nuda e cruda!
|
||||
_nameCtrl = TextEditingController(text: widget.initialQuery.trim());
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_nameCtrl.dispose();
|
||||
_phoneCtrl.dispose();
|
||||
_emailCtrl.dispose();
|
||||
_noteCtrl.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Future<void> _save() async {
|
||||
final NavigatorState navigator = Navigator.of(context);
|
||||
if (_nameCtrl.text.isEmpty) return;
|
||||
|
||||
setState(() => _isLoading = true);
|
||||
|
||||
// Chiamata al Cubit (aggiorna i parametri in base a come li hai definiti)
|
||||
final newCustomer = await context.read<CustomerCubit>().quickCreateCustomer(
|
||||
name: _nameCtrl.text.trim(),
|
||||
phone: _phoneCtrl.text.trim(),
|
||||
// Aggiungi questi se li hai inseriti nel tuo CustomerCubit:
|
||||
// email: _emailCtrl.text.trim(),
|
||||
// note: _noteCtrl.text.trim(),
|
||||
);
|
||||
|
||||
setState(() => _isLoading = false);
|
||||
|
||||
if (context.mounted) {
|
||||
navigator.pop(newCustomer); // Restituiamo il cliente creato
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: const Text("Nuovo Cliente Rapido"),
|
||||
content: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
TextField(
|
||||
controller: _nameCtrl,
|
||||
autofocus: true, // Focus immediato!
|
||||
decoration: const InputDecoration(
|
||||
labelText: "Nome / Ragione Sociale *",
|
||||
),
|
||||
textInputAction: TextInputAction.next,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
TextField(
|
||||
controller: _phoneCtrl,
|
||||
decoration: const InputDecoration(labelText: "Telefono"),
|
||||
keyboardType: TextInputType.phone,
|
||||
textInputAction: TextInputAction.next,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
TextField(
|
||||
controller: _emailCtrl,
|
||||
decoration: const InputDecoration(labelText: "Email"),
|
||||
keyboardType: TextInputType.emailAddress,
|
||||
textInputAction: TextInputAction.next,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
TextField(
|
||||
controller: _noteCtrl,
|
||||
decoration: const InputDecoration(labelText: "Note rapide"),
|
||||
maxLines: 2,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
child: const Text("Annulla"),
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: _isLoading ? null : _save,
|
||||
child: _isLoading
|
||||
? const SizedBox(
|
||||
width: 16,
|
||||
height: 16,
|
||||
child: CircularProgressIndicator(strokeWidth: 2),
|
||||
)
|
||||
: const Text("Salva e Usa"),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user