Merge pull request 'feature/FRONT-05a' (#48) from feature/FRONT-05a into dev
Reviewed-on: #48
This commit is contained in:
commit
9418932791
96
frontend/lib/models/am_user_registration_data.dart
Normal file
96
frontend/lib/models/am_user_registration_data.dart
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
class ChildminderId {
|
||||||
|
String firstName;
|
||||||
|
String lastName;
|
||||||
|
String address;
|
||||||
|
String postalCode;
|
||||||
|
String city;
|
||||||
|
String phone;
|
||||||
|
String email;
|
||||||
|
String password;
|
||||||
|
File? profilePicture;
|
||||||
|
bool photoConsent;
|
||||||
|
|
||||||
|
ChildminderId({
|
||||||
|
this.firstName = '',
|
||||||
|
this.lastName = '',
|
||||||
|
this.address = '',
|
||||||
|
this.postalCode = '',
|
||||||
|
this.city = '',
|
||||||
|
this.phone = '',
|
||||||
|
this.email = '',
|
||||||
|
this.password = '',
|
||||||
|
this.profilePicture,
|
||||||
|
this.photoConsent = false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class ChildminderProfessional {
|
||||||
|
String dateOfBirth;
|
||||||
|
String birthCity;
|
||||||
|
String birthCountry;
|
||||||
|
String socialSecurityNumber; // NIR
|
||||||
|
String agreementNumber;
|
||||||
|
int maxChildren;
|
||||||
|
|
||||||
|
ChildminderProfessional({
|
||||||
|
this.dateOfBirth = '',
|
||||||
|
this.birthCity = '',
|
||||||
|
this.birthCountry = '',
|
||||||
|
this.socialSecurityNumber = '',
|
||||||
|
this.agreementNumber = '',
|
||||||
|
this.maxChildren = 1,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class ChildminderRegistrationData {
|
||||||
|
ChildminderId identity;
|
||||||
|
ChildminderProfessional professional;
|
||||||
|
String presentationMessage;
|
||||||
|
bool cguAccepted;
|
||||||
|
bool isPhotoRequired;
|
||||||
|
|
||||||
|
ChildminderRegistrationData({
|
||||||
|
ChildminderId? identityData,
|
||||||
|
ChildminderProfessional? professionalData,
|
||||||
|
this.presentationMessage = '',
|
||||||
|
this.cguAccepted = false,
|
||||||
|
this.isPhotoRequired = false,
|
||||||
|
}) : identity = identityData ?? ChildminderId(),
|
||||||
|
professional = professionalData ?? ChildminderProfessional();
|
||||||
|
|
||||||
|
void updateIdentity(ChildminderId data) {
|
||||||
|
identity = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateProfessional(ChildminderProfessional data) {
|
||||||
|
professional = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updatePresentation(String message) {
|
||||||
|
presentationMessage = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
void acceptCGU() {
|
||||||
|
cguAccepted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get isComplete {
|
||||||
|
return identity.firstName.isNotEmpty &&
|
||||||
|
identity.lastName.isNotEmpty &&
|
||||||
|
identity.address.isNotEmpty &&
|
||||||
|
identity.postalCode.isNotEmpty &&
|
||||||
|
identity.city.isNotEmpty &&
|
||||||
|
identity.phone.isNotEmpty &&
|
||||||
|
identity.email.isNotEmpty &&
|
||||||
|
identity.password.isNotEmpty &&
|
||||||
|
professional.dateOfBirth.isNotEmpty &&
|
||||||
|
professional.birthCity.isNotEmpty &&
|
||||||
|
professional.birthCountry.isNotEmpty &&
|
||||||
|
professional.socialSecurityNumber.isNotEmpty &&
|
||||||
|
professional.agreementNumber.isNotEmpty &&
|
||||||
|
cguAccepted &&
|
||||||
|
(!isPhotoRequired || (identity.profilePicture != null && identity.photoConsent));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:p_tits_pas/screens/auth/am/am_register_step1_sceen.dart';
|
||||||
import '../screens/auth/login_screen.dart';
|
import '../screens/auth/login_screen.dart';
|
||||||
import '../screens/auth/register_choice_screen.dart';
|
import '../screens/auth/register_choice_screen.dart';
|
||||||
import '../screens/auth/parent/parent_register_step1_screen.dart';
|
import '../screens/auth/parent/parent_register_step1_screen.dart';
|
||||||
@ -8,7 +9,7 @@ import '../screens/auth/parent/parent_register_step3_screen.dart';
|
|||||||
import '../screens/auth/parent/parent_register_step4_screen.dart';
|
import '../screens/auth/parent/parent_register_step4_screen.dart';
|
||||||
import '../screens/auth/parent/parent_register_step5_screen.dart';
|
import '../screens/auth/parent/parent_register_step5_screen.dart';
|
||||||
import '../screens/home/home_screen.dart';
|
import '../screens/home/home_screen.dart';
|
||||||
import '../models/user_registration_data.dart';
|
import '../models/parent_user_registration_data.dart';
|
||||||
|
|
||||||
class AppRouter {
|
class AppRouter {
|
||||||
static const String login = '/login';
|
static const String login = '/login';
|
||||||
@ -18,6 +19,8 @@ class AppRouter {
|
|||||||
static const String parentRegisterStep3 = '/parent-register/step3';
|
static const String parentRegisterStep3 = '/parent-register/step3';
|
||||||
static const String parentRegisterStep4 = '/parent-register/step4';
|
static const String parentRegisterStep4 = '/parent-register/step4';
|
||||||
static const String parentRegisterStep5 = '/parent-register/step5';
|
static const String parentRegisterStep5 = '/parent-register/step5';
|
||||||
|
|
||||||
|
static const String amRegisterStep1 = '/am-register/step1';
|
||||||
static const String home = '/home';
|
static const String home = '/home';
|
||||||
|
|
||||||
static Route<dynamic> generateRoute(RouteSettings settings) {
|
static Route<dynamic> generateRoute(RouteSettings settings) {
|
||||||
@ -74,6 +77,10 @@ class AppRouter {
|
|||||||
}
|
}
|
||||||
slideTransition = true;
|
slideTransition = true;
|
||||||
break;
|
break;
|
||||||
|
case amRegisterStep1:
|
||||||
|
screen = const AmRegisterStep1Screen();
|
||||||
|
slideTransition = true;
|
||||||
|
break;
|
||||||
case home:
|
case home:
|
||||||
screen = const HomeScreen();
|
screen = const HomeScreen();
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -1,17 +1,256 @@
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:p_tits_pas/models/am_user_registration_data.dart';
|
||||||
|
import 'package:p_tits_pas/models/card_assets.dart';
|
||||||
|
import 'package:p_tits_pas/utils/data_generator.dart';
|
||||||
|
import 'package:p_tits_pas/widgets/FormFieldConfig.dart';
|
||||||
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
import 'dart:math' as math;
|
||||||
|
|
||||||
class AmRegisterStep1Screen extends StatelessWidget {
|
|
||||||
const AmRegisterStep1Screen({Key? key}) : super(key: key);
|
class AmRegisterStep1Screen extends StatefulWidget {
|
||||||
|
const AmRegisterStep1Screen({super.key});
|
||||||
|
@override
|
||||||
|
State <AmRegisterStep1Screen> createState() => _AmRegisterStep1ScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AmRegisterStep1ScreenState extends State<AmRegisterStep1Screen> {
|
||||||
|
final _formKey = GlobalKey<FormState>();
|
||||||
|
late ChildminderRegistrationData _registrationData;
|
||||||
|
|
||||||
|
final _lastNameController = TextEditingController();
|
||||||
|
final _firstNameController = TextEditingController();
|
||||||
|
final _phoneController = TextEditingController();
|
||||||
|
final _emailController = TextEditingController();
|
||||||
|
final _passwordController = TextEditingController();
|
||||||
|
final _confirmPasswordController = TextEditingController();
|
||||||
|
final _addressController = TextEditingController();
|
||||||
|
final _postalCodeController = TextEditingController();
|
||||||
|
final _cityController = TextEditingController();
|
||||||
|
|
||||||
|
// File? _selectedImage;
|
||||||
|
// bool _photoConsent = false;
|
||||||
|
// final ImagePicker _picker = ImagePicker();
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_registrationData = ChildminderRegistrationData();
|
||||||
|
_generateAndFillData();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _generateAndFillData() {
|
||||||
|
final String genFirstName = DataGenerator.firstName();
|
||||||
|
final String genLastName = DataGenerator.lastName();
|
||||||
|
|
||||||
|
_addressController.text = DataGenerator.address();
|
||||||
|
_postalCodeController.text = DataGenerator.postalCode();
|
||||||
|
_cityController.text = DataGenerator.city();
|
||||||
|
_firstNameController.text = genFirstName;
|
||||||
|
_lastNameController.text = genLastName;
|
||||||
|
_phoneController.text = DataGenerator.phone();
|
||||||
|
_emailController.text = DataGenerator.email(genFirstName, genLastName);
|
||||||
|
_passwordController.text = DataGenerator.password();
|
||||||
|
_confirmPasswordController.text = _passwordController.text;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_lastNameController.dispose();
|
||||||
|
_firstNameController.dispose();
|
||||||
|
_phoneController.dispose();
|
||||||
|
_emailController.dispose();
|
||||||
|
_passwordController.dispose();
|
||||||
|
_confirmPasswordController.dispose();
|
||||||
|
_addressController.dispose();
|
||||||
|
_postalCodeController.dispose();
|
||||||
|
_cityController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<List<ModularFormField>> get formFields => [
|
||||||
|
[
|
||||||
|
ModularFormField(
|
||||||
|
label: 'Nom',
|
||||||
|
hint: 'Votre nom de famille',
|
||||||
|
controller: _lastNameController,
|
||||||
|
isRequired: true,
|
||||||
|
flex: 12,
|
||||||
|
),
|
||||||
|
ModularFormField(
|
||||||
|
label: 'Prénom',
|
||||||
|
hint: 'Votre prénom',
|
||||||
|
controller: _firstNameController,
|
||||||
|
isRequired: true,
|
||||||
|
flex: 12,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
ModularFormField(
|
||||||
|
label: 'Téléphone',
|
||||||
|
hint: 'Votre numéro de téléphone',
|
||||||
|
controller: _phoneController,
|
||||||
|
keyboardType: TextInputType.phone,
|
||||||
|
flex: 12,
|
||||||
|
),
|
||||||
|
ModularFormField(
|
||||||
|
label: 'Email',
|
||||||
|
hint: 'Votre adresse email',
|
||||||
|
controller: _emailController,
|
||||||
|
keyboardType: TextInputType.emailAddress,
|
||||||
|
flex: 12,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
ModularFormField(
|
||||||
|
label: 'Mot de passe',
|
||||||
|
hint: 'Votre mot de passe',
|
||||||
|
controller: _passwordController,
|
||||||
|
isPassword: true,
|
||||||
|
validator: (value) {
|
||||||
|
if (value == null || value.isEmpty) return 'Mot de passe requis';
|
||||||
|
if (value.length < 6) return '6 caractères minimum';
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
isRequired: true,
|
||||||
|
flex: 12,
|
||||||
|
),
|
||||||
|
ModularFormField(
|
||||||
|
label: 'Confirmer le mot de passe',
|
||||||
|
hint: 'Confirmez votre mot de passe',
|
||||||
|
controller: _confirmPasswordController,
|
||||||
|
isPassword: true,
|
||||||
|
validator: (value) {
|
||||||
|
if (value == null || value.isEmpty) return 'Mot de passe requis';
|
||||||
|
if (value != _passwordController.text) return 'Les mots de passe ne correspondent pas';
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
isRequired: true,
|
||||||
|
flex: 12,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
ModularFormField(
|
||||||
|
label: 'Adresse (N° et Rue)',
|
||||||
|
hint: 'Numéro et nom de votre rue',
|
||||||
|
controller: _addressController,
|
||||||
|
isRequired: true,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
ModularFormField(
|
||||||
|
label: 'Code postal',
|
||||||
|
hint: 'Votre code postal',
|
||||||
|
controller: _postalCodeController,
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
isRequired: true,
|
||||||
|
flex: 1,
|
||||||
|
),
|
||||||
|
ModularFormField(
|
||||||
|
label: 'Ville',
|
||||||
|
hint: 'Votre ville',
|
||||||
|
controller: _cityController,
|
||||||
|
flex: 4,
|
||||||
|
isRequired: true,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
void _handleSubmit() {
|
||||||
|
if (_formKey.currentState?.validate() ?? false) {
|
||||||
|
_registrationData.updateIdentity(
|
||||||
|
ChildminderId(
|
||||||
|
firstName: _firstNameController.text,
|
||||||
|
lastName: _lastNameController.text,
|
||||||
|
address: _addressController.text,
|
||||||
|
postalCode: _postalCodeController.text,
|
||||||
|
city: _cityController.text,
|
||||||
|
phone: _phoneController.text,
|
||||||
|
email: _emailController.text,
|
||||||
|
password: _passwordController.text,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
Navigator.pushNamed(context, '/am-register/step2',
|
||||||
|
arguments: _registrationData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final screenSize = MediaQuery.of(context).size;
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
body: Stack(
|
||||||
title: const Text('Étape 1 - Inscription AM'),
|
children: [
|
||||||
),
|
Positioned.fill(
|
||||||
body: const Center(
|
child: Image.asset(
|
||||||
child: Text('Contenu de l\'étape 1'),
|
'assets/images/paper2.png',
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
repeat: ImageRepeat.repeat,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Center(
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Étape 1/4',
|
||||||
|
style: GoogleFonts.merienda(fontSize: 16, color: Colors.black54),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
Text(
|
||||||
|
'Informations de l\'assistante maternelle',
|
||||||
|
style: GoogleFonts.merienda(
|
||||||
|
fontSize: 24,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Colors.black87,
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 30),
|
||||||
|
Container(
|
||||||
|
width: screenSize.width * 0.6,
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 50, horizontal: 50),
|
||||||
|
constraints: const BoxConstraints(minHeight: 570),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
image: DecorationImage(
|
||||||
|
image: AssetImage(CardColorHorizontal.lavender.path),
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: ModularForm(
|
||||||
|
formKey: _formKey,
|
||||||
|
fieldGroups: formFields,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
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: () => Navigator.pop(context),
|
||||||
|
tooltip: 'Retour',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
top: screenSize.height / 2 - 20,
|
||||||
|
right: 40,
|
||||||
|
child: IconButton(
|
||||||
|
icon: Image.asset('assets/images/chevron_right.png', height: 40),
|
||||||
|
onPressed: _handleSubmit,
|
||||||
|
tooltip: 'Suivant',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
import 'dart:math' as math; // Pour la rotation du chevron
|
import 'dart:math' as math; // Pour la rotation du chevron
|
||||||
import '../../../models/user_registration_data.dart'; // Import du modèle de données
|
import '../../../models/parent_user_registration_data.dart'; // Import du modèle de données
|
||||||
import '../../../utils/data_generator.dart'; // Import du générateur de données
|
import '../../../utils/data_generator.dart'; // Import du générateur de données
|
||||||
import '../../../widgets/custom_app_text_field.dart'; // Import du widget CustomAppTextField
|
import '../../../widgets/custom_app_text_field.dart'; // Import du widget CustomAppTextField
|
||||||
import '../../../models/card_assets.dart'; // Import des enums de cartes
|
import '../../../models/card_assets.dart'; // Import des enums de cartes
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
import 'dart:math' as math; // Pour la rotation du chevron
|
import 'dart:math' as math; // Pour la rotation du chevron
|
||||||
import '../../../models/user_registration_data.dart'; // Import du modèle
|
import '../../../models/parent_user_registration_data.dart'; // Import du modèle
|
||||||
import '../../../utils/data_generator.dart'; // Import du générateur
|
import '../../../utils/data_generator.dart'; // Import du générateur
|
||||||
import '../../../widgets/custom_app_text_field.dart'; // Import du widget
|
import '../../../widgets/custom_app_text_field.dart'; // Import du widget
|
||||||
import '../../../models/card_assets.dart'; // Import des enums de cartes
|
import '../../../models/card_assets.dart'; // Import des enums de cartes
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import 'dart:io' show File, Platform; // Ajout de Platform
|
|||||||
import 'package:flutter/foundation.dart' show kIsWeb; // Import pour kIsWeb
|
import 'package:flutter/foundation.dart' show kIsWeb; // Import pour kIsWeb
|
||||||
import '../../../widgets/custom_app_text_field.dart'; // Import du nouveau widget TextField
|
import '../../../widgets/custom_app_text_field.dart'; // Import du nouveau widget TextField
|
||||||
import '../../../widgets/app_custom_checkbox.dart'; // Import du nouveau widget Checkbox
|
import '../../../widgets/app_custom_checkbox.dart'; // Import du nouveau widget Checkbox
|
||||||
import '../../../models/user_registration_data.dart'; // Import du modèle de données
|
import '../../../models/parent_user_registration_data.dart'; // Import du modèle de données
|
||||||
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
|
import '../../../models/card_assets.dart'; // Import des enums de cartes
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import 'package:p_tits_pas/widgets/custom_decorated_text_field.dart'; // Import
|
|||||||
import 'dart:math' as math; // Pour la rotation du chevron
|
import 'dart:math' as math; // Pour la rotation du chevron
|
||||||
import 'package:p_tits_pas/widgets/app_custom_checkbox.dart'; // Import de la checkbox personnalisée
|
import 'package:p_tits_pas/widgets/app_custom_checkbox.dart'; // Import de la checkbox personnalisée
|
||||||
// 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/parent_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
|
import '../../../models/card_assets.dart'; // Import des enums de cartes
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
import '../../../models/user_registration_data.dart'; // Utilisation du vrai modèle
|
import '../../../models/parent_user_registration_data.dart'; // Utilisation du vrai modèle
|
||||||
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;
|
||||||
|
|||||||
@ -100,6 +100,8 @@ class RegisterChoiceScreen extends StatelessWidget {
|
|||||||
onPressed: () {
|
onPressed: () {
|
||||||
// TODO: Naviguer vers l'écran d'inscription assmat
|
// TODO: Naviguer vers l'écran d'inscription assmat
|
||||||
print('Choix: Assistante Maternelle');
|
print('Choix: Assistante Maternelle');
|
||||||
|
Navigator.pushNamed(context, '/am-register/step1');
|
||||||
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
114
frontend/lib/widgets/FormFieldConfig.dart
Normal file
114
frontend/lib/widgets/FormFieldConfig.dart
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
import 'package:p_tits_pas/widgets/custom_app_text_field.dart';
|
||||||
|
|
||||||
|
class ModularFormField {
|
||||||
|
final String label;
|
||||||
|
final String hint;
|
||||||
|
final TextEditingController controller;
|
||||||
|
final TextInputType? keyboardType;
|
||||||
|
final bool isPassword;
|
||||||
|
final String? Function(String?)? validator;
|
||||||
|
final bool isRequired;
|
||||||
|
final int flex;
|
||||||
|
|
||||||
|
ModularFormField({
|
||||||
|
required this.label,
|
||||||
|
required this.hint,
|
||||||
|
required this.controller,
|
||||||
|
this.keyboardType,
|
||||||
|
this.isPassword = false,
|
||||||
|
this.validator,
|
||||||
|
this.isRequired = false,
|
||||||
|
this.flex = 1,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class ModularForm extends StatelessWidget {
|
||||||
|
final List<List<ModularFormField>> fieldGroups;
|
||||||
|
final GlobalKey<FormState> formKey;
|
||||||
|
final double? width;
|
||||||
|
final EdgeInsets padding;
|
||||||
|
final String? title;
|
||||||
|
final VoidCallback? onSubmit;
|
||||||
|
final String submitLabel;
|
||||||
|
|
||||||
|
const ModularForm({
|
||||||
|
super.key,
|
||||||
|
required this.fieldGroups,
|
||||||
|
required this.formKey,
|
||||||
|
this.width,
|
||||||
|
this.padding = const EdgeInsets.all(20),
|
||||||
|
this.title,
|
||||||
|
this.onSubmit,
|
||||||
|
this.submitLabel = "Suivant",
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
width: width ?? MediaQuery.of(context).size.width * 0.6,
|
||||||
|
padding: padding,
|
||||||
|
child: Form(
|
||||||
|
key: formKey,
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
if (title != null) ...[
|
||||||
|
Text(
|
||||||
|
title!,
|
||||||
|
style: GoogleFonts.merienda(
|
||||||
|
fontSize: 24,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
],
|
||||||
|
...fieldGroups.map((group) {
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: group.asMap().entries.map((entry) {
|
||||||
|
final index = entry.key;
|
||||||
|
final field = entry.value;
|
||||||
|
|
||||||
|
return [
|
||||||
|
Expanded(
|
||||||
|
flex: field.flex,
|
||||||
|
child: CustomAppTextField(
|
||||||
|
controller: field.controller,
|
||||||
|
labelText: field.label,
|
||||||
|
hintText: field.hint,
|
||||||
|
obscureText: field.isPassword,
|
||||||
|
keyboardType: field.keyboardType ?? TextInputType.text,
|
||||||
|
validator: field.validator,
|
||||||
|
style: CustomAppTextFieldStyle.beige,
|
||||||
|
fieldWidth: double.infinity, // CORRECTION PRINCIPALE
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// Ajouter un espaceur entre les champs (sauf pour le dernier)
|
||||||
|
if (index < group.length - 1)
|
||||||
|
const Expanded(
|
||||||
|
flex: 1,
|
||||||
|
child: SizedBox(), // Espacement de 4% comme dans l'original
|
||||||
|
),
|
||||||
|
];
|
||||||
|
}).expand((element) => element).toList(),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
if (onSubmit != null)
|
||||||
|
Center(
|
||||||
|
child: ElevatedButton(
|
||||||
|
onPressed: onSubmit,
|
||||||
|
child: Text(submitLabel),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user