feat(frontend): Refonte infrastructure formulaires multi-modes
- Support des modes Desktop/Mobile et Édition/Lecture seule - Refactoring des widgets de formulaire (PersonalInfo, ProfessionalInfo, Presentation, ChildCard) - Mise à jour des écrans de récapitulatif (ParentStep5, AmStep4) - Ajout de navigation (Précédent/Soumettre) sur mobile Closes #78 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -5,8 +5,10 @@ import 'package:flutter/foundation.dart' show kIsWeb;
|
||||
import '../models/user_registration_data.dart';
|
||||
import '../models/card_assets.dart';
|
||||
import 'custom_app_text_field.dart';
|
||||
import 'form_field_wrapper.dart';
|
||||
import 'app_custom_checkbox.dart';
|
||||
import 'hover_relief_widget.dart';
|
||||
import '../config/display_config.dart';
|
||||
|
||||
/// Widget pour afficher et éditer une carte enfant
|
||||
/// Utilisé dans le workflow d'inscription des parents
|
||||
@@ -22,6 +24,8 @@ class ChildCardWidget extends StatefulWidget {
|
||||
final ValueChanged<bool> onToggleIsUnborn;
|
||||
final VoidCallback onRemove;
|
||||
final bool canBeRemoved;
|
||||
final DisplayMode mode;
|
||||
final VoidCallback? onEdit;
|
||||
|
||||
const ChildCardWidget({
|
||||
required Key key,
|
||||
@@ -36,6 +40,8 @@ class ChildCardWidget extends StatefulWidget {
|
||||
required this.onToggleIsUnborn,
|
||||
required this.onRemove,
|
||||
required this.canBeRemoved,
|
||||
this.mode = DisplayMode.editable,
|
||||
this.onEdit,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
@@ -87,101 +93,137 @@ class _ChildCardWidgetState extends State<ChildCardWidget> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final config = DisplayConfig.fromContext(context, mode: widget.mode);
|
||||
final screenSize = MediaQuery.of(context).size;
|
||||
final scaleFactor = config.isMobile ? 0.9 : 1.1; // Réduire légèrement sur mobile
|
||||
|
||||
// Si mode Readonly Desktop : Layout spécial "Vintage" horizontal
|
||||
if (config.isReadonly && !config.isMobile) {
|
||||
return _buildReadonlyDesktopCard(context, config, screenSize);
|
||||
}
|
||||
|
||||
// Si mode Readonly Mobile : Layout spécial "Vintage" vertical (1:2)
|
||||
if (config.isReadonly && config.isMobile) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: screenSize.width * 0.05),
|
||||
child: _buildReadonlyMobileCard(context, config),
|
||||
);
|
||||
}
|
||||
|
||||
final File? currentChildImage = widget.childData.imageFile;
|
||||
// Utiliser la couleur de la carte de childData pour l'ombre si besoin, ou directement pour le fond
|
||||
// ... (reste du code existant pour mobile/editable)
|
||||
final Color baseCardColorForShadow = widget.childData.cardColor == CardColorVertical.lavender
|
||||
? Colors.purple.shade200
|
||||
: (widget.childData.cardColor == CardColorVertical.pink ? Colors.pink.shade200 : Colors.grey.shade200); // Placeholder pour autres couleurs
|
||||
: (widget.childData.cardColor == CardColorVertical.pink ? Colors.pink.shade200 : Colors.grey.shade200);
|
||||
final Color initialPhotoShadow = baseCardColorForShadow.withAlpha(90);
|
||||
final Color hoverPhotoShadow = baseCardColorForShadow.withAlpha(130);
|
||||
|
||||
return Container(
|
||||
width: 345.0 * 1.1, // 379.5
|
||||
height: 570.0 * 1.2, // 684.0
|
||||
padding: const EdgeInsets.all(22.0 * 1.1), // 24.2
|
||||
width: config.isMobile ? double.infinity : screenSize.width * 0.6,
|
||||
// On retire la hauteur fixe pour laisser le contenu définir la taille, comme les autres cartes
|
||||
// height: config.isMobile ? null : 600.0 * scaleFactor,
|
||||
padding: EdgeInsets.all(22.0 * scaleFactor),
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(image: AssetImage(widget.childData.cardColor.path), fit: BoxFit.cover),
|
||||
borderRadius: BorderRadius.circular(20 * 1.1), // 22
|
||||
image: DecorationImage(image: AssetImage(widget.childData.cardColor.path), fit: BoxFit.fill),
|
||||
borderRadius: BorderRadius.circular(20 * scaleFactor),
|
||||
),
|
||||
child: Stack(
|
||||
children: [
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
// ... (contenu existant)
|
||||
HoverReliefWidget(
|
||||
onPressed: widget.onPickImage,
|
||||
onPressed: config.isReadonly ? null : widget.onPickImage,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
initialShadowColor: initialPhotoShadow,
|
||||
hoverShadowColor: hoverPhotoShadow,
|
||||
child: SizedBox(
|
||||
height: 200.0,
|
||||
width: 200.0,
|
||||
height: 200.0 * (config.isMobile ? 0.8 : 1.0),
|
||||
width: 200.0 * (config.isMobile ? 0.8 : 1.0),
|
||||
child: Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(5.0 * 1.1), // 5.5
|
||||
padding: EdgeInsets.all(5.0 * scaleFactor),
|
||||
child: currentChildImage != null
|
||||
? ClipRRect(borderRadius: BorderRadius.circular(10 * 1.1), child: kIsWeb ? Image.network(currentChildImage.path, fit: BoxFit.cover) : Image.file(currentChildImage, fit: BoxFit.cover))
|
||||
? ClipRRect(borderRadius: BorderRadius.circular(10 * scaleFactor), child: kIsWeb ? Image.network(currentChildImage.path, fit: BoxFit.cover) : Image.file(currentChildImage, fit: BoxFit.cover))
|
||||
: Image.asset('assets/images/photo.png', fit: BoxFit.contain),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12.0 * 1.1), // Augmenté pour plus d'espace après la photo
|
||||
SizedBox(height: 10.0 * scaleFactor),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('Enfant à naître ?', style: GoogleFonts.merienda(fontSize: 16 * 1.1, fontWeight: FontWeight.w600)),
|
||||
Switch(value: widget.childData.isUnbornChild, onChanged: widget.onToggleIsUnborn, activeColor: Theme.of(context).primaryColor),
|
||||
Text(
|
||||
'Enfant à naître ?',
|
||||
style: GoogleFonts.merienda(
|
||||
fontSize: config.isMobile ? 14 : 16 * scaleFactor,
|
||||
fontWeight: FontWeight.w600
|
||||
)
|
||||
),
|
||||
Transform.scale(
|
||||
scale: config.isMobile ? 0.8 : 1.0,
|
||||
child: Switch(
|
||||
value: widget.childData.isUnbornChild,
|
||||
onChanged: config.isReadonly ? null : widget.onToggleIsUnborn,
|
||||
activeColor: Theme.of(context).primaryColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 9.0 * 1.1), // 9.9
|
||||
CustomAppTextField(
|
||||
SizedBox(height: 8.0 * scaleFactor),
|
||||
_buildField(
|
||||
config: config,
|
||||
scaleFactor: scaleFactor,
|
||||
label: 'Prénom',
|
||||
controller: _firstNameController,
|
||||
labelText: 'Prénom',
|
||||
hintText: 'Facultatif si à naître',
|
||||
hint: 'Facultatif si à naître',
|
||||
isRequired: !widget.childData.isUnbornChild,
|
||||
fieldHeight: 55.0 * 1.1, // 60.5
|
||||
),
|
||||
const SizedBox(height: 6.0 * 1.1), // 6.6
|
||||
CustomAppTextField(
|
||||
SizedBox(height: 5.0 * scaleFactor),
|
||||
_buildField(
|
||||
config: config,
|
||||
scaleFactor: scaleFactor,
|
||||
label: 'Nom',
|
||||
controller: _lastNameController,
|
||||
labelText: 'Nom',
|
||||
hintText: 'Nom de l\'enfant',
|
||||
enabled: true,
|
||||
fieldHeight: 55.0 * 1.1, // 60.5
|
||||
hint: 'Nom de l\'enfant',
|
||||
),
|
||||
const SizedBox(height: 9.0 * 1.1), // 9.9
|
||||
CustomAppTextField(
|
||||
SizedBox(height: 8.0 * scaleFactor),
|
||||
_buildField(
|
||||
config: config,
|
||||
scaleFactor: scaleFactor,
|
||||
label: widget.childData.isUnbornChild ? 'Date prévisionnelle de naissance' : 'Date de naissance',
|
||||
controller: _dobController,
|
||||
labelText: widget.childData.isUnbornChild ? 'Date prévisionnelle de naissance' : 'Date de naissance',
|
||||
hintText: 'JJ/MM/AAAA',
|
||||
hint: 'JJ/MM/AAAA',
|
||||
readOnly: true,
|
||||
onTap: widget.onDateSelect,
|
||||
onTap: config.isReadonly ? null : widget.onDateSelect,
|
||||
suffixIcon: Icons.calendar_today,
|
||||
fieldHeight: 55.0 * 1.1, // 60.5
|
||||
),
|
||||
const SizedBox(height: 11.0 * 1.1), // 12.1
|
||||
SizedBox(height: 10.0 * scaleFactor),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
AppCustomCheckbox(
|
||||
label: 'Consentement photo',
|
||||
value: widget.childData.photoConsent,
|
||||
onChanged: widget.onTogglePhotoConsent,
|
||||
checkboxSize: 22.0 * 1.1, // 24.2
|
||||
onChanged: config.isReadonly ? (v) {} : widget.onTogglePhotoConsent,
|
||||
checkboxSize: config.isMobile ? 20.0 : 22.0 * scaleFactor,
|
||||
fontSize: config.isMobile ? 13.0 : 16.0,
|
||||
),
|
||||
const SizedBox(height: 6.0 * 1.1), // 6.6
|
||||
SizedBox(height: 5.0 * scaleFactor),
|
||||
AppCustomCheckbox(
|
||||
label: 'Naissance multiple',
|
||||
value: widget.childData.multipleBirth,
|
||||
onChanged: widget.onToggleMultipleBirth,
|
||||
checkboxSize: 22.0 * 1.1, // 24.2
|
||||
onChanged: config.isReadonly ? (v) {} : widget.onToggleMultipleBirth,
|
||||
checkboxSize: config.isMobile ? 20.0 : 22.0 * scaleFactor,
|
||||
fontSize: config.isMobile ? 13.0 : 16.0,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
if (widget.canBeRemoved)
|
||||
if (widget.canBeRemoved && !config.isReadonly)
|
||||
Positioned(
|
||||
top: -5, right: -5,
|
||||
child: InkWell(
|
||||
@@ -189,14 +231,361 @@ class _ChildCardWidgetState extends State<ChildCardWidget> {
|
||||
customBorder: const CircleBorder(),
|
||||
child: Image.asset(
|
||||
'assets/images/red_cross2.png',
|
||||
width: 36,
|
||||
height: 36,
|
||||
width: config.isMobile ? 30 : 36,
|
||||
height: config.isMobile ? 30 : 36,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
if (config.isReadonly && widget.onEdit != null)
|
||||
Positioned(
|
||||
top: -5, right: -5,
|
||||
child: IconButton(
|
||||
icon: const Icon(Icons.edit, color: Colors.black54),
|
||||
onPressed: widget.onEdit,
|
||||
tooltip: 'Modifier',
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Layout SPÉCIAL Readonly Desktop (Ancien Design Horizontal)
|
||||
Widget _buildReadonlyDesktopCard(BuildContext context, DisplayConfig config, Size screenSize) {
|
||||
// Convertir la couleur verticale (pour mobile) en couleur horizontale (pour desktop/récap)
|
||||
// On mappe les couleurs verticales vers horizontales
|
||||
String horizontalCardAsset = CardColorHorizontal.lavender.path; // Par défaut
|
||||
|
||||
// Mapping manuel simple
|
||||
if (widget.childData.cardColor.path.contains('lavender')) horizontalCardAsset = CardColorHorizontal.lavender.path;
|
||||
else if (widget.childData.cardColor.path.contains('blue')) horizontalCardAsset = CardColorHorizontal.blue.path;
|
||||
else if (widget.childData.cardColor.path.contains('green')) horizontalCardAsset = CardColorHorizontal.green.path;
|
||||
else if (widget.childData.cardColor.path.contains('lime')) horizontalCardAsset = CardColorHorizontal.lime.path;
|
||||
else if (widget.childData.cardColor.path.contains('peach')) horizontalCardAsset = CardColorHorizontal.peach.path;
|
||||
else if (widget.childData.cardColor.path.contains('pink')) horizontalCardAsset = CardColorHorizontal.pink.path;
|
||||
else if (widget.childData.cardColor.path.contains('red')) horizontalCardAsset = CardColorHorizontal.red.path;
|
||||
|
||||
final File? currentChildImage = widget.childData.imageFile;
|
||||
final cardWidth = screenSize.width / 2.0;
|
||||
|
||||
return SizedBox(
|
||||
width: cardWidth,
|
||||
child: AspectRatio(
|
||||
aspectRatio: 2.0,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 20.0, horizontal: 25.0),
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage(horizontalCardAsset),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
// Titre + Edit Button
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
'Enfant ${widget.childIndex + 1}' + (widget.childData.isUnbornChild ? ' (à naître)' : ''),
|
||||
style: GoogleFonts.merienda(fontSize: 28, fontWeight: FontWeight.w600),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
if (widget.onEdit != null)
|
||||
IconButton(
|
||||
icon: const Icon(Icons.edit, color: Colors.black54, size: 28),
|
||||
onPressed: widget.onEdit,
|
||||
tooltip: 'Modifier',
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 18),
|
||||
|
||||
// Contenu principal : Photo + Champs
|
||||
Expanded(
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
// PHOTO (1/3)
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: Center(
|
||||
child: AspectRatio(
|
||||
aspectRatio: 1,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(18),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.1),
|
||||
blurRadius: 10,
|
||||
offset: const Offset(0, 5),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(18),
|
||||
child: currentChildImage != null
|
||||
? (kIsWeb
|
||||
? Image.network(currentChildImage.path, fit: BoxFit.cover)
|
||||
: Image.file(currentChildImage, fit: BoxFit.cover))
|
||||
: Image.asset('assets/images/photo.png', fit: BoxFit.contain),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 32),
|
||||
|
||||
// CHAMPS (2/3)
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
_buildReadonlyField('Prénom :', _firstNameController.text),
|
||||
const SizedBox(height: 12),
|
||||
_buildReadonlyField('Nom :', _lastNameController.text),
|
||||
const SizedBox(height: 12),
|
||||
_buildReadonlyField(
|
||||
widget.childData.isUnbornChild ? 'Date prévisionnelle :' : 'Date de naissance :',
|
||||
_dobController.text
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 18),
|
||||
|
||||
// Consentements
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
AppCustomCheckbox(
|
||||
label: 'Consentement photo',
|
||||
value: widget.childData.photoConsent,
|
||||
onChanged: (v) {}, // Readonly
|
||||
checkboxSize: 22.0,
|
||||
fontSize: 16.0,
|
||||
),
|
||||
const SizedBox(width: 32),
|
||||
AppCustomCheckbox(
|
||||
label: 'Naissance multiple',
|
||||
value: widget.childData.multipleBirth,
|
||||
onChanged: (v) {}, // Readonly
|
||||
checkboxSize: 22.0,
|
||||
fontSize: 16.0,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Carte en mode readonly MOBILE avec hauteur adaptative
|
||||
Widget _buildReadonlyMobileCard(BuildContext context, DisplayConfig config) {
|
||||
final File? currentChildImage = widget.childData.imageFile;
|
||||
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
// Pas de height fixe
|
||||
padding: const EdgeInsets.symmetric(vertical: 20.0, horizontal: 24.0),
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage(widget.childData.cardColor.path), // Image verticale
|
||||
fit: BoxFit.fill, // Fill pour s'adapter
|
||||
),
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
),
|
||||
child: Stack(
|
||||
children: [
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min, // S'adapte au contenu
|
||||
children: [
|
||||
// Titre + Edit Button
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
'Enfant ${widget.childIndex + 1}' + (widget.childData.isUnbornChild ? ' (à naître)' : ''),
|
||||
style: GoogleFonts.merienda(fontSize: 18, fontWeight: FontWeight.bold, color: Colors.black87),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
if (widget.onEdit != null)
|
||||
const SizedBox(width: 28),
|
||||
],
|
||||
),
|
||||
|
||||
// Contenu aligné en haut
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 20.0),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
// Photo
|
||||
SizedBox(
|
||||
height: 150,
|
||||
width: 150,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.1),
|
||||
blurRadius: 10,
|
||||
offset: const Offset(0, 5),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
child: currentChildImage != null
|
||||
? (kIsWeb
|
||||
? Image.network(currentChildImage.path, fit: BoxFit.cover)
|
||||
: Image.file(currentChildImage, fit: BoxFit.cover))
|
||||
: Image.asset('assets/images/photo.png', fit: BoxFit.contain),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// Champs
|
||||
_buildReadonlyField('Prénom :', _firstNameController.text),
|
||||
const SizedBox(height: 8),
|
||||
_buildReadonlyField('Nom :', _lastNameController.text),
|
||||
const SizedBox(height: 8),
|
||||
_buildReadonlyField(
|
||||
widget.childData.isUnbornChild ? 'Date prévisionnelle :' : 'Date de naissance :',
|
||||
_dobController.text
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// Consentements
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
AppCustomCheckbox(
|
||||
label: 'Consentement photo',
|
||||
value: widget.childData.photoConsent,
|
||||
onChanged: (v) {},
|
||||
checkboxSize: 20.0,
|
||||
fontSize: 14.0,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
children: [
|
||||
AppCustomCheckbox(
|
||||
label: 'Naissance multiple',
|
||||
value: widget.childData.multipleBirth,
|
||||
onChanged: (v) {},
|
||||
checkboxSize: 20.0,
|
||||
fontSize: 14.0,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
if (widget.onEdit != null)
|
||||
Positioned(
|
||||
top: 0,
|
||||
right: 0,
|
||||
child: IconButton(
|
||||
padding: EdgeInsets.zero,
|
||||
constraints: const BoxConstraints(),
|
||||
icon: const Icon(Icons.edit, color: Colors.black54, size: 24),
|
||||
onPressed: widget.onEdit,
|
||||
tooltip: 'Modifier',
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Helper pour champ Readonly style "Beige"
|
||||
Widget _buildReadonlyField(String label, String value) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: GoogleFonts.merienda(fontSize: 22.0, fontWeight: FontWeight.w600),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Container(
|
||||
width: double.infinity,
|
||||
height: 50.0,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 18.0, vertical: 12.0),
|
||||
decoration: BoxDecoration(
|
||||
image: const DecorationImage(
|
||||
image: AssetImage('assets/images/bg_beige.png'),
|
||||
fit: BoxFit.fill,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Text(
|
||||
value.isNotEmpty ? value : '-',
|
||||
style: GoogleFonts.merienda(fontSize: 18.0),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildField({
|
||||
required DisplayConfig config,
|
||||
required double scaleFactor,
|
||||
required String label,
|
||||
required TextEditingController controller,
|
||||
String? hint,
|
||||
bool isRequired = false,
|
||||
bool readOnly = false,
|
||||
VoidCallback? onTap,
|
||||
IconData? suffixIcon,
|
||||
}) {
|
||||
if (config.isReadonly) {
|
||||
return FormFieldWrapper(
|
||||
config: config,
|
||||
label: label,
|
||||
value: controller.text,
|
||||
);
|
||||
} else {
|
||||
return CustomAppTextField(
|
||||
controller: controller,
|
||||
labelText: label,
|
||||
hintText: hint ?? label,
|
||||
isRequired: isRequired,
|
||||
fieldHeight: config.isMobile ? 40.0 : 50.0 * scaleFactor, // Hauteur réduite
|
||||
labelFontSize: config.isMobile ? 12.0 : 18.0, // Police réduite
|
||||
inputFontSize: config.isMobile ? 13.0 : 16.0, // Police réduite
|
||||
readOnly: readOnly,
|
||||
onTap: onTap,
|
||||
suffixIcon: suffixIcon,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user