diff --git a/frontend/lib/widgets/summary_screen.dart b/frontend/lib/widgets/summary_screen.dart new file mode 100644 index 0000000..a623891 --- /dev/null +++ b/frontend/lib/widgets/summary_screen.dart @@ -0,0 +1,248 @@ +import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:go_router/go_router.dart'; +import 'dart:math' as math; +import '../models/card_assets.dart'; +import 'image_button.dart'; + +/// Widget générique pour afficher un écran de récapitulatif +/// Utilisé pour le récapitulatif d'inscription Parents et AM +class SummaryScreen extends StatelessWidget { + final String stepText; + final String title; + final List summaryCards; + final String previousRoute; + final VoidCallback onSubmit; + final String submitButtonText; + + const SummaryScreen({ + super.key, + required this.stepText, + required this.title, + required this.summaryCards, + required this.previousRoute, + required this.onSubmit, + this.submitButtonText = 'Soumettre ma demande', + }); + + void _showConfirmationModal(BuildContext context) { + showDialog( + context: context, + barrierDismissible: false, + builder: (BuildContext ctx) { + return AlertDialog( + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), + backgroundColor: const Color(0xFFF4F1DE), + title: Text('Demande envoyée !', style: GoogleFonts.merienda(fontSize: 20, fontWeight: FontWeight.bold, color: const Color(0xFF2D6A4F)), textAlign: TextAlign.center), + content: Text('Votre demande a bien été enregistrée. Nous reviendrons vers vous prochainement.', style: GoogleFonts.merienda(fontSize: 16, color: Colors.black87), textAlign: TextAlign.center), + actions: [ + Center( + child: ImageButton( + bg: 'assets/images/btn_green.png', + text: 'OK', + textColor: const Color(0xFF2D6A4F), + width: 150, + height: 40, + fontSize: 16, + onPressed: () { + Navigator.of(ctx).pop(); + context.go('/'); + }, + ), + ), + ], + ); + }, + ); + } + + @override + Widget build(BuildContext context) { + final screenSize = MediaQuery.of(context).size; + + return Scaffold( + body: Stack( + children: [ + Positioned.fill( + child: Image.asset('assets/images/paper2.png', fit: BoxFit.cover, repeat: ImageRepeat.repeatY), + ), + Center( + child: SingleChildScrollView( + padding: const EdgeInsets.symmetric(vertical: 40.0), + child: Padding( + padding: EdgeInsets.symmetric(horizontal: screenSize.width / 4.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text(stepText, style: GoogleFonts.merienda(fontSize: 16, color: Colors.black54)), + const SizedBox(height: 20), + Text(title, style: GoogleFonts.merienda(fontSize: 22, fontWeight: FontWeight.bold, color: Colors.black87), textAlign: TextAlign.center), + const SizedBox(height: 30), + + // Cartes de récapitulatif passées en paramètre + ...summaryCards.map((card) => Padding( + padding: const EdgeInsets.only(bottom: 20), + child: card, + )), + + const SizedBox(height: 20), + + ImageButton( + bg: 'assets/images/btn_green.png', + text: submitButtonText, + textColor: const Color(0xFF2D6A4F), + width: 350, + height: 50, + fontSize: 18, + onPressed: () { + onSubmit(); + _showConfirmationModal(context); + }, + ), + ], + ), + ), + ), + ), + // Chevron gauche (retour) + Positioned( + top: screenSize.height / 2 - 20, + left: 40, + child: IconButton( + icon: Transform( + alignment: Alignment.center, + transform: Matrix4.rotationY(math.pi), + child: Image.asset('assets/images/chevron_right.png', height: 40), + ), + onPressed: () { + if (context.canPop()) { + context.pop(); + } else { + context.go(previousRoute); + } + }, + tooltip: 'Retour', + ), + ), + ], + ), + ); + } +} + +/// Helper widget pour créer une carte de récapitulatif avec un titre et un contenu +class SummaryCard extends StatelessWidget { + final String title; + final String backgroundImagePath; + final List content; + final VoidCallback? onEdit; + + const SummaryCard({ + super.key, + required this.title, + required this.backgroundImagePath, + required this.content, + this.onEdit, + }); + + @override + Widget build(BuildContext context) { + return AspectRatio( + aspectRatio: 2.0, + child: Container( + padding: const EdgeInsets.symmetric(vertical: 20.0, horizontal: 25.0), + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage(backgroundImagePath), + fit: BoxFit.cover, + ), + borderRadius: BorderRadius.circular(15), + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Align( + alignment: Alignment.center, + child: Text( + title, + style: GoogleFonts.merienda( + fontSize: 22, + fontWeight: FontWeight.bold, + color: Colors.black87, + ), + textAlign: TextAlign.center, + ), + ), + const SizedBox(height: 15), + Expanded( + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: content, + ), + ), + ), + ], + ), + ), + if (onEdit != null) ...[ + const SizedBox(width: 15), + Align( + alignment: Alignment.center, + child: IconButton( + icon: Image.asset('assets/images/input_field_bg.png', height: 35), + tooltip: 'Modifier', + onPressed: onEdit, + ), + ), + ], + ], + ), + ), + ); + } +} + +/// Fonction helper pour afficher un champ de type "lecture seule" stylisé +Widget buildDisplayFieldValue( + BuildContext context, + String label, + String value, { + bool multiLine = false, + double fieldHeight = 50.0, + double labelFontSize = 18.0, +}) { + const FontWeight labelFontWeight = FontWeight.w600; + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(label, style: GoogleFonts.merienda(fontSize: labelFontSize, fontWeight: labelFontWeight)), + const SizedBox(height: 4), + Container( + width: double.infinity, + height: multiLine ? null : fieldHeight, + constraints: multiLine ? const BoxConstraints(minHeight: 50.0) : null, + padding: const EdgeInsets.symmetric(horizontal: 18.0, vertical: 12.0), + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/images/input_field_bg.png'), + fit: BoxFit.fill, + ), + ), + child: Text( + value.isNotEmpty ? value : '-', + style: GoogleFonts.merienda(fontSize: labelFontSize), + maxLines: multiLine ? null : 1, + overflow: multiLine ? TextOverflow.visible : TextOverflow.ellipsis, + ), + ), + ], + ); +}