fg
This commit is contained in:
@@ -208,7 +208,7 @@ class AppRouter {
|
||||
);
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
/* GoRoute(
|
||||
path: '/customer/:id/upload',
|
||||
builder: (context, state) {
|
||||
final customerId = state.pathParameters['id']!;
|
||||
@@ -223,7 +223,7 @@ class AppRouter {
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
), */
|
||||
GoRoute(
|
||||
path: '/operation-form',
|
||||
name: 'operation-form',
|
||||
@@ -255,7 +255,7 @@ class AppRouter {
|
||||
);
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
/* GoRoute(
|
||||
path: '/operation/:id/upload',
|
||||
builder: (context, state) {
|
||||
final operationId = state.pathParameters['id']!;
|
||||
@@ -283,6 +283,29 @@ class AppRouter {
|
||||
),
|
||||
);
|
||||
},
|
||||
), */
|
||||
GoRoute(
|
||||
path: '/upload/:type/:id',
|
||||
builder: (context, state) {
|
||||
final typeString = state.pathParameters['type']!;
|
||||
final id = state.pathParameters['id']!;
|
||||
|
||||
// Trasformiamo la stringa dell'URL nel nostro amato Enum!
|
||||
final parentType = AttachmentParentType.values.firstWhere(
|
||||
(e) => e.name == typeString,
|
||||
orElse: () =>
|
||||
AttachmentParentType.ticket, // Fallback di sicurezza
|
||||
);
|
||||
|
||||
// Creiamo il BLoC "al volo" solo per questa schermata
|
||||
return BlocProvider(
|
||||
create: (context) =>
|
||||
AttachmentsBloc(parentId: id, parentType: parentType),
|
||||
child: const SharedMobileUploadScreen(
|
||||
title: 'Caricamento Rapido',
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flux/core/widgets/qr_upload_dialog.dart';
|
||||
import 'package:flux/core/widgets/shared_forms/mobile_upload_screen.dart';
|
||||
// Adatta gli import alle tue cartelle reali!
|
||||
import 'package:flux/features/attachments/blocs/attachments_bloc.dart';
|
||||
|
||||
class SharedFilesSection extends StatelessWidget {
|
||||
final String
|
||||
titleNameForUpload; // Es. il nome del cliente o il modello da passare alla pagina di upload
|
||||
final String titleNameForUpload;
|
||||
// LA NOSTRA CALLBACK MAGICA
|
||||
final Future<String?> Function()? onGenerateIdForQr;
|
||||
|
||||
const SharedFilesSection({super.key, required this.titleNameForUpload});
|
||||
const SharedFilesSection({
|
||||
super.key,
|
||||
required this.titleNameForUpload,
|
||||
this.onGenerateIdForQr,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -24,22 +29,77 @@ class SharedFilesSection extends StatelessWidget {
|
||||
'Allegati e Foto',
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
TextButton.icon(
|
||||
icon: const Icon(Icons.add_a_photo),
|
||||
label: const Text('Aggiungi'),
|
||||
onPressed: () {
|
||||
// Navighiamo verso la nostra fiammante pagina di upload agnostica!
|
||||
// Assicurati che l'AttachmentsBloc sopravviva al cambio pagina usando BlocProvider.value
|
||||
final bloc = context.read<AttachmentsBloc>();
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (_) => BlocProvider.value(
|
||||
value: bloc,
|
||||
child: SharedMobileUploadScreen(
|
||||
title: titleNameForUpload,
|
||||
|
||||
BlocBuilder<AttachmentsBloc, AttachmentsState>(
|
||||
builder: (context, state) {
|
||||
return Row(
|
||||
children: [
|
||||
// --- IL TASTO QR CODE (Ora sempre attivo!) ---
|
||||
Tooltip(
|
||||
message: 'Carica foto con lo smartphone',
|
||||
child: IconButton(
|
||||
icon: const Icon(Icons.qr_code_scanner),
|
||||
color: theme.colorScheme.primary, // Sempre colorato!
|
||||
onPressed: () async {
|
||||
String? targetId = state.parentId;
|
||||
|
||||
// SE L'ID NON C'È, CHIAMIAMO IL SALVATAGGIO IN BACKGROUND!
|
||||
if (targetId == null) {
|
||||
if (onGenerateIdForQr != null) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text(
|
||||
'Salvataggio rapido scheda in corso... ⏳',
|
||||
),
|
||||
duration: Duration(seconds: 1),
|
||||
),
|
||||
);
|
||||
|
||||
// Aspettiamo che il TicketFormCubit faccia il suo lavoro
|
||||
targetId = await onGenerateIdForQr!();
|
||||
}
|
||||
|
||||
// Se fallisce (es. validazione form non passata), ci fermiamo
|
||||
if (targetId == null) return;
|
||||
}
|
||||
|
||||
// GENERAZIONE DEL DEEP LINK AGNOSTICO
|
||||
final deepLink =
|
||||
'flux://app/upload/${state.parentType.name}/$targetId';
|
||||
|
||||
if (context.mounted) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (_) => QrUploadDialog(
|
||||
deepLinkUrl: deepLink,
|
||||
title: 'Carica File: $titleNameForUpload',
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
|
||||
// --- IL TASTO AGGIUNGI CLASSICO (da PC) ---
|
||||
TextButton.icon(
|
||||
icon: const Icon(Icons.add_a_photo),
|
||||
label: const Text('Aggiungi'),
|
||||
onPressed: () {
|
||||
final bloc = context.read<AttachmentsBloc>();
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (_) => BlocProvider.value(
|
||||
value: bloc,
|
||||
child: SharedMobileUploadScreen(
|
||||
title: titleNameForUpload,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
@@ -47,11 +107,10 @@ class SharedFilesSection extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
|
||||
// LA VETRINA DEI FILE
|
||||
// --- LA VETRINA DEI FILE (Identica a prima) ---
|
||||
BlocBuilder<AttachmentsBloc, AttachmentsState>(
|
||||
builder: (context, state) {
|
||||
final files =
|
||||
state.allFiles; // Unisce sia i remoti che i locali (bozze)
|
||||
final files = state.allFiles;
|
||||
|
||||
if (state.status == AttachmentsStatus.loading) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
@@ -107,21 +166,19 @@ class SharedFilesSection extends StatelessWidget {
|
||||
),
|
||||
child: Stack(
|
||||
children: [
|
||||
// Sfondo File / Anteprima
|
||||
Center(
|
||||
child: isImage
|
||||
? const Icon(
|
||||
Icons.image,
|
||||
color: Colors.blue,
|
||||
size: 40,
|
||||
) // Qui in futuro metteremo Image.network da Supabase
|
||||
)
|
||||
: const Icon(
|
||||
Icons.picture_as_pdf,
|
||||
color: Colors.red,
|
||||
size: 40,
|
||||
),
|
||||
),
|
||||
// Indicatore "Bozza" per i file non ancora caricati
|
||||
if (file.id == null)
|
||||
Positioned(
|
||||
bottom: 4,
|
||||
@@ -144,7 +201,6 @@ class SharedFilesSection extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
// Pulsante Elimina
|
||||
Positioned(
|
||||
top: -8,
|
||||
right: -8,
|
||||
@@ -155,7 +211,6 @@ class SharedFilesSection extends StatelessWidget {
|
||||
size: 20,
|
||||
),
|
||||
onPressed: () {
|
||||
// Manda l'evento di eliminazione
|
||||
context.read<AttachmentsBloc>().add(
|
||||
DeleteSpecificAttachmentEvent(file),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user