fix supabase storage
This commit is contained in:
@@ -132,7 +132,6 @@ class ServicesCubit extends Cubit<ServicesState> {
|
||||
companyId: _sessionBloc.state.company!.id,
|
||||
),
|
||||
status: ServicesStatus.ready,
|
||||
files: [],
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -212,7 +211,7 @@ class ServicesCubit extends Cubit<ServicesState> {
|
||||
final serviceToSave = state.currentService!.copyWith(isBozza: isBozza);
|
||||
|
||||
// 2. Salvataggio corazzato
|
||||
await _repository.saveFullService(serviceToSave, state.files);
|
||||
await _repository.saveFullService(serviceToSave);
|
||||
|
||||
// 3. Reset e ricaricamento
|
||||
emit(state.copyWith(status: ServicesStatus.saved, currentService: null));
|
||||
@@ -230,31 +229,33 @@ class ServicesCubit extends Cubit<ServicesState> {
|
||||
// --- GESTIONE ALLEGATI LOCALI ---
|
||||
|
||||
void addAttachments(List<PlatformFile> files) {
|
||||
// Trasformiamo i PlatformFile in ServiceFileModel "temporanei"
|
||||
final newAttachments = files.map((file) {
|
||||
return ServiceFileModel(
|
||||
id: '', // ID vuoto perché non ancora su DB
|
||||
id: null, // Meglio null se non è su DB
|
||||
serviceId: state.currentService?.id ?? '',
|
||||
name: file.name.fileNameWithoutExtension(),
|
||||
extension: file.name.fileExtension(),
|
||||
url: '', // URL vuoto perché non ancora caricato
|
||||
url: '',
|
||||
fileSize: file.size,
|
||||
localBytes: file.bytes, // Fondamentale per l'upload!
|
||||
localBytes: file.bytes,
|
||||
createdAt: DateTime.now(),
|
||||
);
|
||||
}).toList();
|
||||
|
||||
// Uniamo i file esistenti (remoti + locali già aggiunti) con i nuovi
|
||||
final updatedList = [
|
||||
// Creiamo una nuova lista pulita
|
||||
final List<ServiceFileModel> updatedList = [
|
||||
...(state.currentService?.files ?? []),
|
||||
...newAttachments,
|
||||
];
|
||||
|
||||
emit(
|
||||
state.copyWith(
|
||||
currentService: state.currentService?.copyWith(files: updatedList),
|
||||
),
|
||||
);
|
||||
// Emettiamo lo stato assicurandoci che il ServiceModel venga clonato
|
||||
if (state.currentService != null) {
|
||||
emit(
|
||||
state.copyWith(
|
||||
currentService: state.currentService!.copyWith(files: updatedList),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void removeAttachment(int index) {
|
||||
@@ -295,7 +296,9 @@ class ServicesCubit extends Cubit<ServicesState> {
|
||||
);
|
||||
|
||||
if (savedFile.url.isEmpty) {
|
||||
throw Exception("Errore: URL del file non trovato dopo il salvataggio.");
|
||||
throw Exception(
|
||||
"Errore: URL del file non trovato dopo il salvataggio.",
|
||||
);
|
||||
}
|
||||
|
||||
// 3. Chiamiamo il repository per la copia fisica nel database del cliente
|
||||
@@ -308,12 +311,13 @@ class ServicesCubit extends Cubit<ServicesState> {
|
||||
// 4. Feedback all'utente
|
||||
// Potresti emettere un successo o mostrare un toast
|
||||
emit(state.copyWith(status: ServicesStatus.success));
|
||||
|
||||
} catch (e) {
|
||||
emit(state.copyWith(
|
||||
status: ServicesStatus.failure,
|
||||
errorMessage: "Errore durante la copia del file: $e",
|
||||
));
|
||||
emit(
|
||||
state.copyWith(
|
||||
status: ServicesStatus.failure,
|
||||
errorMessage: "Errore durante la copia del file: $e",
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ class ServicesState extends Equatable {
|
||||
final String query;
|
||||
final DateTimeRange? dateRange;
|
||||
final bool hasReachedMax;
|
||||
final List<ServiceFileModel> files;
|
||||
|
||||
const ServicesState({
|
||||
required this.status,
|
||||
@@ -20,7 +19,6 @@ class ServicesState extends Equatable {
|
||||
this.query = '',
|
||||
this.dateRange,
|
||||
this.hasReachedMax = false,
|
||||
this.files = const [],
|
||||
});
|
||||
|
||||
ServicesState copyWith({
|
||||
@@ -31,7 +29,6 @@ class ServicesState extends Equatable {
|
||||
String? query,
|
||||
DateTimeRange? dateRange,
|
||||
bool? hasReachedMax,
|
||||
List<ServiceFileModel>? files,
|
||||
}) {
|
||||
return ServicesState(
|
||||
status: status ?? this.status,
|
||||
@@ -41,7 +38,6 @@ class ServicesState extends Equatable {
|
||||
query: query ?? this.query,
|
||||
dateRange: dateRange ?? this.dateRange,
|
||||
hasReachedMax: hasReachedMax ?? this.hasReachedMax,
|
||||
files: files ?? this.files,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -54,6 +50,5 @@ class ServicesState extends Equatable {
|
||||
query,
|
||||
dateRange,
|
||||
hasReachedMax,
|
||||
files,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -83,10 +83,7 @@ class ServicesRepository {
|
||||
}
|
||||
|
||||
// --- SALVATAGGIO COMPLETO (PRIMA PADRE, POI FIGLI) ---
|
||||
Future<void> saveFullService(
|
||||
ServiceModel service,
|
||||
List<ServiceFileModel> files,
|
||||
) async {
|
||||
Future<void> saveFullService(ServiceModel service) async {
|
||||
try {
|
||||
// 1. Upsert del record principale
|
||||
final serviceData = await _supabase
|
||||
@@ -153,16 +150,16 @@ class ServicesRepository {
|
||||
if (insertTasks.isNotEmpty) {
|
||||
await Future.wait(insertTasks);
|
||||
}
|
||||
if (files.isNotEmpty) {
|
||||
if (service.files.isNotEmpty) {
|
||||
final List<Future> uploadTasks = [];
|
||||
|
||||
for (var file in files) {
|
||||
for (var file in service.files) {
|
||||
final storagePath =
|
||||
'$companyId/services/$newId/${DateTime.now().millisecondsSinceEpoch}_${file.name}.${file.extension}';
|
||||
final String mimeType = file.extension.toLowerCase() == 'pdf'
|
||||
? 'application/pdf'
|
||||
: 'image/${file.extension}';
|
||||
final fileToSave = file.copyWith(serviceId: newId);
|
||||
final fileToSave = file.copyWith(serviceId: newId, url: storagePath);
|
||||
|
||||
// Creiamo una funzione asincrona per caricare file e scrivere nel DB
|
||||
Future<void> uploadAndLink() async {
|
||||
@@ -182,13 +179,7 @@ class ServicesRepository {
|
||||
),
|
||||
);
|
||||
|
||||
// B. Otteniamo l'URL pubblico e scriviamo il record del file nel DB
|
||||
final String publicUrl = _supabase.storage
|
||||
.from('documents')
|
||||
.getPublicUrl(storagePath);
|
||||
await _supabase
|
||||
.from('service_file')
|
||||
.insert(fileToSave.copyWith(url: publicUrl).toMap());
|
||||
await _supabase.from('service_file').insert(fileToSave.toMap());
|
||||
}
|
||||
|
||||
uploadTasks.add(uploadAndLink());
|
||||
|
||||
@@ -93,5 +93,6 @@ class ServiceFileModel extends Equatable {
|
||||
url,
|
||||
serviceId,
|
||||
fileSize,
|
||||
localBytes,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ class AttachmentsSection extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<ServicesCubit, ServicesState>(
|
||||
builder: (context, state) {
|
||||
final files = state.files;
|
||||
final files = state.currentService?.files ?? [];
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@@ -168,8 +168,14 @@ class AttachmentsSection extends StatelessWidget {
|
||||
width: double.infinity,
|
||||
height: MediaQuery.of(context).size.height * 0.8,
|
||||
child: file.isPdf
|
||||
? PdfViewerWidget(url: file.url)
|
||||
: ImageViewerWidget(url: file.url),
|
||||
? PdfViewerWidget(
|
||||
storagePath: file.url.isNotEmpty ? file.url : null,
|
||||
bytes: file.localBytes,
|
||||
)
|
||||
: ImageViewerWidget(
|
||||
storagePath: file.url.isNotEmpty ? file.url : null,
|
||||
bytes: file.localBytes,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user