// Versione: FINAL - SLIVER LAYOUT (Footer Sicuro e Testi Corretti) import 'package:flutter/material.dart'; import 'global_data.dart'; import 'comp_13.dart'; // IMPORTA IL GRAFICO import 'comp_15.dart'; // IMPORTA LE FIRME class Comp12Screen extends StatefulWidget { const Comp12Screen({super.key}); @override _Comp12ScreenState createState() => _Comp12ScreenState(); } class _Comp12ScreenState extends State { final List _testiCircostanze = [ "1. In fermata / in sosta", "2. Ripartiva dopo una sosta / apriva una portiera", "3. Stava parcheggiando", "4. Usciva da un parcheggio / luogo privato", "5. Entrava in un parcheggio / luogo privato", "6. Si immetteva in una piazza a senso rotatorio", "7. Circolava su una piazza a senso rotatorio", "8. Tamponava procedendo nello stesso senso", "9. Procedeva nello stesso senso ma in fila diversa", "10. Cambiava fila", "11. Sorpassava", "12. Girava a destra", "13. Girava a sinistra", "14. Retrocedeva", "15. Invadeva la sede stradale riservata", "16. Proveniva da destra", "17. Non osservava il segnale di precedenza/semaforo" ]; bool _isReady = false; @override void initState() { super.initState(); _inizializzaPagina(); } Future _inizializzaPagina() async { await Future.delayed(const Duration(milliseconds: 200)); if (mounted) { setState(() => _isReady = true); // MOSTRA IL POPUP ANIMATO ALL'AVVIO WidgetsBinding.instance.addPostFrameCallback((_) => _mostraInfoPopup(context)); } } // --- POPUP INFORMATIVO ANIMATO --- void _mostraInfoPopup(BuildContext context) { bool isB = GlobalData.latoCorrente == 'B'; Color activeColor = isB ? Colors.amber.shade700 : Colors.blue.shade900; showGeneralDialog( context: context, barrierDismissible: false, barrierLabel: "Popup", barrierColor: Colors.black.withOpacity(0.5), transitionDuration: const Duration(milliseconds: 400), pageBuilder: (context, animation, secondaryAnimation) { return AlertDialog( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), title: Row( children: [ Icon(Icons.fact_check, color: activeColor, size: 28), const SizedBox(width: 10), const Expanded(child: Text("Circostanze Incidente", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18))), ], ), content: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Text("Indica l'esatta dinamica del Veicolo ${GlobalData.latoCorrente} al momento dell'urto.", style: const TextStyle(fontSize: 15)), const SizedBox(height: 16), _buildPopupRow(Icons.check_box_outlined, "Selezione Multipla", "Puoi spuntare anche più di una circostanza, ma assicurati che descrivano correttamente l'accaduto."), const SizedBox(height: 12), _buildPopupRow(Icons.warning_amber_rounded, "Attenzione", "Le circostanze selezionate in questa pagina sono fondamentali per stabilire la responsabilità del sinistro!"), ], ), ), actions: [ SizedBox( width: double.infinity, child: ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: activeColor, foregroundColor: isB ? Colors.black87 : Colors.white, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), padding: const EdgeInsets.symmetric(vertical: 14), ), onPressed: () => Navigator.pop(context), child: const Text("HO CAPITO", style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), ), ), ], ); }, transitionBuilder: (context, animation, secondaryAnimation, child) { var curvePosizione = CurvedAnimation( parent: animation, curve: Curves.easeOutBack, reverseCurve: Curves.easeInBack, ); var curveOpacita = CurvedAnimation( parent: animation, curve: Curves.easeOut, reverseCurve: Curves.easeIn, ); return SlideTransition( position: Tween( begin: const Offset(0.0, 0.4), end: Offset.zero, ).animate(curvePosizione), child: FadeTransition( opacity: curveOpacita, child: child, ), ); }, ); } Widget _buildPopupRow(IconData icon, String title, String desc) { return Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Icon(icon, size: 24, color: Colors.blueGrey), const SizedBox(width: 12), Expanded( child: RichText( text: TextSpan( style: const TextStyle(fontSize: 14, color: Colors.black87, height: 1.4), children: [ TextSpan(text: "$title: ", style: const TextStyle(fontWeight: FontWeight.bold)), TextSpan(text: desc), ], ), ), ), ], ); } void _prosegui() { bool isB = GlobalData.latoCorrente == 'B'; if (isB) { // IL LATO B SALTA IL GRAFICO E VA DIRETTAMENTE ALLE FIRME (15) Navigator.push( context, MaterialPageRoute(builder: (context) => const Comp15Screen()), ); } else { // IL LATO A VA AL GRAFICO (13) Navigator.push( context, MaterialPageRoute(builder: (context) => const Comp13Screen()), ); } } @override Widget build(BuildContext context) { bool isB = GlobalData.latoCorrente == 'B'; Color mainCol = isB ? Colors.amber.shade700 : Colors.blue.shade900; Color bgCol = isB ? const Color(0xFFFFF9C4) : const Color(0xFFF5F7FA); if (!_isReady) { return Scaffold(backgroundColor: bgCol, body: Container()); } return Scaffold( backgroundColor: bgCol, appBar: AppBar( title: Text("12. Circostanze (${GlobalData.latoCorrente})"), backgroundColor: mainCol, foregroundColor: isB ? Colors.black : Colors.white, ), // --- SLIVER LAYOUT --- body: SafeArea( child: CustomScrollView( physics: const BouncingScrollPhysics(), slivers: [ // 1. Header (Testo Istruzioni) SliverToBoxAdapter( child: Container( padding: const EdgeInsets.all(15), color: Colors.white, margin: const EdgeInsets.only(bottom: 1), child: Text( "Seleziona le circostanze per il veicolo ${GlobalData.latoCorrente}.", style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold, color: mainCol), ), ), ), // 2. Lista Scrollabile (Le 17 Checkbox) SliverList( delegate: SliverChildBuilderDelegate( (context, index) { int circIndex = index + 1; bool isChecked = isB ? (GlobalData.circostanzeB[circIndex] ?? false) : (GlobalData.circostanzeA[circIndex] ?? false); return Column( children: [ Container( color: Colors.white, child: CheckboxListTile( activeColor: mainCol, contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4), title: Text("${circIndex}. ${_testiCircostanze[index]}", style: const TextStyle(fontSize: 14)), value: isChecked, onChanged: (bool? val) { setState(() { if (isB) { GlobalData.circostanzeB[circIndex] = val ?? false; } else { GlobalData.circostanzeA[circIndex] = val ?? false; } }); }, ), ), const Divider(height: 1, thickness: 1, indent: 16, endIndent: 16), ], ); }, childCount: _testiCircostanze.length, ), ), // 3. Piè di pagina elastico (Bottoni) SliverFillRemaining( hasScrollBody: false, child: Align( alignment: Alignment.bottomCenter, child: Container( padding: const EdgeInsets.all(20), child: _navButtons(context, mainCol, isB), ), ), ), ], ), ), ); } Widget _navButtons(BuildContext context, Color color, bool isB) { return Row( children: [ // Tasto INDIETRO (Expanded flex 1) Expanded( flex: 4, // Proporzione 4/10 child: OutlinedButton( onPressed: () => Navigator.pop(context), style: OutlinedButton.styleFrom( minimumSize: const Size(0, 55), padding: const EdgeInsets.symmetric(horizontal: 5), // Padding ridotto ), // FittedBox evita che il testo vada a capo se lo spazio è poco child: const FittedBox( child: Text("INDIETRO", style: TextStyle(fontWeight: FontWeight.bold)) ) ) ), const SizedBox(width: 15), // Tasto SALVA E PROCEDI (Expanded flex 2) Expanded( flex: 6, // Proporzione 6/10 (più largo) child: ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: color, foregroundColor: isB ? Colors.black : Colors.white, minimumSize: const Size(0, 55) ), onPressed: _prosegui, child: const FittedBox( child: Text("SALVA E PROCEDI", style: TextStyle(fontWeight: FontWeight.bold)) ) ) ), ], ); } }