rese agnostiche sezioni customer e staff per le form. Inizio di lavoro per rendere agnostico il bloc degli allegati

This commit is contained in:
2026-05-06 08:58:23 +02:00
parent 1d45912fc7
commit 5207a82706
10 changed files with 57 additions and 34 deletions

View File

@@ -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';

View File

@@ -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<CustomerModel> 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<OperationsCubit>();
// 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<OperationsCubit>()
.updateOperationFields(
customerId: customer.id, // customer.id
customerDisplayName:
customer.name, // customer.name
);
onCustomerSelected(customer);
Navigator.pop(modalContext);
},
);

View File

@@ -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';

View File

@@ -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<StaffMemberModel> 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<OperationsCubit>().updateOperationFields(
onStaffSelected(staff);
/* context.read<OperationsCubit>().updateOperationFields(
staffId: staff.id,
staffDisplayName: staff.name,
);
); */
},
child: AnimatedContainer(
duration: const Duration(milliseconds: 200),

View File

@@ -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<OperationFormScreen> {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
StaffSection(currentOp: currentOp),
StaffSection(
currentOp: currentOp,
onStaffSelected: (staff) => {
context.read<OperationsCubit>().updateOperationFields(
staffId: staff.id,
staffDisplayName: staff.name,
),
},
),
const Divider(height: 50),
_buildSectionTitle('Cliente & Riferimento'),
CustomerSection(currentOp: currentOp),
CustomerSection(
currentOp: currentOp,
onCustomerSelected: (customer) {
context.read<OperationsCubit>().updateOperationFields(
customerId: customer.id,
customerDisplayName: customer.name,
);
},
),
const SizedBox(height: 16),
TextFormField(
controller: _referenceController,

View File

@@ -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';

View File

@@ -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,
];
}