feat-add-files-from-qr #8

Merged
brontomark merged 13 commits from feat-add-files-from-qr into main 2026-04-26 10:15:35 +02:00
3 changed files with 229 additions and 193 deletions
Showing only changes of commit a634e05052 - Show all commits

View File

@@ -131,9 +131,13 @@ class AppRouter {
// Recuperiamo l'ID se presente nell'URL
final serviceId = state.uri.queryParameters['serviceId'];
return ServiceFormScreen(
return BlocProvider(
create: (context) =>
ServiceFilesBloc(serviceId: serviceId ?? existingService?.id),
child: ServiceFormScreen(
serviceId: serviceId ?? existingService?.id,
existingService: existingService,
),
);
},
),

View File

@@ -36,17 +36,34 @@ class ServiceFilesBloc extends Bloc<ServiceFilesEvent, ServiceFilesState> {
ServiceSavedEvent event,
Emitter<ServiceFilesState> emit,
) {
emit(state.copyWith(serviceId: event.serviceId));
// 1. Aggiorniamo l'ID nello stato
// 2. PIALLIAMO i file locali: ormai sono partiti per Supabase!
// Così la UI si pulisce all'istante e aspetta quelli remoti.
emit(
state.copyWith(
serviceId: event.serviceId,
localFiles: [], // <-- LA MAGIA ANTI-DUPLICATI
),
);
// Lanciamo il caricamento
add(LoadServiceFilesEvent(serviceId: event.serviceId));
}
FutureOr<void> _onLoadServiceFiles(
LoadServiceFilesEvent event,
Emitter<ServiceFilesState> emit,
) async {
if (serviceId != null) {
// Usiamo l'ID dell'evento, e se non c'è usiamo quello dello stato
final currentId = event.serviceId ?? state.serviceId;
if (currentId != null) {
emit(state.copyWith(status: ServiceFilesStatus.loading));
await emit.forEach(
_repository.getServiceFilesStream(serviceId!),
_repository.getServiceFilesStream(
currentId,
), // <-- Usiamo l'ID corretto!
onData: (data) => state.copyWith(
status: ServiceFilesStatus.success,
remoteFiles: data,

View File

@@ -5,6 +5,7 @@ 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/customers/blocs/customer_files_bloc.dart';
import 'package:flux/features/services/blocs/service_files_bloc.dart';
import 'package:flux/features/services/blocs/services_cubit.dart';
import 'package:flux/features/services/models/service_file_model.dart';
@@ -32,7 +33,17 @@ class AttachmentsSection extends StatelessWidget {
context,
);
return BlocBuilder<ServiceFilesBloc, ServiceFilesState>(
return BlocListener<ServicesCubit, ServicesState>(
listenWhen: (previous, current) =>
previous.currentService?.id == null &&
current.currentService?.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));
},
child: BlocBuilder<ServiceFilesBloc, ServiceFilesState>(
builder: (context, state) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
@@ -56,7 +67,10 @@ class AttachmentsSection extends StatelessWidget {
label: const Text("Aggiungi File"),
onPressed: () => _pickFiles(context),
),
if (!context.read<SessionCubit>().state.isMobileDevice) ...[
if (!context
.read<SessionCubit>()
.state
.isMobileDevice) ...[
const SizedBox(width: 12),
ElevatedButton.icon(
onPressed: () => _handleGenerateQr(context),
@@ -149,7 +163,7 @@ class AttachmentsSection extends StatelessWidget {
overflow: TextOverflow.ellipsis,
),
subtitle: Text(
file.isLocal ? "$sizeMb MB • (Nuovo)" : "$sizeMb MB",
file.isLocal ? "$sizeMb MB • (Nuovo)" : " MB",
),
trailing: Icon(
isPdf ? Icons.picture_as_pdf : Icons.image,
@@ -226,13 +240,14 @@ class AttachmentsSection extends StatelessWidget {
],
);
},
),
);
}
Future<void> _handleGenerateQr(BuildContext context) async {
final cubit = context.read<ServicesCubit>();
var currentService = cubit.state.currentService;
final Navigator = Navigator.of(context);
final navigator = Navigator.of(context);
// 1. SE LA PRATICA E' NUOVA (Manca l'ID)
if (currentService == null || currentService.id == null) {
@@ -242,7 +257,7 @@ class AttachmentsSection extends StatelessWidget {
builder: (ctx) => BlocListener<ServiceFilesBloc, ServiceFilesState>(
listener: (context, state) {
if (state.status == ServiceFilesStatus.success) {
Navigator.of.context(ctx).pop();
navigator.pop();
}
},
child: AlertDialog(