438 lines
18 KiB
Dart
438 lines
18 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:google_fonts/google_fonts.dart';
|
|
import '../../models/user_registration_data.dart'; // Utilisation du vrai modèle
|
|
import '../../widgets/image_button.dart'; // Import du ImageButton
|
|
import '../../models/card_assets.dart'; // Import des enums de cartes
|
|
import 'package:flutter/foundation.dart' show kIsWeb;
|
|
|
|
// Nouvelle méthode 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, // Prendra la largeur allouée par son parent (Expanded)
|
|
height: multiLine ? null : fieldHeight, // Hauteur flexible pour multiligne, sinon fixe
|
|
constraints: multiLine ? const BoxConstraints(minHeight: 50.0) : null, // Hauteur min pour multiligne
|
|
padding: const EdgeInsets.symmetric(horizontal: 18.0, vertical: 12.0), // Ajuster au besoin
|
|
decoration: BoxDecoration(
|
|
image: const DecorationImage(
|
|
image: AssetImage('assets/images/input_field_bg.png'), // Image de fond du champ
|
|
fit: BoxFit.fill,
|
|
),
|
|
// Si votre image input_field_bg.png a des coins arrondis intrinsèques, ce borderRadius n'est pas nécessaire
|
|
// ou doit correspondre. Sinon, pour une image rectangulaire, vous pouvez l'ajouter.
|
|
// borderRadius: BorderRadius.circular(12),
|
|
),
|
|
child: Text(
|
|
value.isNotEmpty ? value : '-',
|
|
style: GoogleFonts.merienda(fontSize: labelFontSize),
|
|
maxLines: multiLine ? null : 1, // Permet plusieurs lignes si multiLine est true
|
|
overflow: multiLine ? TextOverflow.visible : TextOverflow.ellipsis,
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
class ParentRegisterStep5Screen extends StatelessWidget {
|
|
final UserRegistrationData registrationData;
|
|
|
|
const ParentRegisterStep5Screen({super.key, required this.registrationData});
|
|
|
|
// Méthode pour construire la carte Parent 1
|
|
Widget _buildParent1Card(BuildContext context, ParentData data) {
|
|
const double verticalSpacing = 28.0; // Espacement vertical augmenté
|
|
const double labelFontSize = 22.0; // Taille de label augmentée
|
|
|
|
List<Widget> details = [
|
|
Row(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Expanded(child: _buildDisplayFieldValue(context, "Nom:", data.lastName, labelFontSize: labelFontSize)),
|
|
const SizedBox(width: 20),
|
|
Expanded(child: _buildDisplayFieldValue(context, "Prénom:", data.firstName, labelFontSize: labelFontSize)),
|
|
],
|
|
),
|
|
const SizedBox(height: verticalSpacing),
|
|
Row(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Expanded(child: _buildDisplayFieldValue(context, "Téléphone:", data.phone, labelFontSize: labelFontSize)),
|
|
const SizedBox(width: 20),
|
|
Expanded(child: _buildDisplayFieldValue(context, "Email:", data.email, multiLine: true, labelFontSize: labelFontSize)),
|
|
],
|
|
),
|
|
const SizedBox(height: verticalSpacing),
|
|
_buildDisplayFieldValue(context, "Adresse:", "${data.address}\n${data.postalCode} ${data.city}".trim(), multiLine: true, fieldHeight: 80, labelFontSize: labelFontSize),
|
|
];
|
|
return _SummaryCard(
|
|
backgroundImagePath: CardColorHorizontal.peach.path,
|
|
title: 'Parent Principal',
|
|
content: details,
|
|
onEdit: () => Navigator.of(context).pushNamed('/parent-register/step1', arguments: registrationData),
|
|
);
|
|
}
|
|
|
|
// Méthode pour construire la carte Parent 2
|
|
Widget _buildParent2Card(BuildContext context, ParentData data) {
|
|
const double verticalSpacing = 28.0;
|
|
const double labelFontSize = 22.0;
|
|
List<Widget> details = [
|
|
Row(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Expanded(child: _buildDisplayFieldValue(context, "Nom:", data.lastName, labelFontSize: labelFontSize)),
|
|
const SizedBox(width: 20),
|
|
Expanded(child: _buildDisplayFieldValue(context, "Prénom:", data.firstName, labelFontSize: labelFontSize)),
|
|
],
|
|
),
|
|
const SizedBox(height: verticalSpacing),
|
|
Row(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Expanded(child: _buildDisplayFieldValue(context, "Téléphone:", data.phone, labelFontSize: labelFontSize)),
|
|
const SizedBox(width: 20),
|
|
Expanded(child: _buildDisplayFieldValue(context, "Email:", data.email, multiLine: true, labelFontSize: labelFontSize)),
|
|
],
|
|
),
|
|
const SizedBox(height: verticalSpacing),
|
|
_buildDisplayFieldValue(context, "Adresse:", "${data.address}\n${data.postalCode} ${data.city}".trim(), multiLine: true, fieldHeight: 80, labelFontSize: labelFontSize),
|
|
];
|
|
return _SummaryCard(
|
|
backgroundImagePath: CardColorHorizontal.blue.path,
|
|
title: 'Deuxième Parent',
|
|
content: details,
|
|
onEdit: () => Navigator.of(context).pushNamed('/parent-register/step2', arguments: registrationData),
|
|
);
|
|
}
|
|
|
|
// Méthode pour construire les cartes Enfants
|
|
List<Widget> _buildChildrenCards(BuildContext context, List<ChildData> children) {
|
|
return children.asMap().entries.map((entry) {
|
|
int index = entry.key;
|
|
ChildData child = entry.value;
|
|
|
|
CardColorHorizontal cardColorHorizontal = CardColorHorizontal.values.firstWhere(
|
|
(e) => e.name == child.cardColor.name,
|
|
orElse: () => CardColorHorizontal.lavender,
|
|
);
|
|
|
|
return Padding(
|
|
padding: const EdgeInsets.only(bottom: 20.0),
|
|
child: Stack(
|
|
children: [
|
|
AspectRatio(
|
|
aspectRatio: 2.0,
|
|
child: Container(
|
|
padding: const EdgeInsets.symmetric(vertical: 20.0, horizontal: 25.0),
|
|
decoration: BoxDecoration(
|
|
image: DecorationImage(
|
|
image: AssetImage(cardColorHorizontal.path),
|
|
fit: BoxFit.cover,
|
|
),
|
|
borderRadius: BorderRadius.circular(15),
|
|
),
|
|
child: Column(
|
|
children: [
|
|
// Titre centré dans la carte
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: Text(
|
|
'Enfant ${index + 1}' + (child.isUnbornChild ? ' (à naître)' : ''),
|
|
style: GoogleFonts.merienda(fontSize: 28, fontWeight: FontWeight.w600),
|
|
textAlign: TextAlign.center,
|
|
),
|
|
),
|
|
IconButton(
|
|
icon: const Icon(Icons.edit, color: Colors.black54, size: 28),
|
|
onPressed: () {
|
|
Navigator.of(context).pushNamed(
|
|
'/parent-register/step3',
|
|
arguments: {
|
|
'registrationData': registrationData,
|
|
'childIndex': index,
|
|
},
|
|
);
|
|
},
|
|
tooltip: 'Modifier',
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 18),
|
|
Expanded(
|
|
child: Row(
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
children: [
|
|
// IMAGE SANS CADRE BLANC, PREND LA HAUTEUR
|
|
Expanded(
|
|
flex: 1,
|
|
child: Center(
|
|
child: ClipRRect(
|
|
borderRadius: BorderRadius.circular(18),
|
|
child: AspectRatio(
|
|
aspectRatio: 1,
|
|
child: (child.imageFile != null)
|
|
? (kIsWeb
|
|
? Image.network(child.imageFile!.path, fit: BoxFit.cover)
|
|
: Image.file(child.imageFile!, fit: BoxFit.cover))
|
|
: Image.asset('assets/images/photo.png', fit: BoxFit.contain),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(width: 32),
|
|
// INFOS À DROITE (2/3)
|
|
Expanded(
|
|
flex: 2,
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
_buildDisplayFieldValue(context, 'Prénom :', child.firstName, labelFontSize: 22.0),
|
|
const SizedBox(height: 12),
|
|
_buildDisplayFieldValue(context, 'Nom :', child.lastName, labelFontSize: 22.0),
|
|
const SizedBox(height: 12),
|
|
_buildDisplayFieldValue(context, child.isUnbornChild ? 'Date de naissance :' : 'Date de naissance :', child.dob, labelFontSize: 22.0),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
const SizedBox(height: 18),
|
|
// Ligne des consentements
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Row(
|
|
children: [
|
|
Checkbox(
|
|
value: child.photoConsent,
|
|
onChanged: null,
|
|
),
|
|
Text('Consentement photo', style: GoogleFonts.merienda(fontSize: 16)),
|
|
],
|
|
),
|
|
const SizedBox(width: 32),
|
|
Row(
|
|
children: [
|
|
Checkbox(
|
|
value: child.multipleBirth,
|
|
onChanged: null,
|
|
),
|
|
Text('Naissance multiple', style: GoogleFonts.merienda(fontSize: 16)),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}).toList();
|
|
}
|
|
|
|
// Méthode pour construire la carte Motivation
|
|
Widget _buildMotivationCard(BuildContext context, String motivation) {
|
|
List<Widget> details = [
|
|
Text(motivation.isNotEmpty ? motivation : 'Aucune motivation renseignée.',
|
|
style: GoogleFonts.merienda(fontSize: 18),
|
|
maxLines: 4,
|
|
overflow: TextOverflow.ellipsis)
|
|
];
|
|
return _SummaryCard(
|
|
backgroundImagePath: CardColorHorizontal.pink.path,
|
|
title: 'Votre Motivation',
|
|
content: details,
|
|
onEdit: () => Navigator.of(context).pushNamed('/parent-register/step4', arguments: registrationData),
|
|
);
|
|
}
|
|
|
|
// Helper pour afficher une ligne de détail (police et agencement amélioré)
|
|
Widget _buildDetailRow(String label, String value) {
|
|
return Padding(
|
|
padding: const EdgeInsets.only(bottom: 8.0),
|
|
child: Row(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
"$label: ",
|
|
style: GoogleFonts.merienda(fontSize: 18, fontWeight: FontWeight.w600),
|
|
),
|
|
Expanded(
|
|
child: Text(
|
|
value.isNotEmpty ? value : '-',
|
|
style: GoogleFonts.merienda(fontSize: 18),
|
|
softWrap: true,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final screenSize = MediaQuery.of(context).size;
|
|
final cardWidth = screenSize.width / 2.0; // Largeur de la carte (50% de l'écran)
|
|
final double imageAspectRatio = 2.0; // Ratio corrigé (1024/512 = 2.0)
|
|
final cardHeight = cardWidth / imageAspectRatio;
|
|
|
|
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), // Padding horizontal supprimé ici
|
|
child: Padding( // Ajout du Padding horizontal externe
|
|
padding: EdgeInsets.symmetric(horizontal: screenSize.width / 4.0),
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
children: [
|
|
Text('Étape 5/5', style: GoogleFonts.merienda(fontSize: 16, color: Colors.black54)),
|
|
const SizedBox(height: 20),
|
|
Text('Récapitulatif de votre demande', style: GoogleFonts.merienda(fontSize: 22, fontWeight: FontWeight.bold, color: Colors.black87), textAlign: TextAlign.center),
|
|
const SizedBox(height: 30),
|
|
|
|
_buildParent1Card(context, registrationData.parent1),
|
|
const SizedBox(height: 20),
|
|
if (registrationData.parent2 != null) ...[
|
|
_buildParent2Card(context, registrationData.parent2!),
|
|
const SizedBox(height: 20),
|
|
],
|
|
..._buildChildrenCards(context, registrationData.children),
|
|
_buildMotivationCard(context, registrationData.motivationText),
|
|
const SizedBox(height: 40),
|
|
ImageButton(
|
|
bg: 'assets/images/btn_green.png',
|
|
text: 'Soumettre ma demande',
|
|
textColor: const Color(0xFF2D6A4F),
|
|
width: 350,
|
|
height: 50,
|
|
fontSize: 18,
|
|
onPressed: () {
|
|
print("Données finales: ${registrationData.parent1.firstName}, Enfant(s): ${registrationData.children.length}");
|
|
_showConfirmationModal(context);
|
|
},
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
Positioned(
|
|
top: screenSize.height / 2 - 20,
|
|
left: 40,
|
|
child: IconButton(
|
|
icon: Transform.flip(flipX: true, child: Image.asset('assets/images/chevron_right.png', height: 40)),
|
|
onPressed: () => Navigator.pop(context), // Retour à l'étape 4
|
|
tooltip: 'Retour',
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
void _showConfirmationModal(BuildContext context) {
|
|
showDialog<void>(
|
|
context: context,
|
|
barrierDismissible: false,
|
|
builder: (BuildContext dialogContext) {
|
|
return AlertDialog(
|
|
title: Text(
|
|
'Demande enregistrée',
|
|
style: GoogleFonts.merienda(fontWeight: FontWeight.bold),
|
|
),
|
|
content: Text(
|
|
'Votre dossier a bien été pris en compte. Un gestionnaire le validera bientôt.',
|
|
style: GoogleFonts.merienda(fontSize: 14),
|
|
),
|
|
actions: <Widget>[
|
|
TextButton(
|
|
child: Text('OK', style: GoogleFonts.merienda(fontWeight: FontWeight.bold)),
|
|
onPressed: () {
|
|
Navigator.of(dialogContext).pop(); // Ferme la modale
|
|
// TODO: Naviguer vers l'écran de connexion ou tableau de bord
|
|
Navigator.of(context).pushNamedAndRemoveUntil('/login', (Route<dynamic> route) => false);
|
|
},
|
|
),
|
|
],
|
|
);
|
|
},
|
|
);
|
|
}
|
|
}
|
|
|
|
// Widget générique _SummaryCard (ajusté)
|
|
class _SummaryCard extends StatelessWidget {
|
|
final String backgroundImagePath;
|
|
final String title;
|
|
final List<Widget> content;
|
|
final VoidCallback onEdit;
|
|
|
|
const _SummaryCard({
|
|
super.key,
|
|
required this.backgroundImagePath,
|
|
required this.title,
|
|
required this.content,
|
|
required this.onEdit,
|
|
});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return AspectRatio(
|
|
aspectRatio: 2.0, // Le ratio largeur/hauteur de nos images de fond
|
|
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, // Pour que la colonne prenne la hauteur du contenu
|
|
children: [
|
|
Align( // Centrer le titre
|
|
alignment: Alignment.center,
|
|
child: Text(
|
|
title,
|
|
style: GoogleFonts.merienda(fontSize: 22, fontWeight: FontWeight.bold, color: Colors.black87), // Police légèrement augmentée
|
|
),
|
|
),
|
|
const SizedBox(height: 12), // Espacement ajusté après le titre
|
|
...content,
|
|
],
|
|
),
|
|
),
|
|
IconButton(
|
|
icon: const Icon(Icons.edit, color: Colors.black54, size: 28), // Icône un peu plus grande
|
|
onPressed: onEdit,
|
|
tooltip: 'Modifier',
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
} |