import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import '../config/display_config.dart'; import '../models/card_assets.dart'; import 'hover_relief_widget.dart'; import 'image_button.dart'; /// Widget de base générique pour tous les écrans de formulaire /// Gère automatiquement le layout, les boutons de navigation, etc. class BaseFormScreen extends StatelessWidget { /// Configuration d'affichage final DisplayConfig config; /// Texte de l'étape (ex: "Étape 1/4") final String stepText; /// Titre du formulaire final String title; /// Couleur de la carte (horizontal pour desktop) final CardColorHorizontal cardColor; /// Contenu du formulaire final Widget content; /// Texte du bouton de soumission (par défaut "Suivant") final String? submitButtonText; /// Callback de soumission final VoidCallback onSubmit; /// Route précédente (pour le bouton retour) final String previousRoute; /// Widget supplémentaire au-dessus du contenu (ex: toggle) final Widget? headerWidget; /// Widget supplémentaire en dessous du contenu (ex: checkbox CGU) final Widget? footerWidget; /// Padding personnalisé pour le contenu final EdgeInsets? contentPadding; const BaseFormScreen({ super.key, required this.config, required this.stepText, required this.title, required this.cardColor, required this.content, required this.onSubmit, required this.previousRoute, this.submitButtonText, this.headerWidget, this.footerWidget, this.contentPadding, }); @override Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color(0xFFFFF8E1), body: SafeArea( child: SingleChildScrollView( padding: EdgeInsets.all( LayoutHelper.getSpacing(context, mobileSpacing: 16.0, desktopSpacing: 32.0, ), ), child: Center( child: ConstrainedBox( constraints: BoxConstraints( maxWidth: LayoutHelper.getMaxWidth(context), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Texte de l'étape Text( stepText, style: GoogleFonts.merienda( fontSize: config.isMobile ? 14 : 16, fontWeight: FontWeight.w500, color: const Color(0xFF6D4C41), ), ), const SizedBox(height: 8), // Titre Text( title, style: GoogleFonts.merienda( fontSize: config.isMobile ? 24 : 32, fontWeight: FontWeight.bold, color: const Color(0xFF4A4A4A), ), ), const SizedBox(height: 24), // Header widget (si fourni) if (headerWidget != null) ...[ headerWidget!, const SizedBox(height: 16), ], // Carte principale _buildCard(context), const SizedBox(height: 24), // Footer widget (si fourni) if (footerWidget != null) ...[ footerWidget!, const SizedBox(height: 24), ], // Boutons de navigation _buildNavigationButtons(context), ], ), ), ), ), ), ); } /// Construit la carte principale Widget _buildCard(BuildContext context) { final effectivePadding = contentPadding ?? EdgeInsets.all( LayoutHelper.getSpacing(context, mobileSpacing: 16.0, desktopSpacing: 32.0, ), ); if (config.isMobile) { // Carte verticale sur mobile return Container( decoration: BoxDecoration( image: DecorationImage( image: AssetImage(_getVerticalCardAsset()), fit: BoxFit.fill, ), ), child: Padding( padding: effectivePadding, child: content, ), ); } else { // Carte horizontale sur desktop return Container( decoration: BoxDecoration( image: DecorationImage( image: AssetImage(cardColor.path), fit: BoxFit.fill, ), ), child: Padding( padding: effectivePadding, child: content, ), ); } } /// Retourne l'asset de carte vertical correspondant à la couleur String _getVerticalCardAsset() { // Mapping couleur horizontale -> verticale switch (cardColor) { case CardColorHorizontal.blue: return CardColorVertical.blue.path; case CardColorHorizontal.green: return CardColorVertical.green.path; case CardColorHorizontal.lavender: return CardColorVertical.lavender.path; case CardColorHorizontal.lime: return CardColorVertical.lime.path; case CardColorHorizontal.peach: return CardColorVertical.peach.path; case CardColorHorizontal.pink: return CardColorVertical.pink.path; case CardColorHorizontal.red: return CardColorVertical.red.path; } } /// Construit les boutons de navigation Widget _buildNavigationButtons(BuildContext context) { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ // Bouton Précédent HoverReliefWidget( child: ImageButton( bg: 'assets/images/bg_green.png', text: 'Précédent', textColor: Colors.white, onPressed: () => Navigator.pushNamed(context, previousRoute), width: config.isMobile ? 120 : 150, height: config.isMobile ? 40 : 50, ), ), // Bouton Suivant/Soumettre HoverReliefWidget( child: ImageButton( bg: 'assets/images/bg_green.png', text: submitButtonText ?? 'Suivant', textColor: Colors.white, onPressed: config.isReadonly ? onSubmit : () { // En mode éditable, valider avant de soumettre onSubmit(); }, width: config.isMobile ? 120 : 150, height: config.isMobile ? 40 : 50, ), ), ], ); } }