From 5207a82706d154fd1e4745d9418090b0d9d9ba0f Mon Sep 17 00:00:00 2001 From: Mark M2 Macbook Date: Wed, 6 May 2026 08:58:23 +0200 Subject: [PATCH] rese agnostiche sezioni customer e staff per le form. Inizio di lavoro per rendere agnostico il bloc degli allegati --- lib/core/routes/app_router.dart | 2 +- .../shared_forms}/customer_section.dart | 27 +++++++---------- .../operation_files_section.dart | 2 +- .../widgets/shared_forms}/staff_section.dart | 18 +++++++----- .../blocs/operation_files_bloc.dart | 0 .../blocs/operation_files_events.dart | 0 .../blocs/operation_files_state.dart | 0 .../operations/ui/operation_form_screen.dart | 29 ++++++++++++++----- .../ui/operation_mobile_upload_screen.dart | 2 +- lib/features/tickets/models/ticket_model.dart | 11 +++++++ 10 files changed, 57 insertions(+), 34 deletions(-) rename lib/{features/operations/ui/widgets => core/widgets/shared_forms}/customer_section.dart (89%) rename lib/{features/operations/ui/widgets => core/widgets/shared_forms}/operation_files_section.dart (99%) rename lib/{features/operations/ui/widgets => core/widgets/shared_forms}/staff_section.dart (92%) rename lib/features/{operations => attachments}/blocs/operation_files_bloc.dart (100%) rename lib/features/{operations => attachments}/blocs/operation_files_events.dart (100%) rename lib/features/{operations => attachments}/blocs/operation_files_state.dart (100%) diff --git a/lib/core/routes/app_router.dart b/lib/core/routes/app_router.dart index 6f9ccac..4ad187b 100644 --- a/lib/core/routes/app_router.dart +++ b/lib/core/routes/app_router.dart @@ -24,7 +24,7 @@ import 'package:flux/features/master_data/staff/ui/staff_screen.dart'; import 'package:flux/features/master_data/store/ui/stores_screen.dart'; import 'package:flux/features/onboarding/blocs/onboarding_cubit.dart'; import 'package:flux/features/onboarding/ui/onboarding_screen.dart'; -import 'package:flux/features/operations/blocs/operation_files_bloc.dart'; +import 'package:flux/features/attachments/blocs/operation_files_bloc.dart'; import 'package:flux/features/operations/models/operation_model.dart'; import 'package:flux/features/operations/ui/operation_form_screen.dart'; import 'package:flux/features/operations/ui/operation_mobile_upload_screen.dart'; diff --git a/lib/features/operations/ui/widgets/customer_section.dart b/lib/core/widgets/shared_forms/customer_section.dart similarity index 89% rename from lib/features/operations/ui/widgets/customer_section.dart rename to lib/core/widgets/shared_forms/customer_section.dart index 88ec939..4c1c9ce 100644 --- a/lib/features/operations/ui/widgets/customer_section.dart +++ b/lib/core/widgets/shared_forms/customer_section.dart @@ -1,13 +1,19 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flux/features/customers/blocs/customers_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/operations/blocs/operations_cubit.dart'; import 'package:flux/features/operations/models/operation_model.dart'; class CustomerSection extends StatelessWidget { final OperationModel? currentOp; - const CustomerSection({super.key, required this.currentOp}); + final ValueChanged onCustomerSelected; + + const CustomerSection({ + super.key, + required this.currentOp, + required this.onCustomerSelected, + }); @override Widget build(BuildContext context) { @@ -125,9 +131,6 @@ class CustomerSection extends StatelessWidget { icon: const Icon(Icons.person_add), label: const Text('Crea Nuovo Cliente'), onPressed: () async { - final OperationsCubit operationsCubit = context - .read(); - // APRIAMO LA DIALOG RAPIDA CON LA MAGIA DEL BLOC PROVIDER final newCustomer = await showDialog( context: context, @@ -145,10 +148,7 @@ class CustomerSection extends StatelessWidget { // Se l'ha creato davvero (e non ha premuto annulla)... if (newCustomer != null) { // 1. Aggiorniamo il form delle operazioni - operationsCubit.updateOperationFields( - customerId: newCustomer.id, - customerDisplayName: newCustomer.name, - ); + onCustomerSelected(newCustomer); // 2. Chiudiamo la BottomSheet dei clienti per tornare alla form! if (context.mounted) { @@ -196,14 +196,7 @@ class CustomerSection extends StatelessWidget { '${customer.phoneNumber} • ${customer.email}', ), onTap: () { - // Aggiorniamo il form tramite il Cubit delle operazioni - context - .read() - .updateOperationFields( - customerId: customer.id, // customer.id - customerDisplayName: - customer.name, // customer.name - ); + onCustomerSelected(customer); Navigator.pop(modalContext); }, ); diff --git a/lib/features/operations/ui/widgets/operation_files_section.dart b/lib/core/widgets/shared_forms/operation_files_section.dart similarity index 99% rename from lib/features/operations/ui/widgets/operation_files_section.dart rename to lib/core/widgets/shared_forms/operation_files_section.dart index e7ee5d5..5a0dc36 100644 --- a/lib/features/operations/ui/widgets/operation_files_section.dart +++ b/lib/core/widgets/shared_forms/operation_files_section.dart @@ -7,7 +7,7 @@ import 'package:file_picker/file_picker.dart'; import 'package:flux/features/attachments/data/attachments_repository.dart'; import 'package:flux/features/attachments/ui/attachment_viewer_screen.dart'; import 'package:flux/features/attachments/ui/quick_rename_dialog.dart'; -import 'package:flux/features/operations/blocs/operation_files_bloc.dart'; +import 'package:flux/features/attachments/blocs/operation_files_bloc.dart'; import 'package:get_it/get_it.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:flux/features/operations/models/operation_model.dart'; diff --git a/lib/features/operations/ui/widgets/staff_section.dart b/lib/core/widgets/shared_forms/staff_section.dart similarity index 92% rename from lib/features/operations/ui/widgets/staff_section.dart rename to lib/core/widgets/shared_forms/staff_section.dart index 00967b1..fe705b4 100644 --- a/lib/features/operations/ui/widgets/staff_section.dart +++ b/lib/core/widgets/shared_forms/staff_section.dart @@ -2,16 +2,19 @@ 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/master_data/staff/blocs/staff_cubit.dart'; -import 'package:flux/features/operations/blocs/operations_cubit.dart'; +import 'package:flux/features/master_data/staff/models/staff_member_model.dart'; import 'package:flux/features/operations/models/operation_model.dart'; import 'package:get_it/get_it.dart'; -// IMPORTA IL TUO CUBIT DELLO STAFF -// import 'package:flux/features/staff/blocs/staff_cubit.dart'; class StaffSection extends StatelessWidget { final OperationModel? currentOp; + final ValueChanged onStaffSelected; - const StaffSection({super.key, required this.currentOp}); + const StaffSection({ + super.key, + required this.currentOp, + required this.onStaffSelected, + }); @override Widget build(BuildContext context) { @@ -49,11 +52,12 @@ class StaffSection extends StatelessWidget { return GestureDetector( onTap: () { - // Aggiorniamo la form con un solo tap! - context.read().updateOperationFields( + onStaffSelected(staff); + + /* context.read().updateOperationFields( staffId: staff.id, staffDisplayName: staff.name, - ); + ); */ }, child: AnimatedContainer( duration: const Duration(milliseconds: 200), diff --git a/lib/features/operations/blocs/operation_files_bloc.dart b/lib/features/attachments/blocs/operation_files_bloc.dart similarity index 100% rename from lib/features/operations/blocs/operation_files_bloc.dart rename to lib/features/attachments/blocs/operation_files_bloc.dart diff --git a/lib/features/operations/blocs/operation_files_events.dart b/lib/features/attachments/blocs/operation_files_events.dart similarity index 100% rename from lib/features/operations/blocs/operation_files_events.dart rename to lib/features/attachments/blocs/operation_files_events.dart diff --git a/lib/features/operations/blocs/operation_files_state.dart b/lib/features/attachments/blocs/operation_files_state.dart similarity index 100% rename from lib/features/operations/blocs/operation_files_state.dart rename to lib/features/attachments/blocs/operation_files_state.dart diff --git a/lib/features/operations/ui/operation_form_screen.dart b/lib/features/operations/ui/operation_form_screen.dart index 40f7193..28e7b35 100644 --- a/lib/features/operations/ui/operation_form_screen.dart +++ b/lib/features/operations/ui/operation_form_screen.dart @@ -3,12 +3,11 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flux/core/blocs/session/session_cubit.dart'; import 'package:flux/features/operations/blocs/operations_cubit.dart'; import 'package:flux/features/operations/models/operation_model.dart'; -import 'package:flux/features/operations/ui/widgets/customer_section.dart'; +import 'package:flux/core/widgets/shared_forms/customer_section.dart'; import 'package:flux/features/operations/ui/widgets/details_section.dart'; -import 'package:flux/features/operations/ui/widgets/operation_files_section.dart'; -import 'package:flux/features/operations/ui/widgets/staff_section.dart'; -import 'package:get_it/get_it.dart'; // ASSICURATI DEL PATH -// import 'package:flux/features/attachments/ui/operation_files_section.dart'; +import 'package:flux/core/widgets/shared_forms/operation_files_section.dart'; +import 'package:flux/core/widgets/shared_forms/staff_section.dart'; +import 'package:get_it/get_it.dart'; class OperationFormScreen extends StatefulWidget { final String? operationId; @@ -317,10 +316,26 @@ class _OperationFormScreenState extends State { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - StaffSection(currentOp: currentOp), + StaffSection( + currentOp: currentOp, + onStaffSelected: (staff) => { + context.read().updateOperationFields( + staffId: staff.id, + staffDisplayName: staff.name, + ), + }, + ), const Divider(height: 50), _buildSectionTitle('Cliente & Riferimento'), - CustomerSection(currentOp: currentOp), + CustomerSection( + currentOp: currentOp, + onCustomerSelected: (customer) { + context.read().updateOperationFields( + customerId: customer.id, + customerDisplayName: customer.name, + ); + }, + ), const SizedBox(height: 16), TextFormField( controller: _referenceController, diff --git a/lib/features/operations/ui/operation_mobile_upload_screen.dart b/lib/features/operations/ui/operation_mobile_upload_screen.dart index 730efd0..ad916c7 100644 --- a/lib/features/operations/ui/operation_mobile_upload_screen.dart +++ b/lib/features/operations/ui/operation_mobile_upload_screen.dart @@ -1,7 +1,7 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:flux/features/operations/blocs/operation_files_bloc.dart'; +import 'package:flux/features/attachments/blocs/operation_files_bloc.dart'; import 'package:image_picker/image_picker.dart'; import 'package:file_picker/file_picker.dart'; diff --git a/lib/features/tickets/models/ticket_model.dart b/lib/features/tickets/models/ticket_model.dart index 70c06d2..74a7b2b 100644 --- a/lib/features/tickets/models/ticket_model.dart +++ b/lib/features/tickets/models/ticket_model.dart @@ -113,6 +113,7 @@ class TicketModel extends Equatable { final String? targetModelName; final String? sourceModelName; final String? staffName; + final String? includedAccessories; const TicketModel({ this.id, @@ -146,6 +147,7 @@ class TicketModel extends Equatable { this.targetModelName, this.sourceModelName, this.staffName, + this.includedAccessories, }); /// Factory per creare un ticket vuoto (utile per i form di creazione) @@ -194,6 +196,7 @@ class TicketModel extends Equatable { String? targetModelName, String? sourceModelName, String? staffName, + String? includedAccessories, }) { return TicketModel( id: id ?? this.id, @@ -228,6 +231,7 @@ class TicketModel extends Equatable { targetModelName: targetModelName ?? this.targetModelName, sourceModelName: sourceModelName ?? this.sourceModelName, staffName: staffName ?? this.staffName, + includedAccessories: includedAccessories ?? this.includedAccessories, ); } @@ -276,6 +280,7 @@ class TicketModel extends Equatable { sourceModelName: (map['source_model']?['name_with_brand'] as String?) ?.myFormat(), staffName: (map['staff']?['name'] as String?).myFormat(), + includedAccessories: map['included_accessories'] as String?, ); } @@ -309,6 +314,7 @@ class TicketModel extends Equatable { if (result != null) 'result': result!.value, 'resolution_notes': resolutionNotes, 'legacy_id': legacyId, + 'included_accessories': includedAccessories, }; } @@ -341,5 +347,10 @@ class TicketModel extends Equatable { result, resolutionNotes, legacyId, + includedAccessories, + customerName, + targetModelName, + sourceModelName, + staffName, ]; }