feat: harmonisation de la taille de police dans les champs de motivation (étape4 et 5) - Ajout du paramètre fontSize au CustomDecoratedTextField - Taille de police fixée à 18px pour une meilleure lisibilité

This commit is contained in:
Julien Martin 2025-05-12 16:11:12 +02:00
parent 760f4feca3
commit 7707b99773
10 changed files with 138 additions and 92 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

View File

@ -6,6 +6,7 @@ import 'package:p_tits_pas/widgets/app_custom_checkbox.dart'; // Import de la ch
// import 'package:p_tits_pas/models/placeholder_registration_data.dart'; // Remplacé // import 'package:p_tits_pas/models/placeholder_registration_data.dart'; // Remplacé
import '../../models/user_registration_data.dart'; // Import du vrai modèle import '../../models/user_registration_data.dart'; // Import du vrai modèle
import '../../utils/data_generator.dart'; // Import du générateur import '../../utils/data_generator.dart'; // Import du générateur
import '../../models/card_assets.dart'; // Import des enums de cartes
class ParentRegisterStep4Screen extends StatefulWidget { class ParentRegisterStep4Screen extends StatefulWidget {
final UserRegistrationData registrationData; // Accepte les données final UserRegistrationData registrationData; // Accepte les données
@ -100,11 +101,9 @@ Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lo
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final screenSize = MediaQuery.of(context).size; final screenSize = MediaQuery.of(context).size;
// Calculer la largeur disponible pour le contenu principal de la colonne final cardWidth = screenSize.width * 0.6; // Largeur de la carte (60% de l'écran)
// La SingleChildScrollView a un padding horizontal de 50.0 de chaque côté. final double imageAspectRatio = 2.0; // Ratio corrigé (1024/512 = 2.0)
final availableContentWidth = screenSize.width - (50.0 * 2); final cardHeight = cardWidth / imageAspectRatio;
// Définir la taille du champ de texte carré comme un pourcentage de cette largeur disponible
final textFieldSize = (availableContentWidth * 0.65) / 2; // Réduction de la taille par deux
return Scaffold( return Scaffold(
body: Stack( body: Stack(
@ -120,7 +119,7 @@ Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lo
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Text( Text(
'Étape 4/5', // Supposant 5 étapes au total pour l'instant 'Étape 4/5',
style: GoogleFonts.merienda(fontSize: 16, color: Colors.black54), style: GoogleFonts.merienda(fontSize: 16, color: Colors.black54),
), ),
const SizedBox(height: 20), const SizedBox(height: 20),
@ -130,18 +129,31 @@ Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lo
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
const SizedBox(height: 30), const SizedBox(height: 30),
SizedBox( Container(
width: textFieldSize, width: cardWidth,
height: textFieldSize, height: cardHeight,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(CardColorHorizontal.green.path),
fit: BoxFit.fill,
),
),
child: Padding(
padding: const EdgeInsets.all(40.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: CustomDecoratedTextField( child: CustomDecoratedTextField(
controller: _motivationController, controller: _motivationController,
hintText: 'Écrivez ici pour motiver votre demande...', hintText: 'Écrivez ici pour motiver votre demande...',
fieldHeight: textFieldSize, fieldHeight: cardHeight * 0.6,
maxLines: 10, maxLines: 10,
expandDynamically: true, expandDynamically: true,
fontSize: 18.0,
), ),
), ),
const SizedBox(height: 30), const SizedBox(height: 20),
GestureDetector( GestureDetector(
onTap: () { onTap: () {
if (!_cguAccepted) { if (!_cguAccepted) {
@ -160,7 +172,10 @@ Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lo
}, },
), ),
), ),
const SizedBox(height: 40), ],
),
),
),
], ],
), ),
), ),

View File

