diff --git a/lib/features/customers/blocs/customer_files_bloc.dart b/lib/features/customers/blocs/customer_files_bloc.dart index ba172ea..ae03aaa 100644 --- a/lib/features/customers/blocs/customer_files_bloc.dart +++ b/lib/features/customers/blocs/customer_files_bloc.dart @@ -17,7 +17,7 @@ class CustomerFilesBloc extends Bloc { : super(const CustomerFilesState(status: CustomerFilesStatus.initial)) { on(_loadCustomerFiles); on(_uploadCustomerFile); - on(_deleteCustomerFile); + on(_deleteCustomerFiles); on(_toggleCustomerFileSelection); } void _loadCustomerFiles( @@ -60,14 +60,16 @@ class CustomerFilesBloc extends Bloc { } } - Future _deleteCustomerFile( + Future _deleteCustomerFiles( DeleteCustomerFileEvent event, Emitter emit, ) async { emit(state.copyWith(status: CustomerFilesStatus.loading)); try { - await _repository.deleteDocument(event.file); - emit(state.copyWith(status: CustomerFilesStatus.success)); + await _repository.deleteDocuments(state.selectedFiles); + emit( + state.copyWith(status: CustomerFilesStatus.success, selectedFiles: []), + ); } catch (e) { emit( state.copyWith( diff --git a/lib/features/customers/blocs/customer_files_events.dart b/lib/features/customers/blocs/customer_files_events.dart index 7d87c49..8bdf725 100644 --- a/lib/features/customers/blocs/customer_files_events.dart +++ b/lib/features/customers/blocs/customer_files_events.dart @@ -15,10 +15,7 @@ class UploadCustomerFileEvent extends CustomerFilesEvent { const UploadCustomerFileEvent({this.pickedFile, this.photo}); } -class DeleteCustomerFileEvent extends CustomerFilesEvent { - final CustomerFileModel file; - const DeleteCustomerFileEvent(this.file); -} +class DeleteCustomerFileEvent extends CustomerFilesEvent {} class ToggleCustomerFileSelectionEvent extends CustomerFilesEvent { final CustomerFileModel file; diff --git a/lib/features/customers/data/customer_repository.dart b/lib/features/customers/data/customer_repository.dart index de5da24..d4a3b68 100644 --- a/lib/features/customers/data/customer_repository.dart +++ b/lib/features/customers/data/customer_repository.dart @@ -1,4 +1,5 @@ import 'package:file_picker/file_picker.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flux/core/blocs/session/session_cubit.dart'; import 'package:flux/core/utils/functions.dart'; import 'package:flux/core/utils/string_extensions.dart'; @@ -174,14 +175,31 @@ class CustomerRepository { .eq('id', id); } - /// Elimina un file dallo storage - Future deleteDocument(CustomerFileModel file) async { + Future deleteDocuments(List files) async { + if (files.isEmpty) return; + + // 1. Prepariamo le liste di ID e di Percorsi + final List idsToDelete = files.map((f) => f.id!).toList(); + final List storagePaths = files.map((f) => f.storagePath).toList(); + try { - final path = await getSignedUrl(file.storagePath); - await _supabase.from('customer_file').delete().eq('id', file.id!); - await _supabase.storage.from('documents').remove([path]); - } on Exception catch (e) { - throw 'Errore durante l\'eliminazione del file: $e'; + // 2. Cancellazione MASSIVA dal DB (una sola chiamata invece di un ciclo!) + // .in_ dice: "cancella tutti i record il cui ID è contenuto in questa lista" + await _supabase + .from('customer_file') + .delete() + .inFilter('id', idsToDelete); + + // 3. Cancellazione MASSIVA dallo Storage + await _supabase.storage.from('documents').remove(storagePaths); + + debugPrint("Eliminati con successo ${files.length} file."); + } on PostgrestException catch (e) { + debugPrint("Errore DB: ${e.message}"); + throw 'Errore database: ${e.message}'; + } catch (e) { + debugPrint("Errore generico: $e"); + throw 'Errore durante l\'eliminazione dei file: $e'; } } } diff --git a/lib/features/customers/ui/customer_detail_screen.dart b/lib/features/customers/ui/customer_detail_screen.dart index d4c79d7..53224b1 100644 --- a/lib/features/customers/ui/customer_detail_screen.dart +++ b/lib/features/customers/ui/customer_detail_screen.dart @@ -190,9 +190,8 @@ class _CustomerDetailScreenState extends State { showDialog( context: context, builder: (context) => QrUploadDialog( - // L'URL dinamico che il telefono digerirà! deepLinkUrl: - 'fluxapp://customer/${widget.customer.id}?action=camera', + 'fluxapp://customer/${widget.customer.id}/upload?name=${Uri.encodeComponent(widget.customer.nome)}', title: 'Scatta per ${widget.customer.nome}', ), );