- Added routes for registration steps 2, 3, and 4 in app_router.dart. - Created AmRegisterStep2Screen for entering professional details including birth date, city, country, social security number, agreement number, and max children. - Implemented validation for social security number and max children fields. - Developed AmRegisterStep3Screen for entering a motivation message and accepting terms and conditions. - Created AmRegisterStep4Screen to display a summary of the registration data for review before submission. - Introduced SummaryCard widget for displaying user information in a structured format. - Enhanced DataGenerator utility to provide realistic data for testing.
252 lines
8.3 KiB
Dart
252 lines
8.3 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:google_fonts/google_fonts.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 'dart:math' as math;
|
|
|
|
class AmRegisterStep2Screen extends StatefulWidget {
|
|
final ChildminderRegistrationData registrationData;
|
|
const AmRegisterStep2Screen({super.key, required this.registrationData});
|
|
|
|
@override
|
|
State<AmRegisterStep2Screen> createState() => _AmRegisterStep2ScreenState();
|
|
}
|
|
|
|
class _AmRegisterStep2ScreenState extends State<AmRegisterStep2Screen> {
|
|
final _formKey = GlobalKey<FormState>();
|
|
late ChildminderRegistrationData _registrationData;
|
|
|
|
final _dateOfBirthController = TextEditingController();
|
|
final _birthCityController = TextEditingController();
|
|
final _birthCountryController = TextEditingController();
|
|
final _socialSecurityController = TextEditingController();
|
|
final _agreementNumberController = TextEditingController();
|
|
final _maxChildrenController = TextEditingController();
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_registrationData = widget.registrationData;
|
|
_generateAndFillData();
|
|
}
|
|
|
|
void _generateAndFillData() {
|
|
_dateOfBirthController.text = DataGenerator.birthDate();
|
|
_birthCityController.text = DataGenerator.city();
|
|
_birthCountryController.text = "France";
|
|
_socialSecurityController.text = DataGenerator.socialSecurityNumber();
|
|
_agreementNumberController.text = DataGenerator.agreementNumber();
|
|
_maxChildrenController.text = "3";
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_dateOfBirthController.dispose();
|
|
_birthCityController.dispose();
|
|
_birthCountryController.dispose();
|
|
_socialSecurityController.dispose();
|
|
_agreementNumberController.dispose();
|
|
_maxChildrenController.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
String? _validateSocialSecurity(String? value) {
|
|
if (value == null || value.isEmpty)
|
|
return 'Numéro de sécurité sociale requis';
|
|
|
|
// Supprime les espaces pour la validation
|
|
String cleanValue = value.replaceAll(' ', '');
|
|
|
|
// Vérifie que c'est bien 13 ou 15 chiffres
|
|
if (cleanValue.length != 13 && cleanValue.length != 15) {
|
|
return 'Format invalide (13 ou 15 chiffres)';
|
|
}
|
|
|
|
if (!RegExp(r'^[0-9]+$').hasMatch(cleanValue)) {
|
|
return 'Seuls les chiffres sont autorisés';
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
List<List<ModularFormField>> get formFields => [
|
|
[
|
|
ModularFormField(
|
|
label: 'Date de naissance',
|
|
hint: 'JJ/MM/AAAA',
|
|
controller: _dateOfBirthController,
|
|
keyboardType: TextInputType.datetime,
|
|
isRequired: true,
|
|
validator: (value) {
|
|
if (value == null || value.isEmpty)
|
|
return 'Date de naissance requise';
|
|
// Validation basique du format de date
|
|
if (!RegExp(r'^[0-3][0-9]/[0-1][0-9]/[1-2][0-9]{3}$')
|
|
.hasMatch(value)) {
|
|
return 'Format invalide (JJ/MM/AAAA)';
|
|
}
|
|
return null;
|
|
},
|
|
flex: 12,
|
|
),
|
|
],
|
|
[
|
|
ModularFormField(
|
|
label: 'Ville de naissance',
|
|
hint: 'Votre ville de naissance',
|
|
controller: _birthCityController,
|
|
isRequired: true,
|
|
flex: 12,
|
|
),
|
|
ModularFormField(
|
|
label: 'Pays de naissance',
|
|
hint: 'Votre pays de naissance',
|
|
controller: _birthCountryController,
|
|
isRequired: true,
|
|
flex: 12,
|
|
),
|
|
],
|
|
[
|
|
ModularFormField(
|
|
label: 'Numéro de Sécurité Sociale (NIR)',
|
|
hint: '1234567890123',
|
|
controller: _socialSecurityController,
|
|
keyboardType: TextInputType.number,
|
|
isRequired: true,
|
|
validator: _validateSocialSecurity,
|
|
),
|
|
],
|
|
[
|
|
ModularFormField(
|
|
label: 'Numéro d\'agrément',
|
|
hint: 'Votre numéro d\'agrément',
|
|
controller: _agreementNumberController,
|
|
isRequired: true,
|
|
flex: 12,
|
|
),
|
|
ModularFormField(
|
|
label: 'Nombre d\'enfants max',
|
|
hint: 'Ex: 3',
|
|
controller: _maxChildrenController,
|
|
keyboardType: TextInputType.number,
|
|
isRequired: true,
|
|
validator: (value) {
|
|
if (value == null || value.isEmpty) return 'Nombre requis';
|
|
int? number = int.tryParse(value);
|
|
if (number == null || number < 1 || number > 6) {
|
|
return 'Entre 1 et 6 enfants';
|
|
}
|
|
return null;
|
|
},
|
|
flex: 6,
|
|
),
|
|
],
|
|
];
|
|
void _handleSubmit() {
|
|
print('Vérification des données2:');
|
|
print('Adresse: ${_registrationData.identity.address}');
|
|
print('Nom: ${_registrationData.identity.lastName}');
|
|
print('Prénom: ${_registrationData.identity.firstName}');
|
|
if (_formKey.currentState?.validate() ?? false) {
|
|
_registrationData.updateProfessional(
|
|
ChildminderProfessional(
|
|
dateOfBirth: _dateOfBirthController.text,
|
|
birthCity: _birthCityController.text,
|
|
birthCountry: _birthCountryController.text,
|
|
socialSecurityNumber: _socialSecurityController.text,
|
|
agreementNumber: _agreementNumberController.text,
|
|
maxChildren: int.tryParse(_maxChildrenController.text) ?? 1,
|
|
),
|
|
);
|
|
|
|
Navigator.pushNamed(context, '/am-register/step3',
|
|
arguments: _registrationData);
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final screenSize = MediaQuery.of(context).size;
|
|
|
|
return Scaffold(
|
|
body: Stack(
|
|
children: [
|
|
Positioned.fill(
|
|
child: Image.asset(
|
|
'assets/images/paper2.png',
|
|
fit: BoxFit.cover,
|
|
repeat: ImageRepeat.repeat,
|
|
),
|
|
),
|
|
Center(
|
|
child: SingleChildScrollView(
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Text(
|
|
'Étape 2/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.peach.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',
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|