@ -4,34 +4,58 @@ import '../../models/user_registration_data.dart'; // Utilisation du vrai modèl
import '../../widgets/image_button.dart'; // Import du ImageButton import '../../widgets/image_button.dart'; // Import du ImageButton
import '../../models/card_assets.dart'; // Import des enums de cartes import '../../models/card_assets.dart'; // Import des enums de cartes
import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter/foundation.dart' show kIsWeb;
import '../../widgets/custom_decorated_text_field.dart'; // Import du CustomDecoratedTextField
// Nouvelle méthode helper pour afficher un champ de type "lecture seule" stylisé // 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}) { Widget _buildDisplayFieldValue(BuildContext context, String label, String value, {bool multiLine = false, double fieldHeight = 50.0, double labelFontSize = 18.0}) {
const FontWeight labelFontWeight = FontWeight.w600; const FontWeight labelFontWeight = FontWeight.w600;
// Ne pas afficher le label si labelFontSize est 0 ou si label est vide
bool showLabel = label.isNotEmpty && labelFontSize > 0;
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
if (showLabel)
Text(label, style: GoogleFonts.merienda(fontSize: labelFontSize, fontWeight: labelFontWeight)), Text(label, style: GoogleFonts.merienda(fontSize: labelFontSize, fontWeight: labelFontWeight)),
if (showLabel)
const SizedBox(height: 4), const SizedBox(height: 4),
Container( // Utiliser Expanded si multiLine et pas de hauteur fixe, sinon Container
width: double.infinity, // Prendra la largeur allouée par son parent (Expanded) multiLine && fieldHeight == null
height: multiLine ? null : fieldHeight, // Hauteur flexible pour multiligne, sinon fixe ? Expanded(
constraints: multiLine ? const BoxConstraints(minHeight: 50.0) : null, // Hauteur min pour multiligne child: Container(
padding: const EdgeInsets.symmetric(horizontal: 18.0, vertical: 12.0), // Ajuster au besoin width: double.infinity,
padding: const EdgeInsets.symmetric(horizontal: 18.0, vertical: 12.0),
decoration: BoxDecoration( decoration: BoxDecoration(
image: const DecorationImage( image: const DecorationImage(
image: AssetImage('assets/images/input_field_bg.png'), // Image de fond du champ image: AssetImage('assets/images/input_field_bg.png'),
fit: BoxFit.fill,
),
),
child: SingleChildScrollView( // Pour le défilement si le texte dépasse
child: Text(
value.isNotEmpty ? value : '-',
style: GoogleFonts.merienda(fontSize: labelFontSize > 0 ? labelFontSize : 18.0), // Garder une taille de texte par défaut si label caché
maxLines: null, // Permettre un nombre illimité de lignes
),
),
),
)
: Container(
width: double.infinity,
height: multiLine ? null : fieldHeight,
constraints: multiLine ? BoxConstraints(minHeight: fieldHeight) : null,
padding: const EdgeInsets.symmetric(horizontal: 18.0, vertical: 12.0),
decoration: BoxDecoration(
image: const DecorationImage(
image: AssetImage('assets/images/input_field_bg.png'),
fit: BoxFit.fill, 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( child: Text(
value.isNotEmpty ? value : '-', value.isNotEmpty ? value : '-',
style: GoogleFonts.merienda(fontSize: labelFontSize), style: GoogleFonts.merienda(fontSize: labelFontSize > 0 ? labelFontSize : 18.0),
maxLines: multiLine ? null : 1, // Permet plusieurs lignes si multiLine est true maxLines: multiLine ? null : 1,
overflow: multiLine ? TextOverflow.visible : TextOverflow.ellipsis, overflow: multiLine ? TextOverflow.visible : TextOverflow.ellipsis,
), ),
), ),
@ -154,10 +178,7 @@ class ParentRegisterStep5Screen extends StatelessWidget {
onPressed: () { onPressed: () {
Navigator.of(context).pushNamed( Navigator.of(context).pushNamed(
'/parent-register/step3', '/parent-register/step3',
arguments: { arguments: registrationData,
'registrationData': registrationData,
'childIndex': index,
},
); );
}, },
tooltip: 'Modifier', tooltip: 'Modifier',
@ -243,16 +264,22 @@ class ParentRegisterStep5Screen extends StatelessWidget {
// Méthode pour construire la carte Motivation // Méthode pour construire la carte Motivation
Widget _buildMotivationCard(BuildContext context, String 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( return _SummaryCard(
backgroundImagePath: CardColorHorizontal.pink.path, backgroundImagePath: CardColorHorizontal.green.path,
title: 'Votre Motivation', title: 'Votre Motivation',
content: details, content: [
Expanded(
child: CustomDecoratedTextField(
controller: TextEditingController(text: motivation),
hintText: 'Aucune motivation renseignée.',
fieldHeight: 200,
maxLines: 10,
expandDynamically: true,
readOnly: true,
fontSize: 18.0,
),
),
],
onEdit: () => Navigator.of(context).pushNamed('/parent-register/step4', arguments: registrationData), onEdit: () => Navigator.of(context).pushNamed('/parent-register/step4', arguments: registrationData),
); );
} }
@ -395,7 +422,7 @@ class _SummaryCard extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return AspectRatio( return AspectRatio(
aspectRatio: 2.0, // Le ratio largeur/hauteur de nos images de fond aspectRatio: 2.0,
child: Container( child: Container(
padding: const EdgeInsets.symmetric(vertical: 20.0, horizontal: 25.0), padding: const EdgeInsets.symmetric(vertical: 20.0, horizontal: 25.0),
decoration: BoxDecoration( decoration: BoxDecoration(
@ -405,33 +432,32 @@ class _SummaryCard extends StatelessWidget {
), ),
borderRadius: BorderRadius.circular(15), borderRadius: BorderRadius.circular(15),
), ),
child: Row( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, children: [
Row(
children: [ children: [
Expanded( 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( child: Text(
title, title,
style: GoogleFonts.merienda(fontSize: 22, fontWeight: FontWeight.bold, color: Colors.black87), // Police légèrement augmentée style: GoogleFonts.merienda(fontSize: 28, fontWeight: FontWeight.w600),
), textAlign: TextAlign.center,
),
const SizedBox(height: 12), // Espacement ajusté après le titre
...content,
],
), ),
), ),
IconButton( IconButton(
icon: const Icon(Icons.edit, color: Colors.black54, size: 28), // Icône un peu plus grande icon: const Icon(Icons.edit, color: Colors.black54, size: 28),
onPressed: onEdit, onPressed: onEdit,
tooltip: 'Modifier', tooltip: 'Modifier',
), ),
], ],
), ),
const SizedBox(height: 18),
Expanded(
child: Column(
children: content,
),
),
],
),
), ),
); );
} }

