Files
flux/lib/features/settings/document_sequence/ui/document_sequence_section.dart

174 lines
6.8 KiB
Dart
Raw Normal View History

2026-05-10 14:09:57 +02:00
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flux/features/settings/document_sequence/blocs/document_sequence_cubit.dart';
2026-05-16 09:04:18 +02:00
import 'package:flux/features/settings/document_sequence/models/document_sequence_model.dart';
2026-05-10 14:09:57 +02:00
class DocumentSequenceSection extends StatelessWidget {
const DocumentSequenceSection({super.key});
2026-05-16 09:04:18 +02:00
// La nostra lista "Ninja" di tutti i documenti gestiti dall'app
// Se domani aggiungo le fatture, basta aggiungere una riga qui!
// e all'enum DocumentType nel model
static final supportedDocumentTypes = [
{
'type': DocumentType.ticket.name,
'label': 'TICKET',
'defaultPrefix': 'TCK',
},
{
'type': DocumentType.shipment.name,
'label': 'DDT (Documento di Trasporto)',
'defaultPrefix': 'DDT',
},
];
2026-05-10 14:09:57 +02:00
@override
Widget build(BuildContext context) {
final year = DateTime.now().year;
return BlocBuilder<DocumentSequenceCubit, DocumentSequenceState>(
builder: (context, state) {
2026-05-16 09:04:18 +02:00
if (state.status == DocumentSequenceStatus.loading) {
2026-05-10 14:09:57 +02:00
return const Center(child: CircularProgressIndicator());
}
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: Text(
"Protocolli e Numerazione",
style: Theme.of(
context,
).textTheme.titleLarge?.copyWith(fontWeight: FontWeight.bold),
),
),
2026-05-16 09:04:18 +02:00
// Invece di mappare state.sequences, mappiamo i documenti supportati
...supportedDocumentTypes.map((docDef) {
final docType = docDef['type']!;
// Cerchiamo se c'è già una configurazione nello stato per questo documento
final existingList = state.sequences
.where((s) => s.docType == docType)
.toList();
final existingSeq = existingList.isNotEmpty
? existingList.first
: null;
// Se esiste usiamo i suoi valori, altrimenti i default
final prefix = existingSeq?.prefix ?? docDef['defaultPrefix']!;
final nextValue = existingSeq?.nextValue ?? 1;
// Anteprima dinamica (aggiornata a 4 zeri come nel DB!)
2026-05-10 14:09:57 +02:00
final preview =
2026-05-16 09:04:18 +02:00
"${prefix.isNotEmpty ? '$prefix-' : ''}$year-${nextValue.toString().padLeft(4, '0')}";
2026-05-10 14:09:57 +02:00
return Card(
margin: const EdgeInsets.only(bottom: 12),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
2026-05-16 09:04:18 +02:00
docDef['label']!,
2026-05-10 14:09:57 +02:00
style: const TextStyle(
fontWeight: FontWeight.bold,
color: Colors.blue,
),
),
const SizedBox(height: 12),
Row(
children: [
Expanded(
flex: 2,
child: TextFormField(
2026-05-16 09:04:18 +02:00
initialValue: prefix,
2026-05-10 14:09:57 +02:00
decoration: const InputDecoration(
labelText: 'Prefisso',
hintText: 'es. TCK',
),
onChanged: (val) => context
.read<DocumentSequenceCubit>()
2026-05-16 09:04:18 +02:00
.updateLocalSequence(docType, prefix: val),
2026-05-10 14:09:57 +02:00
),
),
const SizedBox(width: 16),
Expanded(
flex: 3,
child: TextFormField(
2026-05-16 09:04:18 +02:00
initialValue: nextValue.toString(),
2026-05-10 14:09:57 +02:00
keyboardType: TextInputType.number,
decoration: const InputDecoration(
labelText: 'Prossimo Numero',
),
onChanged: (val) => context
.read<DocumentSequenceCubit>()
.updateLocalSequence(
2026-05-16 09:04:18 +02:00
docType,
2026-05-10 14:09:57 +02:00
nextValue: int.tryParse(val) ?? 1,
),
),
),
],
),
const SizedBox(height: 12),
Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
2026-05-16 09:04:18 +02:00
color: Colors
.grey
.shade100, // Se hai un tema scuro potresti voler usare Theme.of(context).colorScheme.surfaceContainer
2026-05-10 14:09:57 +02:00
borderRadius: BorderRadius.circular(8),
),
child: Row(
children: [
const Icon(
Icons.visibility,
size: 16,
color: Colors.grey,
),
const SizedBox(width: 8),
Text(
"Anteprima prossimo: ",
style: TextStyle(
2026-05-16 09:04:18 +02:00
color: Colors
.grey
.shade700, // Idem per la dark mode
2026-05-10 14:09:57 +02:00
fontSize: 12,
),
),
Text(
preview,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontFamily: 'monospace',
),
),
],
),
),
],
),
),
);
}),
const SizedBox(height: 16),
SizedBox(
width: double.infinity,
child: ElevatedButton.icon(
onPressed: () =>
context.read<DocumentSequenceCubit>().saveSequences(),
icon: const Icon(Icons.save),
label: const Text("SALVA PROTOCOLLI"),
),
),
],
);
},
);
}
}