feat(inscription): email accusé réception, photos enfants, formulaires identité

- Backend: mail après inscription parent avec n° dossier, UPLOAD_PHOTOS_DIR, réponse API
- Frontend: imageBytes + payload photo, utils email/code postal/téléphone, champs dédiés
- Formulaires admin, login (focus), personal_info, child_card, custom_app_text_field

Made-with: Cursor
This commit is contained in:
2026-03-31 00:04:38 +02:00
parent 110240b682
commit bf05b1d7d7
20 changed files with 1148 additions and 273 deletions
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:p_tits_pas/services/configuration_service.dart';
import 'package:p_tits_pas/utils/email_utils.dart';
import 'package:p_tits_pas/widgets/admin/relais_management_panel.dart';
/// Panneau Paramètres admin : Email (SMTP), Personnalisation, Avancé.
@@ -182,6 +183,9 @@ class _ParametresPanelState extends State<ParametresPanel> {
hintText: 'admin@example.com',
),
keyboardType: TextInputType.emailAddress,
autocorrect: false,
enableSuggestions: false,
inputFormatters: const [EmailMaxLengthFormatter()],
),
actions: [
TextButton(
@@ -191,7 +195,17 @@ class _ParametresPanelState extends State<ParametresPanel> {
FilledButton(
onPressed: () {
final t = c.text.trim();
if (t.isNotEmpty) Navigator.pop(ctx, t);
if (t.isEmpty) {
return;
}
final err = validateEmail(t, allowEmpty: true);
if (err != null) {
ScaffoldMessenger.of(ctx).showSnackBar(
SnackBar(content: Text(err)),
);
return;
}
Navigator.pop(ctx, t);
},
child: const Text('Envoyer'),
),