From de431b6ee68cdaaea3a8d595922a1432a4189794 Mon Sep 17 00:00:00 2001 From: Mark M2 Macbook Date: Sat, 25 Apr 2026 08:30:38 +0200 Subject: [PATCH] fixes Co-authored-by: Copilot --- .../services/blocs/service_files_bloc.dart | 24 ++++++++- .../services/blocs/service_files_events.dart | 8 +-- .../attachment_section.dart | 2 +- .../service_mobile_upload_screen.dart | 53 ++++++++++++++++--- 4 files changed, 73 insertions(+), 14 deletions(-) diff --git a/lib/features/services/blocs/service_files_bloc.dart b/lib/features/services/blocs/service_files_bloc.dart index 85bf3c8..f22214a 100644 --- a/lib/features/services/blocs/service_files_bloc.dart +++ b/lib/features/services/blocs/service_files_bloc.dart @@ -128,7 +128,29 @@ class ServiceFilesBloc extends Bloc { FutureOr _onUploadServiceFiles( UploadServiceFilesEvent event, Emitter emit, - ) {} + ) async { + if (event.pickedFiles == null && event.photos == null) return; + if (event.pickedFiles!.isEmpty && event.photos!.isEmpty) return; + + // BIVIO 2: PRATICA ESISTENTE (Abbiamo l'ID + emit(state.copyWith(status: ServiceFilesStatus.uploading)); + try { + // Logica identica a quella che abbiamo fatto per i clienti + if (event.pickedFiles != null && event.pickedFiles!.isNotEmpty) { + for (var file in event.pickedFiles!) { + await _repository.uploadAndRegisterServiceFile( + serviceId: serviceId!, + pickedFile: file, + ); + } + } + emit(state.copyWith(status: ServiceFilesStatus.success)); + } catch (e) { + emit( + state.copyWith(status: ServiceFilesStatus.failure, error: e.toString()), + ); + } + } FutureOr _onDeleteServiceFiles( DeleteServiceFilesEvent event, diff --git a/lib/features/services/blocs/service_files_events.dart b/lib/features/services/blocs/service_files_events.dart index cb794ef..d1a0de7 100644 --- a/lib/features/services/blocs/service_files_events.dart +++ b/lib/features/services/blocs/service_files_events.dart @@ -33,12 +33,12 @@ class AddServiceFilesEvent extends ServiceFilesEvent { } class UploadServiceFilesEvent extends ServiceFilesEvent { - final PlatformFile? pickedFile; - final File? photo; - const UploadServiceFilesEvent({this.pickedFile, this.photo}); + final List? pickedFiles; + final List? photos; + const UploadServiceFilesEvent({this.pickedFiles, this.photos}); @override - List get props => [pickedFile, photo]; + List get props => [pickedFiles, photos]; } class DeleteServiceFilesEvent extends ServiceFilesEvent {} diff --git a/lib/features/services/ui/service_form_screen/attachment_section.dart b/lib/features/services/ui/service_form_screen/attachment_section.dart index 1558277..622db8f 100644 --- a/lib/features/services/ui/service_form_screen/attachment_section.dart +++ b/lib/features/services/ui/service_form_screen/attachment_section.dart @@ -308,7 +308,7 @@ class AttachmentsSection extends StatelessWidget { }, child: QrUploadDialog( deepLinkUrl: - 'fluxapp://service/${currentService!.id}/upload?name=${Uri.encodeComponent(nomePratica)}', + 'fluxapp:///service/${currentService!.id}/upload?name=${Uri.encodeComponent(nomePratica)}', title: 'Scatta per\n$nomePratica', ), ), diff --git a/lib/features/services/ui/service_form_screen/service_mobile_upload_screen.dart b/lib/features/services/ui/service_form_screen/service_mobile_upload_screen.dart index a093579..6fbb01c 100644 --- a/lib/features/services/ui/service_form_screen/service_mobile_upload_screen.dart +++ b/lib/features/services/ui/service_form_screen/service_mobile_upload_screen.dart @@ -5,7 +5,7 @@ import 'package:image_picker/image_picker.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flux/features/services/blocs/service_files_bloc.dart'; -class ServiceMobileUploadScreen extends StatelessWidget { +class ServiceMobileUploadScreen extends StatefulWidget { final String serviceId; final String serviceName; @@ -15,6 +15,15 @@ class ServiceMobileUploadScreen extends StatelessWidget { required this.serviceName, }); + @override + State createState() => + _ServiceMobileUploadScreenState(); +} + +class _ServiceMobileUploadScreenState extends State { + final List _pickedFiles = []; + final List _photos = []; + @override Widget build(BuildContext context) { return BlocListener( @@ -31,7 +40,7 @@ class ServiceMobileUploadScreen extends StatelessWidget { } }, child: Scaffold( - appBar: AppBar(title: Text("Upload Pratica:\n$serviceName")), + appBar: AppBar(title: Text("Upload Pratica:\n${widget.serviceName}")), body: Padding( padding: const EdgeInsets.all(24.0), child: Column( @@ -74,6 +83,27 @@ class ServiceMobileUploadScreen extends StatelessWidget { ), ), ), + + const SizedBox(height: 30), + SizedBox( + width: double.infinity, + height: 80, + child: ElevatedButton.icon( + onPressed: () => _handleSaveAndClose(context), + icon: const Icon(Icons.save_alt_rounded, size: 28), + label: const Text( + "INVIA E CHIUDI", + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + ), + style: ElevatedButton.styleFrom( + backgroundColor: Colors.grey[200], + foregroundColor: Colors.black87, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + ), + ), + ), + ), ], ), ), @@ -88,18 +118,25 @@ class ServiceMobileUploadScreen extends StatelessWidget { imageQuality: 80, ); if (photo != null && context.mounted) { - context.read().add( - UploadServiceFilesEvent(photo: File(photo.path)), - ); + setState(() { + _photos.add(File(photo.path)); + }); } } Future _handleFilePicker(BuildContext context) async { final result = await FilePicker.pickFiles(withData: true); if (result != null && context.mounted) { - context.read().add( - UploadServiceFilesEvent(pickedFile: result.files.first), - ); + setState(() { + _pickedFiles.addAll(result.files); + }); } } + + Future _handleSaveAndClose(BuildContext context) async { + context.read().add( + UploadServiceFilesEvent(pickedFiles: _pickedFiles, photos: _photos), + ); + Navigator.pop(context); + } }