asd
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ServiceActionCard extends StatelessWidget {
|
||||
class OperationActionCard extends StatelessWidget {
|
||||
final String title;
|
||||
final IconData icon;
|
||||
final VoidCallback onTap;
|
||||
final Color color;
|
||||
final int count;
|
||||
const ServiceActionCard({
|
||||
const OperationActionCard({
|
||||
super.key,
|
||||
required this.title,
|
||||
required this.icon,
|
||||
@@ -5,9 +5,9 @@ import 'package:flux/core/blocs/session/session_cubit.dart';
|
||||
import 'package:flux/core/widgets/image_viewer_widget.dart';
|
||||
import 'package:flux/core/widgets/pdf_viewer_widget.dart';
|
||||
import 'package:flux/core/widgets/qr_upload_dialog.dart';
|
||||
import 'package:flux/features/operations/blocs/service_files_bloc.dart';
|
||||
import 'package:flux/features/operations/blocs/operation_files_bloc.dart';
|
||||
import 'package:flux/features/operations/blocs/operations_cubit.dart';
|
||||
import 'package:flux/features/operations/models/service_file_model.dart';
|
||||
import 'package:flux/features/operations/models/operation_file_model.dart';
|
||||
|
||||
class AttachmentsSection extends StatelessWidget {
|
||||
const AttachmentsSection({super.key});
|
||||
@@ -22,27 +22,29 @@ class AttachmentsSection extends StatelessWidget {
|
||||
);
|
||||
|
||||
if (result != null && context.mounted) {
|
||||
context.read<ServiceFilesBloc>().add(AddServiceFilesEvent(result.files));
|
||||
context.read<OperationFilesBloc>().add(
|
||||
AddOperationFilesEvent(result.files),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
ServiceFilesBloc serviceFilesBloc = BlocProvider.of<ServiceFilesBloc>(
|
||||
OperationFilesBloc operationFilesBloc = BlocProvider.of<OperationFilesBloc>(
|
||||
context,
|
||||
);
|
||||
|
||||
return BlocListener<ServicesCubit, ServicesState>(
|
||||
return BlocListener<OperationsCubit, OperationsState>(
|
||||
listenWhen: (previous, current) =>
|
||||
previous.currentService?.id == null &&
|
||||
current.currentService?.id != null,
|
||||
previous.currentOperation?.id == null &&
|
||||
current.currentOperation?.id != null,
|
||||
listener: (context, state) {
|
||||
// FIGASSA! La pratica è stata salvata e ora ha un ID.
|
||||
// Diciamo al Bloc dei file di agganciarsi al database.
|
||||
final newId = state.currentService!.id!;
|
||||
context.read<ServiceFilesBloc>().add(ServiceSavedEvent(newId));
|
||||
final newId = state.currentOperation!.id!;
|
||||
context.read<OperationFilesBloc>().add(OperationsavedEvent(newId));
|
||||
},
|
||||
child: BlocBuilder<ServiceFilesBloc, ServiceFilesState>(
|
||||
child: BlocBuilder<OperationFilesBloc, OperationFilesState>(
|
||||
builder: (context, state) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@@ -125,8 +127,8 @@ class AttachmentsSection extends StatelessWidget {
|
||||
final isSelected = state.selectedFiles.contains(file);
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () => serviceFilesBloc.add(
|
||||
ToggleServiceFileSelectionEvent(file),
|
||||
onTap: () => operationFilesBloc.add(
|
||||
ToggleOperationFileSelectionEvent(file),
|
||||
),
|
||||
onDoubleTap: () => _handleDoubleClick(context, file),
|
||||
child: Card(
|
||||
@@ -216,7 +218,7 @@ class AttachmentsSection extends StatelessWidget {
|
||||
label: const Text("Elimina"),
|
||||
onPressed: () {
|
||||
// Qui lancerai l'evento per eliminare i file selezionati!
|
||||
// Es: serviceFilesBloc.add(DeleteSelectedFilesEvent());
|
||||
// Es: operationFilesBloc.add(DeleteSelectedFilesEvent());
|
||||
},
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
@@ -243,14 +245,14 @@ class AttachmentsSection extends StatelessWidget {
|
||||
}
|
||||
|
||||
Future<void> _handleGenerateQr(BuildContext context) async {
|
||||
final cubit = context.read<ServicesCubit>();
|
||||
var currentService = cubit.state.currentService;
|
||||
final cubit = context.read<OperationsCubit>();
|
||||
var currentOperation = cubit.state.currentOperation;
|
||||
|
||||
// 1. CATTURIAMO IL BLOC MENTRE SIAMO ANCORA NELLA PAGINA
|
||||
final serviceFilesBloc = context.read<ServiceFilesBloc>();
|
||||
final operationFilesBloc = context.read<OperationFilesBloc>();
|
||||
|
||||
// 2. SE LA PRATICA E' NUOVA (Manca l'ID)
|
||||
if (currentService == null || currentService.id == null) {
|
||||
if (currentOperation == null || currentOperation.id == null) {
|
||||
// NIENTE BlocListener qui! Solo un semplice Dialog di conferma
|
||||
final bool? confirm = await showDialog<bool>(
|
||||
context: context,
|
||||
@@ -275,42 +277,42 @@ class AttachmentsSection extends StatelessWidget {
|
||||
if (confirm != true) return; // Utente ha annullato
|
||||
|
||||
// Salviamo forzatamente in bozza
|
||||
await cubit.saveCurrentService(
|
||||
await cubit.saveCurrentOperation(
|
||||
isBozza: true,
|
||||
shouldPop: false,
|
||||
files: serviceFilesBloc.state.localFiles,
|
||||
files: operationFilesBloc.state.localFiles,
|
||||
);
|
||||
|
||||
// Recuperiamo il servizio aggiornato con l'ID!
|
||||
currentService = cubit.state.currentService;
|
||||
currentOperation = cubit.state.currentOperation;
|
||||
|
||||
if (currentService?.id == null) return;
|
||||
if (currentOperation?.id == null) return;
|
||||
}
|
||||
|
||||
// 3. MOSTRIAMO IL QR CODE (Con il Ponte e l'Auto-Chiusura!)
|
||||
if (context.mounted) {
|
||||
final nomePratica = "Pratica ${currentService?.customerDisplayName ?? ''}"
|
||||
.trim();
|
||||
final nomePratica =
|
||||
"Pratica ${currentOperation?.customerDisplayName ?? ''}".trim();
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (dialogContext) => BlocProvider.value(
|
||||
// INIETTIAMO IL BLOC NEL CONTESTO DEL DIALOG ALIENO
|
||||
value: serviceFilesBloc,
|
||||
value: operationFilesBloc,
|
||||
|
||||
// ORA METTIAMO L'AUTO-CHIUSURA SUL QR CODE!
|
||||
child: BlocListener<ServiceFilesBloc, ServiceFilesState>(
|
||||
child: BlocListener<OperationFilesBloc, OperationFilesState>(
|
||||
listener: (context, state) {
|
||||
// Se arrivano file remoti e lo stato è success, chiudiamo il QR!
|
||||
// (Nota: usiamo dialogContext per assicurarci di chiudere il popup giusto)
|
||||
if (state.status == ServiceFilesStatus.success &&
|
||||
if (state.status == OperationFilesStatus.success &&
|
||||
state.remoteFiles.isNotEmpty) {
|
||||
Navigator.of(dialogContext).pop();
|
||||
}
|
||||
},
|
||||
child: QrUploadDialog(
|
||||
deepLinkUrl:
|
||||
'fluxapp:///operation/${currentService!.id}/upload?name=${Uri.encodeComponent(nomePratica)}',
|
||||
'fluxapp:///operation/${currentOperation!.id}/upload?name=${Uri.encodeComponent(nomePratica)}',
|
||||
title: 'Scatta per\n$nomePratica',
|
||||
),
|
||||
),
|
||||
@@ -322,7 +324,7 @@ class AttachmentsSection extends StatelessWidget {
|
||||
// --- LOGICA DI COPIA AL CLIENTE ---
|
||||
void saveAndCopyFilesToCustomer(
|
||||
BuildContext context,
|
||||
List<ServiceFileModel> files,
|
||||
List<OperationFileModel> files,
|
||||
) {
|
||||
showDialog(
|
||||
context: context,
|
||||
@@ -341,7 +343,7 @@ class AttachmentsSection extends StatelessWidget {
|
||||
onPressed: () {
|
||||
Navigator.pop(ctx);
|
||||
// 1. Diciamo al Cubit di salvare in Bozza e fare la copia
|
||||
context.read<ServicesCubit>().saveAndCopyFileToCustomer(files);
|
||||
context.read<OperationsCubit>().saveAndCopyFileToCustomer(files);
|
||||
},
|
||||
child: const Text("Salva e Copia"),
|
||||
),
|
||||
@@ -351,7 +353,7 @@ class AttachmentsSection extends StatelessWidget {
|
||||
}
|
||||
|
||||
// --- LOGICA DI VISUALIZZAZIONE OVERLAY ---
|
||||
void _handleDoubleClick(BuildContext context, ServiceFileModel file) {
|
||||
void _handleDoubleClick(BuildContext context, OperationFileModel file) {
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: true,
|
||||
@@ -1,9 +1,9 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flux/features/customers/ui/customer_search_sheet.dart';
|
||||
import 'package:flux/features/operations/models/service_model.dart';
|
||||
import 'package:flux/features/operations/models/operation_model.dart';
|
||||
|
||||
class CustomerSection extends StatelessWidget {
|
||||
final ServiceModel operation;
|
||||
final OperationModel operation;
|
||||
|
||||
const CustomerSection({super.key, required this.operation});
|
||||
|
||||
@@ -2,32 +2,32 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flux/features/master_data/providers/blocs/provider_cubit.dart';
|
||||
import 'package:flux/features/master_data/providers/models/provider_model.dart';
|
||||
import 'package:flux/features/operations/models/energy_service_model.dart'; // Assicurati degli import
|
||||
import 'package:flux/features/operations/models/energy_operation_model.dart'; // Assicurati degli import
|
||||
|
||||
class EnergyServiceDialog extends StatefulWidget {
|
||||
final List<EnergyServiceModel> initialServices;
|
||||
class EnergyOperationDialog extends StatefulWidget {
|
||||
final List<EnergyOperationModel> initialOperations;
|
||||
final String
|
||||
currentStoreId; // Ci serve per sapere per quale negozio caricare i gestori
|
||||
|
||||
const EnergyServiceDialog({
|
||||
const EnergyOperationDialog({
|
||||
super.key,
|
||||
required this.initialServices,
|
||||
required this.initialOperations,
|
||||
required this.currentStoreId,
|
||||
});
|
||||
|
||||
@override
|
||||
State<EnergyServiceDialog> createState() => _EnergyServiceDialogState();
|
||||
State<EnergyOperationDialog> createState() => _EnergyOperationDialogState();
|
||||
}
|
||||
|
||||
class _EnergyServiceDialogState extends State<EnergyServiceDialog> {
|
||||
class _EnergyOperationDialogState extends State<EnergyOperationDialog> {
|
||||
// Lista temporanea per non "sporcare" il cubit finché non si preme Conferma
|
||||
late List<EnergyServiceModel> _tempList;
|
||||
late List<EnergyOperationModel> _tempList;
|
||||
bool _isAddingNew = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_tempList = List.from(widget.initialServices);
|
||||
_tempList = List.from(widget.initialOperations);
|
||||
// Al caricamento della modale, chiediamo al Cubit di recuperare i gestori veri!
|
||||
context.read<ProvidersCubit>().loadActiveProvidersForStore(
|
||||
widget.currentStoreId,
|
||||
@@ -52,9 +52,9 @@ class _EnergyServiceDialogState extends State<EnergyServiceDialog> {
|
||||
// Cambia vista in base al flag
|
||||
child: _isAddingNew
|
||||
? _EnergyForm(
|
||||
onSave: (newService) {
|
||||
onSave: (newOperation) {
|
||||
setState(() {
|
||||
_tempList.add(newService);
|
||||
_tempList.add(newOperation);
|
||||
_isAddingNew = false; // Torna alla lista
|
||||
});
|
||||
},
|
||||
@@ -101,7 +101,7 @@ class _EnergyServiceDialogState extends State<EnergyServiceDialog> {
|
||||
// VISTA 1: LA LISTA DEI CONTRATTI
|
||||
// ==========================================
|
||||
class _EnergyList extends StatelessWidget {
|
||||
final List<EnergyServiceModel> operations;
|
||||
final List<EnergyOperationModel> operations;
|
||||
final List<ProviderModel>
|
||||
activeProviders; // <--- NUOVO: La lista vera dal Cubit
|
||||
final Function(int) onDelete;
|
||||
@@ -193,7 +193,7 @@ class _EnergyList extends StatelessWidget {
|
||||
// VISTA 2: IL FORM DI INSERIMENTO
|
||||
// ==========================================
|
||||
class _EnergyForm extends StatefulWidget {
|
||||
final Function(EnergyServiceModel) onSave;
|
||||
final Function(EnergyOperationModel) onSave;
|
||||
final VoidCallback onCancel;
|
||||
|
||||
const _EnergyForm({required this.onSave, required this.onCancel});
|
||||
@@ -400,12 +400,12 @@ class _EnergyFormState extends State<_EnergyForm> {
|
||||
(_selectedProviderId == null || _selectedExpiration == null)
|
||||
? null // Disabilitato se mancano dati obbligatori
|
||||
: () {
|
||||
final newService = EnergyServiceModel(
|
||||
final newOperation = EnergyOperationModel(
|
||||
type: _selectedType,
|
||||
expiration: _selectedExpiration!,
|
||||
providerId: _selectedProviderId!,
|
||||
);
|
||||
widget.onSave(newService);
|
||||
widget.onSave(newOperation);
|
||||
},
|
||||
child: const Text("Salva Contratto"),
|
||||
),
|
||||
@@ -3,34 +3,34 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flux/core/blocs/session/session_cubit.dart';
|
||||
import 'package:flux/features/master_data/providers/blocs/provider_cubit.dart';
|
||||
import 'package:flux/features/master_data/providers/models/provider_model.dart';
|
||||
import 'package:flux/features/operations/data/services_repository.dart';
|
||||
import 'package:flux/features/operations/models/entertainment_service_model.dart';
|
||||
import 'package:flux/features/operations/data/operations_repository.dart';
|
||||
import 'package:flux/features/operations/models/entertainment_operation_model.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
|
||||
class EntertainmentServiceDialog extends StatefulWidget {
|
||||
final List<EntertainmentServiceModel> initialServices;
|
||||
class EntertainmentOperationDialog extends StatefulWidget {
|
||||
final List<EntertainmentOperationModel> initialOperations;
|
||||
final String currentStoreId;
|
||||
|
||||
const EntertainmentServiceDialog({
|
||||
const EntertainmentOperationDialog({
|
||||
super.key,
|
||||
required this.initialServices,
|
||||
required this.initialOperations,
|
||||
required this.currentStoreId,
|
||||
});
|
||||
|
||||
@override
|
||||
State<EntertainmentServiceDialog> createState() =>
|
||||
_EntertainmentServiceDialogState();
|
||||
State<EntertainmentOperationDialog> createState() =>
|
||||
_EntertainmentOperationDialogState();
|
||||
}
|
||||
|
||||
class _EntertainmentServiceDialogState
|
||||
extends State<EntertainmentServiceDialog> {
|
||||
late List<EntertainmentServiceModel> _tempList;
|
||||
class _EntertainmentOperationDialogState
|
||||
extends State<EntertainmentOperationDialog> {
|
||||
late List<EntertainmentOperationModel> _tempList;
|
||||
bool _isAddingNew = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_tempList = List.from(widget.initialServices);
|
||||
_tempList = List.from(widget.initialOperations);
|
||||
// Carichiamo i provider attivi per lo store corrente
|
||||
context.read<ProvidersCubit>().loadActiveProvidersForStore(
|
||||
widget.currentStoreId,
|
||||
@@ -57,8 +57,8 @@ class _EntertainmentServiceDialogState
|
||||
child: _isAddingNew
|
||||
? _EntertainmentForm(
|
||||
// Il form che abbiamo creato prima
|
||||
onSave: (newService) => setState(() {
|
||||
_tempList.add(newService);
|
||||
onSave: (newOperation) => setState(() {
|
||||
_tempList.add(newOperation);
|
||||
_isAddingNew = false;
|
||||
}),
|
||||
onCancel: () => setState(() => _isAddingNew = false),
|
||||
@@ -94,7 +94,7 @@ class _EntertainmentServiceDialogState
|
||||
}
|
||||
|
||||
class _EntertainmentList extends StatelessWidget {
|
||||
final List<EntertainmentServiceModel> operations;
|
||||
final List<EntertainmentOperationModel> operations;
|
||||
final List<ProviderModel> allProviders;
|
||||
final Function(int) onDelete;
|
||||
final VoidCallback onAddTap;
|
||||
@@ -194,7 +194,7 @@ class _EntertainmentList extends StatelessWidget {
|
||||
// ---ENTERTAINMENT FORM (MODALE)---
|
||||
|
||||
class _EntertainmentForm extends StatefulWidget {
|
||||
final Function(EntertainmentServiceModel) onSave;
|
||||
final Function(EntertainmentOperationModel) onSave;
|
||||
final VoidCallback onCancel;
|
||||
|
||||
const _EntertainmentForm({required this.onSave, required this.onCancel});
|
||||
@@ -280,7 +280,7 @@ class _EntertainmentFormState extends State<_EntertainmentForm> {
|
||||
const SizedBox(height: 8),
|
||||
// Suggerimenti rapidi (Chip)
|
||||
FutureBuilder<List<String>>(
|
||||
future: GetIt.I<ServicesRepository>().fetchTopEntertainmentTypes(
|
||||
future: GetIt.I<OperationsRepository>().fetchTopEntertainmentTypes(
|
||||
GetIt.I<SessionCubit>().state.company!.id!,
|
||||
),
|
||||
builder: (context, snapshot) {
|
||||
@@ -376,7 +376,7 @@ class _EntertainmentFormState extends State<_EntertainmentForm> {
|
||||
(_selectedProviderId == null || _typeController.text.isEmpty)
|
||||
? null
|
||||
: () => widget.onSave(
|
||||
EntertainmentServiceModel(
|
||||
EntertainmentOperationModel(
|
||||
providerId: _selectedProviderId!,
|
||||
type: _typeController.text,
|
||||
constrained: _isConstrained,
|
||||
@@ -5,36 +5,36 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flux/features/master_data/products/blocs/product_cubit.dart';
|
||||
import 'package:flux/features/master_data/products/models/model_model.dart';
|
||||
import 'package:flux/features/master_data/providers/blocs/provider_cubit.dart';
|
||||
import 'package:flux/features/operations/models/fin_service_model.dart';
|
||||
import 'package:flux/features/operations/models/fin_operation_model.dart';
|
||||
import 'package:flux/features/master_data/providers/models/provider_model.dart';
|
||||
|
||||
// ===========================================================================
|
||||
// DIALOG PRINCIPALE
|
||||
// ===========================================================================
|
||||
class FinanceServiceDialog extends StatefulWidget {
|
||||
final List<FinServiceModel> initialServices;
|
||||
class FinanceOperationDialog extends StatefulWidget {
|
||||
final List<FinOperationModel> initialOperations;
|
||||
final String currentStoreId;
|
||||
final ProductCubit productCubit;
|
||||
|
||||
const FinanceServiceDialog({
|
||||
const FinanceOperationDialog({
|
||||
super.key,
|
||||
required this.initialServices,
|
||||
required this.initialOperations,
|
||||
required this.currentStoreId,
|
||||
required this.productCubit,
|
||||
});
|
||||
|
||||
@override
|
||||
State<FinanceServiceDialog> createState() => _FinanceServiceDialogState();
|
||||
State<FinanceOperationDialog> createState() => _FinanceOperationDialogState();
|
||||
}
|
||||
|
||||
class _FinanceServiceDialogState extends State<FinanceServiceDialog> {
|
||||
late List<FinServiceModel> _tempList;
|
||||
class _FinanceOperationDialogState extends State<FinanceOperationDialog> {
|
||||
late List<FinOperationModel> _tempList;
|
||||
bool _isAddingNew = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_tempList = List.from(widget.initialServices);
|
||||
_tempList = List.from(widget.initialOperations);
|
||||
// Carichiamo i dati necessari dai Cubit
|
||||
context.read<ProvidersCubit>().loadActiveProvidersForStore(
|
||||
widget.currentStoreId,
|
||||
@@ -109,7 +109,7 @@ class _FinanceServiceDialogState extends State<FinanceServiceDialog> {
|
||||
// VISTA LISTA (STORICA)
|
||||
// ===========================================================================
|
||||
class _FinanceList extends StatelessWidget {
|
||||
final List<FinServiceModel> operations;
|
||||
final List<FinOperationModel> operations;
|
||||
final List<ProviderModel> allProviders;
|
||||
final List<ModelModel> allModels;
|
||||
final Function(int) onDelete;
|
||||
@@ -221,7 +221,7 @@ class _FinanceList extends StatelessWidget {
|
||||
// FORM CON OMNI-SEARCH
|
||||
// ===========================================================================
|
||||
class _FinanceForm extends StatefulWidget {
|
||||
final Function(FinServiceModel) onSave;
|
||||
final Function(FinOperationModel) onSave;
|
||||
final VoidCallback onCancel;
|
||||
|
||||
const _FinanceForm({required this.onSave, required this.onCancel});
|
||||
@@ -428,7 +428,7 @@ class _FinanceFormState extends State<_FinanceForm> {
|
||||
: () {
|
||||
final now = DateTime.now();
|
||||
widget.onSave(
|
||||
FinServiceModel(
|
||||
FinOperationModel(
|
||||
providerId: _selectedProviderId!,
|
||||
modelId: _selectedModel!.id!,
|
||||
expiration: DateTime(
|
||||
@@ -1,10 +1,10 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flux/features/operations/blocs/operations_cubit.dart';
|
||||
import 'package:flux/features/operations/models/service_model.dart';
|
||||
import 'package:flux/features/operations/models/operation_model.dart';
|
||||
|
||||
class GeneralInfoSection extends StatelessWidget {
|
||||
final ServiceModel operation;
|
||||
final OperationModel operation;
|
||||
const GeneralInfoSection({super.key, required this.operation});
|
||||
|
||||
@override
|
||||
@@ -44,7 +44,7 @@ class GeneralInfoSection extends StatelessWidget {
|
||||
prefixIcon: Icon(Icons.phone),
|
||||
),
|
||||
onChanged: (val) {
|
||||
context.read<ServicesCubit>().updateField(number: val);
|
||||
context.read<OperationsCubit>().updateField(number: val);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
@@ -63,7 +63,7 @@ class GeneralInfoSection extends StatelessWidget {
|
||||
activeThumbColor: Colors.orange,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
onChanged: (val) {
|
||||
context.read<ServicesCubit>().updateField(isBozza: val);
|
||||
context.read<OperationsCubit>().updateField(isBozza: val);
|
||||
},
|
||||
),
|
||||
),
|
||||
@@ -79,7 +79,9 @@ class GeneralInfoSection extends StatelessWidget {
|
||||
activeThumbColor: Colors.green,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
onChanged: (val) {
|
||||
context.read<ServicesCubit>().updateField(resultOk: val);
|
||||
context.read<OperationsCubit>().updateField(
|
||||
resultOk: val,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
@@ -100,7 +102,7 @@ class GeneralInfoSection extends StatelessWidget {
|
||||
alignLabelWithHint: true,
|
||||
),
|
||||
onChanged: (val) {
|
||||
context.read<ServicesCubit>().updateField(note: val);
|
||||
context.read<OperationsCubit>().updateField(note: val);
|
||||
},
|
||||
),
|
||||
],
|
||||
@@ -1,49 +1,49 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flux/features/operations/blocs/operations_cubit.dart';
|
||||
import 'package:flux/features/operations/models/service_model.dart';
|
||||
import 'package:flux/features/operations/ui/service_form_screen/attachment_section.dart';
|
||||
import 'package:flux/features/operations/ui/service_form_screen/customer_section.dart';
|
||||
import 'package:flux/features/operations/ui/service_form_screen/general_info_section.dart';
|
||||
import 'package:flux/features/operations/ui/service_form_screen/services_grid.dart';
|
||||
import 'package:flux/features/operations/models/operation_model.dart';
|
||||
import 'package:flux/features/operations/ui/operation_form_screen/attachment_section.dart';
|
||||
import 'package:flux/features/operations/ui/operation_form_screen/customer_section.dart';
|
||||
import 'package:flux/features/operations/ui/operation_form_screen/general_info_section.dart';
|
||||
import 'package:flux/features/operations/ui/operation_form_screen/operations_grid.dart';
|
||||
|
||||
class ServiceFormScreen extends StatefulWidget {
|
||||
final String? serviceId;
|
||||
final ServiceModel? existingService; // <-- AGGIUNTO
|
||||
class OperationFormScreen extends StatefulWidget {
|
||||
final String? operationId;
|
||||
final OperationModel? existingOperation; // <-- AGGIUNTO
|
||||
|
||||
const ServiceFormScreen({
|
||||
const OperationFormScreen({
|
||||
super.key,
|
||||
this.serviceId,
|
||||
this.existingService, // <-- AGGIUNTO
|
||||
this.operationId,
|
||||
this.existingOperation, // <-- AGGIUNTO
|
||||
});
|
||||
|
||||
@override
|
||||
State<ServiceFormScreen> createState() => _ServiceFormScreenState();
|
||||
State<OperationFormScreen> createState() => _OperationFormScreenState();
|
||||
}
|
||||
|
||||
class _ServiceFormScreenState extends State<ServiceFormScreen> {
|
||||
class _OperationFormScreenState extends State<OperationFormScreen> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
// Diamo in pasto al Cubit tutto quello che abbiamo!
|
||||
context.read<ServicesCubit>().initServiceForm(
|
||||
existingService: widget.existingService,
|
||||
serviceId: widget.serviceId,
|
||||
context.read<OperationsCubit>().initOperationForm(
|
||||
existingOperation: widget.existingOperation,
|
||||
operationId: widget.operationId,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
void _performSave(BuildContext context, {required bool isBozza}) {
|
||||
FocusScope.of(context).unfocus();
|
||||
context.read<ServicesCubit>().saveCurrentService(isBozza: isBozza);
|
||||
context.read<OperationsCubit>().saveCurrentOperation(isBozza: isBozza);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocConsumer<ServicesCubit, ServicesState>(
|
||||
return BlocConsumer<OperationsCubit, OperationsState>(
|
||||
listener: (context, state) {
|
||||
if (state.status == ServicesStatus.saved) {
|
||||
if (state.status == OperationsStatus.saved) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text("Pratica salvata con successo!"),
|
||||
@@ -52,7 +52,7 @@ class _ServiceFormScreenState extends State<ServiceFormScreen> {
|
||||
);
|
||||
Navigator.pop(context);
|
||||
}
|
||||
if (state.status == ServicesStatus.failure) {
|
||||
if (state.status == OperationsStatus.failure) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text("Errore: ${state.errorMessage ?? ''}"),
|
||||
@@ -60,7 +60,7 @@ class _ServiceFormScreenState extends State<ServiceFormScreen> {
|
||||
),
|
||||
);
|
||||
}
|
||||
if (state.status == ServicesStatus.savedNoPop) {
|
||||
if (state.status == OperationsStatus.savedNoPop) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text("Pratica salvata con successo!"),
|
||||
@@ -70,9 +70,9 @@ class _ServiceFormScreenState extends State<ServiceFormScreen> {
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
final operation = state.currentService;
|
||||
final isSaving = state.status == ServicesStatus.saving;
|
||||
final isEditMode = widget.serviceId != null;
|
||||
final operation = state.currentOperation;
|
||||
final isSaving = state.status == OperationsStatus.saving;
|
||||
final isEditMode = widget.operationId != null;
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
@@ -120,7 +120,7 @@ class _ServiceFormScreenState extends State<ServiceFormScreen> {
|
||||
GeneralInfoSection(operation: operation),
|
||||
const SizedBox(height: 24),
|
||||
|
||||
ServicesGrid(operation: operation),
|
||||
OperationsGrid(operation: operation),
|
||||
const SizedBox(height: 32),
|
||||
|
||||
AttachmentsSection(),
|
||||
@@ -3,24 +3,25 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flux/features/operations/blocs/service_files_bloc.dart';
|
||||
import 'package:flux/features/operations/blocs/operation_files_bloc.dart';
|
||||
|
||||
class ServiceMobileUploadScreen extends StatefulWidget {
|
||||
final String serviceId;
|
||||
final String serviceName;
|
||||
class OperationMobileUploadScreen extends StatefulWidget {
|
||||
final String operationId;
|
||||
final String operationName;
|
||||
|
||||
const ServiceMobileUploadScreen({
|
||||
const OperationMobileUploadScreen({
|
||||
super.key,
|
||||
required this.serviceId,
|
||||
required this.serviceName,
|
||||
required this.operationId,
|
||||
required this.operationName,
|
||||
});
|
||||
|
||||
@override
|
||||
State<ServiceMobileUploadScreen> createState() =>
|
||||
_ServiceMobileUploadScreenState();
|
||||
State<OperationMobileUploadScreen> createState() =>
|
||||
_OperationMobileUploadScreenState();
|
||||
}
|
||||
|
||||
class _ServiceMobileUploadScreenState extends State<ServiceMobileUploadScreen> {
|
||||
class _OperationMobileUploadScreenState
|
||||
extends State<OperationMobileUploadScreen> {
|
||||
// 1. LA NOSTRA STAGING AREA (Il "Carrello")
|
||||
final List<PlatformFile> _stagedFiles = [];
|
||||
|
||||
@@ -35,10 +36,10 @@ class _ServiceMobileUploadScreenState extends State<ServiceMobileUploadScreen> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocListener<ServiceFilesBloc, ServiceFilesState>(
|
||||
return BlocListener<OperationFilesBloc, OperationFilesState>(
|
||||
listener: (context, state) {
|
||||
// Quando il BLoC ci dice che ha finito l'upload (Success), chiudiamo la pagina!
|
||||
if (state.status == ServiceFilesStatus.success && _isUploading) {
|
||||
if (state.status == OperationFilesStatus.success && _isUploading) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text("Tutti i file caricati con successo! ✅"),
|
||||
@@ -46,7 +47,7 @@ class _ServiceMobileUploadScreenState extends State<ServiceMobileUploadScreen> {
|
||||
);
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
if (state.status == ServiceFilesStatus.failure) {
|
||||
if (state.status == OperationFilesStatus.failure) {
|
||||
setState(() => _isUploading = false);
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
@@ -55,7 +56,7 @@ class _ServiceMobileUploadScreenState extends State<ServiceMobileUploadScreen> {
|
||||
},
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text("Upload Pratica:\n${widget.serviceName}"),
|
||||
title: Text("Upload Pratica:\n${widget.operationName}"),
|
||||
automaticallyImplyLeading: !_isUploading,
|
||||
),
|
||||
body: Stack(
|
||||
@@ -294,8 +295,8 @@ class _ServiceMobileUploadScreenState extends State<ServiceMobileUploadScreen> {
|
||||
|
||||
// Diciamo al BLoC di caricare tutti i file.
|
||||
// Usiamo il tuo evento esistente per ogni file (il BLoC li metterà in coda)
|
||||
final bloc = context.read<ServiceFilesBloc>();
|
||||
bloc.add(UploadMultipleServiceFilesEvent(_stagedFiles));
|
||||
final bloc = context.read<OperationFilesBloc>();
|
||||
bloc.add(UploadMultipleOperationFilesEvent(_stagedFiles));
|
||||
|
||||
// N.B: Il Navigator.pop() viene chiamato dal BlocListener in alto quando lo stato diventa "success"!
|
||||
}
|
||||
@@ -2,20 +2,20 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flux/features/master_data/products/blocs/product_cubit.dart';
|
||||
import 'package:flux/features/operations/blocs/operations_cubit.dart';
|
||||
import 'package:flux/features/operations/models/energy_service_model.dart';
|
||||
import 'package:flux/features/operations/models/entertainment_service_model.dart';
|
||||
import 'package:flux/features/operations/models/fin_service_model.dart';
|
||||
import 'package:flux/features/operations/models/service_model.dart';
|
||||
import 'package:flux/features/operations/ui/service_form_screen/action_card.dart';
|
||||
import 'package:flux/features/operations/ui/service_form_screen/energy_service_dialog.dart';
|
||||
import 'package:flux/features/operations/ui/service_form_screen/entertainment_service_card.dart';
|
||||
import 'package:flux/features/operations/ui/service_form_screen/finance_service_dialog.dart';
|
||||
import 'package:flux/features/operations/ui/service_form_screen/int_dialogs.dart'; // Assicurati di importare il modello
|
||||
import 'package:flux/features/operations/models/energy_operation_model.dart';
|
||||
import 'package:flux/features/operations/models/entertainment_operation_model.dart';
|
||||
import 'package:flux/features/operations/models/fin_operation_model.dart';
|
||||
import 'package:flux/features/operations/models/operation_model.dart';
|
||||
import 'package:flux/features/operations/ui/operation_form_screen/action_card.dart';
|
||||
import 'package:flux/features/operations/ui/operation_form_screen/energy_operation_dialog.dart';
|
||||
import 'package:flux/features/operations/ui/operation_form_screen/entertainment_operation_card.dart';
|
||||
import 'package:flux/features/operations/ui/operation_form_screen/finance_operation_dialog.dart';
|
||||
import 'package:flux/features/operations/ui/operation_form_screen/int_dialogs.dart'; // Assicurati di importare il modello
|
||||
|
||||
class ServicesGrid extends StatelessWidget {
|
||||
final ServiceModel operation;
|
||||
class OperationsGrid extends StatelessWidget {
|
||||
final OperationModel operation;
|
||||
|
||||
const ServicesGrid({super.key, required this.operation});
|
||||
const OperationsGrid({super.key, required this.operation});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -60,7 +60,7 @@ class ServicesGrid extends StatelessWidget {
|
||||
"AL",
|
||||
operation.al,
|
||||
(val) =>
|
||||
context.read<ServicesCubit>().updateField(al: val),
|
||||
context.read<OperationsCubit>().updateField(al: val),
|
||||
),
|
||||
),
|
||||
ActionCard(
|
||||
@@ -73,7 +73,7 @@ class ServicesGrid extends StatelessWidget {
|
||||
"MNP",
|
||||
operation.mnp,
|
||||
(val) =>
|
||||
context.read<ServicesCubit>().updateField(mnp: val),
|
||||
context.read<OperationsCubit>().updateField(mnp: val),
|
||||
),
|
||||
),
|
||||
ActionCard(
|
||||
@@ -86,7 +86,7 @@ class ServicesGrid extends StatelessWidget {
|
||||
"NIP",
|
||||
operation.nip,
|
||||
(val) =>
|
||||
context.read<ServicesCubit>().updateField(nip: val),
|
||||
context.read<OperationsCubit>().updateField(nip: val),
|
||||
),
|
||||
),
|
||||
ActionCard(
|
||||
@@ -98,8 +98,9 @@ class ServicesGrid extends StatelessWidget {
|
||||
context,
|
||||
"Unica",
|
||||
operation.unica,
|
||||
(val) =>
|
||||
context.read<ServicesCubit>().updateField(unica: val),
|
||||
(val) => context.read<OperationsCubit>().updateField(
|
||||
unica: val,
|
||||
),
|
||||
),
|
||||
),
|
||||
ActionCard(
|
||||
@@ -111,7 +112,7 @@ class ServicesGrid extends StatelessWidget {
|
||||
context,
|
||||
"Telepass",
|
||||
operation.telepass,
|
||||
(val) => context.read<ServicesCubit>().updateField(
|
||||
(val) => context.read<OperationsCubit>().updateField(
|
||||
telepass: val,
|
||||
),
|
||||
),
|
||||
@@ -120,23 +121,24 @@ class ServicesGrid extends StatelessWidget {
|
||||
// --- MODULI COMPLESSI (Le liste) ---
|
||||
ActionCard(
|
||||
label: "Energia",
|
||||
count: operation.energyServices.length,
|
||||
count: operation.energyOperations.length,
|
||||
icon: Icons.bolt,
|
||||
color: Colors.green,
|
||||
onTap: () async {
|
||||
// Apriamo la modale e aspettiamo il risultato
|
||||
final result = await showDialog<List<EnergyServiceModel>>(
|
||||
context: context,
|
||||
builder: (context) => EnergyServiceDialog(
|
||||
currentStoreId: operation.storeId,
|
||||
initialServices: operation
|
||||
.energyServices, // Passiamo la lista attuale
|
||||
),
|
||||
);
|
||||
final result =
|
||||
await showDialog<List<EnergyOperationModel>>(
|
||||
context: context,
|
||||
builder: (context) => EnergyOperationDialog(
|
||||
currentStoreId: operation.storeId,
|
||||
initialOperations: operation
|
||||
.energyOperations, // Passiamo la lista attuale
|
||||
),
|
||||
);
|
||||
|
||||
// Se l'utente ha premuto "Conferma" e non "Annulla" o tap fuori
|
||||
if (result != null && context.mounted) {
|
||||
context.read<ServicesCubit>().updateEnergyServices(
|
||||
context.read<OperationsCubit>().updateEnergyOperations(
|
||||
result,
|
||||
);
|
||||
}
|
||||
@@ -144,44 +146,47 @@ class ServicesGrid extends StatelessWidget {
|
||||
),
|
||||
ActionCard(
|
||||
label: "Finanziam.",
|
||||
count: operation.finServices.length,
|
||||
count: operation.finOperations.length,
|
||||
icon: Icons.euro_symbol,
|
||||
color: Colors.teal,
|
||||
onTap: () async {
|
||||
final result = await showDialog<List<FinServiceModel>>(
|
||||
final result = await showDialog<List<FinOperationModel>>(
|
||||
context: context,
|
||||
builder: (context) => FinanceServiceDialog(
|
||||
builder: (context) => FinanceOperationDialog(
|
||||
productCubit: context.read<ProductCubit>(),
|
||||
currentStoreId: operation.storeId,
|
||||
initialServices: operation
|
||||
.finServices, // Passiamo la lista attuale
|
||||
initialOperations: operation
|
||||
.finOperations, // Passiamo la lista attuale
|
||||
),
|
||||
);
|
||||
|
||||
if (result != null && context.mounted) {
|
||||
context.read<ServicesCubit>().updateFinServices(result);
|
||||
context.read<OperationsCubit>().updateFinOperations(
|
||||
result,
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
ActionCard(
|
||||
label: "Intratten.",
|
||||
count: operation.entertainmentServices.length,
|
||||
count: operation.entertainmentOperations.length,
|
||||
icon: Icons.movie_filter_outlined,
|
||||
color: Colors.purple,
|
||||
onTap: () async {
|
||||
final result =
|
||||
await showDialog<List<EntertainmentServiceModel>>(
|
||||
await showDialog<List<EntertainmentOperationModel>>(
|
||||
context: context,
|
||||
builder: (context) => EntertainmentServiceDialog(
|
||||
initialServices: operation.entertainmentServices,
|
||||
builder: (context) => EntertainmentOperationDialog(
|
||||
initialOperations:
|
||||
operation.entertainmentOperations,
|
||||
currentStoreId: operation.storeId,
|
||||
),
|
||||
);
|
||||
|
||||
if (result != null && context.mounted) {
|
||||
context
|
||||
.read<ServicesCubit>()
|
||||
.updateEntertainmentServices(result);
|
||||
.read<OperationsCubit>()
|
||||
.updateEntertainmentOperations(result);
|
||||
}
|
||||
},
|
||||
),
|
||||
@@ -1,19 +1,19 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flux/features/operations/blocs/operations_cubit.dart';
|
||||
import 'package:flux/features/operations/models/service_model.dart';
|
||||
import 'package:flux/features/operations/utils/service_actions.dart';
|
||||
import 'package:flux/features/operations/models/operation_model.dart';
|
||||
import 'package:flux/features/operations/utils/operation_actions.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
// Importa i tuoi modelli e cubit
|
||||
|
||||
class ServicesScreen extends StatefulWidget {
|
||||
const ServicesScreen({super.key});
|
||||
class OperationsScreen extends StatefulWidget {
|
||||
const OperationsScreen({super.key});
|
||||
|
||||
@override
|
||||
State<ServicesScreen> createState() => _ServicesScreenState();
|
||||
State<OperationsScreen> createState() => _OperationsScreenState();
|
||||
}
|
||||
|
||||
class _ServicesScreenState extends State<ServicesScreen> {
|
||||
class _OperationsScreenState extends State<OperationsScreen> {
|
||||
final ScrollController _scrollController = ScrollController();
|
||||
|
||||
@override
|
||||
@@ -22,12 +22,12 @@ class _ServicesScreenState extends State<ServicesScreen> {
|
||||
// Agganciamo il listener per la paginazione (Scroll Infinito)
|
||||
_scrollController.addListener(_onScroll);
|
||||
// Carichiamo i servizi iniziali
|
||||
context.read<ServicesCubit>().loadServices();
|
||||
context.read<OperationsCubit>().loadOperations();
|
||||
}
|
||||
|
||||
void _onScroll() {
|
||||
if (_isBottom) {
|
||||
context.read<ServicesCubit>().loadServices();
|
||||
context.read<OperationsCubit>().loadOperations();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,16 +60,16 @@ class _ServicesScreenState extends State<ServicesScreen> {
|
||||
),
|
||||
],
|
||||
),
|
||||
body: BlocBuilder<ServicesCubit, ServicesState>(
|
||||
body: BlocBuilder<OperationsCubit, OperationsState>(
|
||||
builder: (context, state) {
|
||||
// 1. Stato di caricamento iniziale
|
||||
if (state.status == ServicesStatus.loading &&
|
||||
state.allServices.isEmpty) {
|
||||
if (state.status == OperationsStatus.loading &&
|
||||
state.allOperations.isEmpty) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
|
||||
// 2. Lista vuota
|
||||
if (state.allServices.isEmpty) {
|
||||
if (state.allOperations.isEmpty) {
|
||||
return Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
@@ -77,9 +77,9 @@ class _ServicesScreenState extends State<ServicesScreen> {
|
||||
const Text("Nessuna pratica trovata."),
|
||||
const SizedBox(height: 10),
|
||||
ElevatedButton(
|
||||
onPressed: () => context.read<ServicesCubit>().loadServices(
|
||||
refresh: true,
|
||||
),
|
||||
onPressed: () => context
|
||||
.read<OperationsCubit>()
|
||||
.loadOperations(refresh: true),
|
||||
child: const Text("Riprova"),
|
||||
),
|
||||
],
|
||||
@@ -90,15 +90,15 @@ class _ServicesScreenState extends State<ServicesScreen> {
|
||||
// 3. La Lista (con Pull-to-refresh)
|
||||
return RefreshIndicator(
|
||||
onRefresh: () =>
|
||||
context.read<ServicesCubit>().loadServices(refresh: true),
|
||||
context.read<OperationsCubit>().loadOperations(refresh: true),
|
||||
child: ListView.builder(
|
||||
controller: _scrollController,
|
||||
padding: const EdgeInsets.only(bottom: 80), // Spazio per il FAB
|
||||
itemCount: state.hasReachedMax
|
||||
? state.allServices.length
|
||||
: state.allServices.length + 1,
|
||||
? state.allOperations.length
|
||||
: state.allOperations.length + 1,
|
||||
itemBuilder: (context, index) {
|
||||
if (index >= state.allServices.length) {
|
||||
if (index >= state.allOperations.length) {
|
||||
return const Center(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(16.0),
|
||||
@@ -107,21 +107,21 @@ class _ServicesScreenState extends State<ServicesScreen> {
|
||||
);
|
||||
}
|
||||
|
||||
final operation = state.allServices[index];
|
||||
return _buildServiceCard(context, operation);
|
||||
final operation = state.allOperations[index];
|
||||
return _buildOperationCard(context, operation);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: () => startNewService(context),
|
||||
onPressed: () => startNewOperation(context),
|
||||
child: const Icon(Icons.add),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildServiceCard(BuildContext context, ServiceModel operation) {
|
||||
Widget _buildOperationCard(BuildContext context, OperationModel operation) {
|
||||
return Card(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
|
||||
elevation: 2,
|
||||
@@ -164,11 +164,11 @@ class _ServicesScreenState extends State<ServicesScreen> {
|
||||
children: [
|
||||
if (operation.al > 0 || operation.mnp > 0)
|
||||
_miniBadge("📞 Tel", Colors.blue),
|
||||
if (operation.energyServices.isNotEmpty)
|
||||
if (operation.energyOperations.isNotEmpty)
|
||||
_miniBadge("⚡ Energy", Colors.green),
|
||||
if (operation.finServices.isNotEmpty)
|
||||
if (operation.finOperations.isNotEmpty)
|
||||
_miniBadge("💰 Fin", Colors.purple),
|
||||
if (operation.entertainmentServices.isNotEmpty)
|
||||
if (operation.entertainmentOperations.isNotEmpty)
|
||||
_miniBadge("📺 Ent", Colors.red),
|
||||
],
|
||||
),
|
||||
@@ -180,7 +180,7 @@ class _ServicesScreenState extends State<ServicesScreen> {
|
||||
extra: operation, // <-- LA MAGIA È QUI: Passa l'oggetto intero!
|
||||
// Teniamo anche il parametro URL per coerenza di routing
|
||||
queryParameters: operation.id != null
|
||||
? {'serviceId': operation.id!}
|
||||
? {'operationId': operation.id!}
|
||||
: {},
|
||||
),
|
||||
),
|
||||
Reference in New Issue
Block a user