View File

@ -7,6 +7,8 @@ class CustomDecoratedTextField extends StatelessWidget {
final int maxLines; final int maxLines;
final double? fieldHeight; // Hauteur optionnelle pour le champ final double? fieldHeight; // Hauteur optionnelle pour le champ
final bool expandDynamically; // Nouvelle propriété final bool expandDynamically; // Nouvelle propriété
final bool readOnly;
final double fontSize;
const CustomDecoratedTextField({ const CustomDecoratedTextField({
super.key, super.key,
@ -15,6 +17,8 @@ class CustomDecoratedTextField extends StatelessWidget {
this.maxLines = 10, // Un nombre raisonnable de lignes par défaut si non dynamique this.maxLines = 10, // Un nombre raisonnable de lignes par défaut si non dynamique
this.fieldHeight, // Si non fourni, la hauteur sera intrinsèque ou définie par l'image this.fieldHeight, // Si non fourni, la hauteur sera intrinsèque ou définie par l'image
this.expandDynamically = false, // Par défaut, non dynamique this.expandDynamically = false, // Par défaut, non dynamique
this.readOnly = false,
this.fontSize = 15.0,
}); });
@override @override
@ -37,11 +41,12 @@ class CustomDecoratedTextField extends StatelessWidget {
controller: controller, controller: controller,
keyboardType: TextInputType.multiline, keyboardType: TextInputType.multiline,
maxLines: expandDynamically ? null : maxLines, // S'étend dynamiquement si expandDynamically est true maxLines: expandDynamically ? null : maxLines, // S'étend dynamiquement si expandDynamically est true
style: GoogleFonts.merienda(fontSize: 15, color: Colors.black87), style: GoogleFonts.merienda(fontSize: fontSize, color: Colors.black87),
textAlignVertical: TextAlignVertical.top, textAlignVertical: TextAlignVertical.top,
readOnly: readOnly,
decoration: InputDecoration( decoration: InputDecoration(
hintText: hintText, hintText: hintText,
hintStyle: GoogleFonts.merienda(fontSize: 15, color: Colors.black54.withOpacity(0.7)), hintStyle: GoogleFonts.merienda(fontSize: fontSize, color: Colors.black54.withOpacity(0.7)),
border: InputBorder.none, // Pas de bordure pour le TextFormField lui-même border: InputBorder.none, // Pas de bordure pour le TextFormField lui-même
contentPadding: EdgeInsets.zero, // Le padding est géré par le widget Padding externe contentPadding: EdgeInsets.zero, // Le padding est géré par le widget Padding externe
// Pour aligner le hintText en haut à gauche // Pour aligner le hintText en haut à gauche