Compare commits
4
Commits
b5b32062b3
...
9557cf9947
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9557cf9947 | ||
|
|
939e7777ac | ||
|
|
b474842e19 | ||
|
|
a312d9c0fa |
@@ -0,0 +1,54 @@
|
||||
# Mini-spec — Rename préfixe `Admin*` dashboard partagé (#155)
|
||||
|
||||
**Ticket** : **#155**
|
||||
**Branche** : `feature/155-rename-admin-prefix-dashboard` (depuis `develop`)
|
||||
**Décision naming** : **option C** — dossier neutre `widgets/dashboard/` + noms **sans** préfixe `Admin`.
|
||||
|
||||
---
|
||||
|
||||
## Principe
|
||||
|
||||
Les widgets partagés **admin + gestionnaire** ne doivent plus s’appeler `Admin*`.
|
||||
On garde `Admin*` seulement là où c’est vraiment le rôle administrateur.
|
||||
|
||||
## Gardé `Admin*` (hors rename)
|
||||
|
||||
| Élément | Raison |
|
||||
|---------|--------|
|
||||
| `AdminManagementWidget` | Onglet **Administrateurs** |
|
||||
| `screens/administrateurs/*` | `AdminDashboardScreen`, `AdminCreateDialog`, `AdminUserFormDialog` |
|
||||
| `EnfantAdminModel` | Modèle API (pas un widget) — hors scope ticket |
|
||||
|
||||
## Renames faits
|
||||
|
||||
| Avant | Après |
|
||||
|-------|--------|
|
||||
| `widgets/admin/common/admin_child_detail_modal.dart` → `AdminChildDetailModal` | `widgets/dashboard/child_detail_modal.dart` → `ChildDetailModal` |
|
||||
| `admin_am_edit_modal` → `AdminAmEditModal` | `am_edit_modal` → `AmEditModal` |
|
||||
| `admin_parent_edit_modal` → `AdminParentEditModal` | `parent_edit_modal` → `ParentEditModal` |
|
||||
| `admin_user_card` → `AdminUserCard` | `user_card` → `UserCard` |
|
||||
| `admin_enfant_user_card` → `AdminEnfantUserCard` | `enfant_user_card` → `EnfantUserCard` |
|
||||
| `admin_am_photo_frame` → `AdminAmPhotoFrame` | `am_photo_frame` → `AmPhotoFrame` |
|
||||
| `admin_am_children_capacity_grid` | `am_children_capacity_grid` → `AmChildrenCapacityGrid` |
|
||||
| `admin_children_affiliation_panel` | `children_affiliation_panel` → `ChildrenAffiliationPanel` |
|
||||
| `admin_select_*` / `AdminSelect*` / `AdminFamilleFoyer` | `select_*` / `Select*` / `FamilleFoyer` |
|
||||
| `admin_status_capsule` | `status_capsule` → `StatusCapsule` |
|
||||
| `admin_list_state` → `AdminListState` | `user_list_state` → `UserListState` |
|
||||
| `admin_detail_modal` → `AdminDetailModal` / `AdminDetailField` | `detail_modal` → `DetailModal` / `DetailField` |
|
||||
| `dashboard_admin.dart` | `user_management_sub_bar.dart` (`DashboardUserManagementSubBar` inchangé) |
|
||||
|
||||
Dossier `widgets/admin/` conserve encore les panels métier (`user_management_panel`, wizards, etc.) + `AdminManagementWidget`.
|
||||
|
||||
**Phase 2** (même ticket #155) : déplacer ces panels → `widgets/dashboard/` — voir [155-suite-move-admin-panels-to-dashboard.md](./155-suite-move-admin-panels-to-dashboard.md).
|
||||
|
||||
## Hors scope
|
||||
|
||||
- Refonte UX modales (ticket dédié)
|
||||
- Rename API / back
|
||||
- Déplacer tout `widgets/admin/` → `widgets/dashboard/` (panels) — possible follow-up
|
||||
|
||||
## Critères
|
||||
|
||||
- [x] Plus de préfixe `Admin` sur les composants **partagés** listés
|
||||
- [ ] Build Flutter / recette dashboard admin + gestionnaire OK
|
||||
- [x] Pas de changement comportemental (rename mécanique)
|
||||
@@ -0,0 +1,203 @@
|
||||
# Mini-spec — Déplacer les panels `widgets/admin/` → `widgets/dashboard/`
|
||||
|
||||
**Ticket** : **#155** (phase 2 — même ticket que le rename `Admin*`)
|
||||
**Phase 1** : widgets `Admin*` → `widgets/dashboard/` (déjà sur `feature/155-rename-admin-prefix-dashboard`)
|
||||
**Branche** : poursuivre / rebaser `feature/155-rename-admin-prefix-dashboard` (ou nouvelle branche depuis `develop` après merge phase 1)
|
||||
**Nature** : rename / move mécanique — **zéro** changement UX / métier
|
||||
|
||||
---
|
||||
|
||||
## Contexte
|
||||
|
||||
Après la phase 1 (#155), la situation est **hybride** :
|
||||
|
||||
| Emplacement | Contenu |
|
||||
|-------------|---------|
|
||||
| `widgets/dashboard/` | Composants partagés sans préfixe `Admin*` (modales, cartes, selects, sub-bar…) |
|
||||
| `widgets/admin/` | **Panels** du dashboard staff (listes, wizards, validation, shell `UserManagementPanel`…) + `AdminManagementWidget` |
|
||||
|
||||
Le dossier `admin/` laisse encore croire « réservé administrateur », alors que **gestionnaire** consomme les mêmes panels (`GestionnaireDashboardScreen` → `UserManagementPanel`).
|
||||
|
||||
Ce ticket **termine l’option C** au niveau dossier : tout le dashboard staff vit sous `widgets/dashboard/`, sauf ce qui est **vraiment** rôle admin.
|
||||
|
||||
---
|
||||
|
||||
## Objectif
|
||||
|
||||
```
|
||||
frontend/lib/widgets/admin/<panels & common partagés>
|
||||
↓ git mv + update imports
|
||||
frontend/lib/widgets/dashboard/…
|
||||
```
|
||||
|
||||
Critère : un nouveau dev ne doit plus ouvrir `widgets/admin/` pour du code partagé admin+gestionnaire.
|
||||
|
||||
---
|
||||
|
||||
## Cible d’arborescence (proposée)
|
||||
|
||||
```
|
||||
widgets/dashboard/
|
||||
├── (déjà là #155) child_detail_modal.dart, am_edit_modal.dart, user_card.dart, …
|
||||
├── user_management_panel.dart ← shell onglets
|
||||
├── user_management_sub_bar.dart ← déjà déplacé #155
|
||||
├── dossiers_management_widget.dart
|
||||
├── dossier_list_card.dart
|
||||
├── parent_management_widget.dart ← corriger le typo managmant au passage ?
|
||||
├── enfant_management_widget.dart
|
||||
├── assistante_maternelle_management_widget.dart
|
||||
├── gestionnaire_management_widget.dart
|
||||
├── pending_validation_widget.dart
|
||||
├── parent_dossier_create_modal.dart
|
||||
├── parent_dossier_wizard.dart
|
||||
├── am_dossier_create_modal.dart
|
||||
├── am_dossier_wizard.dart
|
||||
├── validation_*.dart ← family/am wizards, refus, theme, confirm
|
||||
├── parametres_panel.dart ← utilisé par écran admin (OK dans dashboard)
|
||||
├── relais_management_panel.dart
|
||||
├── common/ ← sous-dossier optionnel
|
||||
│ ├── suppression_confirm_dialog.dart
|
||||
│ ├── user_list.dart
|
||||
│ └── validation_detail_section.dart
|
||||
└── …
|
||||
|
||||
widgets/admin/ ← mince, rôle admin seulement
|
||||
└── admin_management_widget.dart ← onglet Administrateurs
|
||||
```
|
||||
|
||||
### Variante B (plus stricte)
|
||||
|
||||
`AdminManagementWidget` + éventuels helpers purement admin →
|
||||
`screens/administrateurs/widgets/`
|
||||
et **suppression** du dossier `widgets/admin/`.
|
||||
|
||||
**Reco** : **variante A** (garder `widgets/admin/` minimal avec seulement `AdminManagementWidget`) — moins de churn screens, clair.
|
||||
|
||||
---
|
||||
|
||||
## Inventaire à déplacer (état actuel)
|
||||
|
||||
### Racine `widgets/admin/` → `widgets/dashboard/`
|
||||
|
||||
| Fichier actuel | Notes |
|
||||
|----------------|--------|
|
||||
| `user_management_panel.dart` | Shell partagé admin + gestionnaire |
|
||||
| `dossiers_management_widget.dart` | |
|
||||
| `dossier_list_card.dart` | |
|
||||
| `parent_managmant_widget.dart` | Typo historique `managmant` — **option** : renommer → `parent_management_widget.dart` dans le même ticket ou ticket typo séparé |
|
||||
| `enfant_management_widget.dart` | |
|
||||
| `assistante_maternelle_management_widget.dart` | |
|
||||
| `gestionnaire_management_widget.dart` | |
|
||||
| `pending_validation_widget.dart` | |
|
||||
| `parent_dossier_create_modal.dart` | |
|
||||
| `parent_dossier_wizard.dart` | |
|
||||
| `am_dossier_create_modal.dart` | |
|
||||
| `am_dossier_wizard.dart` | |
|
||||
| `validation_am_wizard.dart` | |
|
||||
| `validation_family_wizard.dart` | |
|
||||
| `validation_dossier_modal.dart` | |
|
||||
| `validation_modal_theme.dart` | |
|
||||
| `validation_refus_form.dart` | |
|
||||
| `validation_valider_confirm_dialog.dart` | |
|
||||
| `parametres_panel.dart` | Écran admin seulement, mais pas préfixé Admin — OK dashboard |
|
||||
| `relais_management_panel.dart` | |
|
||||
|
||||
### `widgets/admin/common/` → `widgets/dashboard/common/` (ou plat)
|
||||
|
||||
| Fichier | Notes |
|
||||
|---------|--------|
|
||||
| `suppression_confirm_dialog.dart` | Partagé (y compris `screens/administrateurs/creation/*`) |
|
||||
| `user_list.dart` | |
|
||||
| `validation_detail_section.dart` | |
|
||||
|
||||
### **Ne pas** déplacer
|
||||
|
||||
| Fichier | Destination |
|
||||
|---------|-------------|
|
||||
| `admin_management_widget.dart` | Reste `widgets/admin/` (ou variante B → screens) |
|
||||
|
||||
### Déjà fait (#155) — ne pas retraiter
|
||||
|
||||
Tout ce qui est déjà sous `widgets/dashboard/` (`child_detail_modal`, `am_edit_modal`, `user_card`, `select_*`, `user_management_sub_bar`, …).
|
||||
|
||||
---
|
||||
|
||||
## Consommateurs d’imports (à mettre à jour)
|
||||
|
||||
### Screens
|
||||
- `screens/administrateurs/admin_dashboardScreen.dart` — `UserManagementPanel`, `ParametresPanel`
|
||||
- `screens/gestionnaire/gestionnaire_dashboard_screen.dart` — `UserManagementPanel`
|
||||
- `screens/administrateurs/creation/admin_create.dart` — `suppression_confirm_dialog`
|
||||
- `screens/administrateurs/creation/gestionnaires_create.dart` — idem
|
||||
|
||||
### Widgets déjà en `dashboard/`
|
||||
- `am_edit_modal`, `child_detail_modal`, `parent_edit_modal`, `select_*` — imports vers `widgets/admin/common/*` ou panels
|
||||
|
||||
### Divers
|
||||
- `widgets/common/identity_block.dart` (si import admin)
|
||||
- Tous les fichiers **déplacés** entre eux (imports relatifs / package)
|
||||
|
||||
### Hors scope rename classes
|
||||
Sauf décision explicite sur le typo `parent_managmant_widget` → pas de rename de **classes** métier dans ce ticket (seulement chemins de fichiers + imports).
|
||||
`AdminManagementWidget` **conserve** son nom.
|
||||
|
||||
---
|
||||
|
||||
## Plan d’exécution
|
||||
|
||||
1. Partir de `feature/155-rename-admin-prefix-dashboard` (phase 1) **ou** `develop` si phase 1 déjà mergée
|
||||
2. `git mv` fichiers selon inventaire
|
||||
3. Remplacer globalement
|
||||
`package:p_tits_pas/widgets/admin/` → `package:p_tits_pas/widgets/dashboard/`
|
||||
**sauf** `…/widgets/admin/admin_management_widget.dart`
|
||||
4. Corriger imports relatifs cassés
|
||||
5. Grep de contrôle (ci-dessous)
|
||||
6. Build Flutter web (Docker) + smoke dashboard admin **et** gestionnaire
|
||||
7. Merge → squash master si flux habituel
|
||||
|
||||
---
|
||||
|
||||
## Vérifs
|
||||
|
||||
```bash
|
||||
# Plus de panels partagés sous admin (seul AdminManagement attendu)
|
||||
find frontend/lib/widgets/admin -name '*.dart'
|
||||
|
||||
# Plus d’imports panels vers l’ancien chemin (sauf AdminManagement)
|
||||
rg -n "widgets/admin/(user_management|dossiers_|parent_|enfant_|assistante|gestionnaire|pending|validation_|parametres|relais|am_dossier|parent_dossier|dossier_list|common/)" frontend/lib
|
||||
|
||||
# Screens OK
|
||||
rg -n "widgets/admin/" frontend/lib/screens
|
||||
```
|
||||
|
||||
Attendu screens : **0** hit vers panels ; éventuellement plus aucun hit `widgets/admin/` sauf si import explicite `AdminManagementWidget` depuis `user_management_panel` (chemin `widgets/admin/admin_management_widget.dart`).
|
||||
|
||||
---
|
||||
|
||||
## Hors scope
|
||||
|
||||
- Refonte UX des modales / panels (ticket dédié annoncé)
|
||||
- Rename `EnfantAdminModel`
|
||||
- Rename `screens/administrateurs/`
|
||||
- Rename `AdminUserFormDialog` / `AdminCreateDialog`
|
||||
- Changement API / back
|
||||
- #152 (`est_multiple`) — autre branche
|
||||
|
||||
---
|
||||
|
||||
## Critères d’acceptation
|
||||
|
||||
- [ ] Inventaire déplacé selon tableau
|
||||
- [ ] `widgets/admin/` ne contient plus que `admin_management_widget.dart` (variante A)
|
||||
- [ ] Imports screens + widgets à jour
|
||||
- [ ] Build Flutter OK
|
||||
- [ ] Recette : dashboard **administrateur** et **gestionnaire** (listes, ouverture fiches, validation, création dossier) sans régression
|
||||
- [ ] Aucun changement comportemental volontaire
|
||||
|
||||
---
|
||||
|
||||
## Risques / notes
|
||||
|
||||
- **Conflits de merge** si d’autres features touchent les panels → faire ce ticket quand la surface dashboard est calme (fin 0.1.0 OK)
|
||||
- Typo `parent_managmant_widget` : soit inclus (bonus), soit ticket cleanup 1-ligne séparé
|
||||
- Docs d’archive citant `widgets/admin/…` : pas obligatoire de mettre à jour ; `docs/27_BRIEFING-FRONTEND.md` oui si encore listé
|
||||
@@ -2,9 +2,9 @@ import 'package:flutter/material.dart';
|
||||
import 'package:p_tits_pas/models/user.dart';
|
||||
import 'package:p_tits_pas/services/auth_service.dart';
|
||||
import 'package:p_tits_pas/services/configuration_service.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/dashboard_admin.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/parametres_panel.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/user_management_panel.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/user_management_sub_bar.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/parametres_panel.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/user_management_panel.dart';
|
||||
import 'package:p_tits_pas/widgets/app_footer.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/dashboard_bandeau.dart';
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import 'package:p_tits_pas/utils/phone_utils.dart';
|
||||
import 'package:p_tits_pas/models/user.dart';
|
||||
import 'package:p_tits_pas/services/user_service.dart';
|
||||
import 'package:p_tits_pas/utils/email_utils.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/suppression_confirm_dialog.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/common/suppression_confirm_dialog.dart';
|
||||
import 'package:p_tits_pas/widgets/email_text_field.dart';
|
||||
import 'package:p_tits_pas/widgets/french_phone_field.dart';
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import 'package:p_tits_pas/services/auth_service.dart';
|
||||
import 'package:p_tits_pas/services/relais_service.dart';
|
||||
import 'package:p_tits_pas/services/user_service.dart';
|
||||
import 'package:p_tits_pas/utils/staff_deletion_rights.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/suppression_confirm_dialog.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/common/suppression_confirm_dialog.dart';
|
||||
|
||||
class AdminUserFormDialog extends StatefulWidget {
|
||||
final AppUser? initialUser;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:p_tits_pas/models/user.dart';
|
||||
import 'package:p_tits_pas/services/auth_service.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/user_management_panel.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/user_management_panel.dart';
|
||||
import 'package:p_tits_pas/widgets/app_footer.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/dashboard_bandeau.dart';
|
||||
|
||||
|
||||
@@ -5,9 +5,9 @@ import 'package:p_tits_pas/screens/administrateurs/creation/gestionnaires_create
|
||||
import 'package:p_tits_pas/services/auth_service.dart';
|
||||
import 'package:p_tits_pas/services/user_service.dart';
|
||||
import 'package:p_tits_pas/utils/staff_deletion_rights.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_user_card.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/suppression_confirm_dialog.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/user_list.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/user_card.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/common/suppression_confirm_dialog.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/common/user_list.dart';
|
||||
|
||||
class AdminManagementWidget extends StatefulWidget {
|
||||
final String searchQuery;
|
||||
@@ -183,7 +183,7 @@ class _AdminManagementWidgetState extends State<AdminManagementWidget> {
|
||||
final isSuperAdmin = _isSuperAdmin(user);
|
||||
final canEdit = _canEditAdmin(user);
|
||||
final canDelete = _canDeleteAdmin(user);
|
||||
return AdminUserCard(
|
||||
return UserCard(
|
||||
title: user.fullName,
|
||||
fallbackIcon: isSuperAdmin
|
||||
? Icons.verified_user_outlined
|
||||
|
||||
@@ -3,7 +3,7 @@ import 'package:p_tits_pas/models/dossier_unifie.dart';
|
||||
import 'package:p_tits_pas/models/user.dart';
|
||||
import 'package:p_tits_pas/utils/name_format_utils.dart';
|
||||
import 'package:p_tits_pas/utils/phone_utils.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/validation_detail_section.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/common/validation_detail_section.dart';
|
||||
|
||||
/// Valeurs affichées dans un [IdentityBlock] en lecture seule.
|
||||
class IdentityValues {
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@ import 'package:p_tits_pas/utils/date_display_utils.dart';
|
||||
import 'package:p_tits_pas/widgets/common/auth_network_image.dart';
|
||||
|
||||
/// Grille 2×2 des places d'accueil AM (max 4, limitée à [capacity]).
|
||||
class AdminAmChildrenCapacityGrid extends StatelessWidget {
|
||||
class AmChildrenCapacityGrid extends StatelessWidget {
|
||||
static const int _gridSlots = 4;
|
||||
static const double _slotHeight = 44;
|
||||
static const double _gridPadding = 10;
|
||||
@@ -23,7 +23,7 @@ class AdminAmChildrenCapacityGrid extends StatelessWidget {
|
||||
/// Clic sur une case libre → même flux que « Rattacher un enfant » (#149).
|
||||
final VoidCallback? onAttachEmpty;
|
||||
|
||||
const AdminAmChildrenCapacityGrid({
|
||||
const AmChildrenCapacityGrid({
|
||||
super.key,
|
||||
required this.children,
|
||||
required this.capacity,
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/am_dossier_wizard.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/am_dossier_wizard.dart';
|
||||
|
||||
/// Modale de création dossier AM (#156) — même shell que [ValidationDossierModal].
|
||||
class AmDossierCreateModal extends StatefulWidget {
|
||||
+18
-18
@@ -14,12 +14,12 @@ import 'package:p_tits_pas/utils/name_format_utils.dart';
|
||||
import 'package:p_tits_pas/utils/nir_utils.dart';
|
||||
import 'package:p_tits_pas/utils/phone_utils.dart';
|
||||
import 'package:p_tits_pas/utils/postal_utils.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_am_photo_frame.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_detail_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/validation_detail_section.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/validation_modal_theme.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/validation_refus_form.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/validation_valider_confirm_dialog.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/am_photo_frame.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/detail_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/common/validation_detail_section.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/validation_modal_theme.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/validation_refus_form.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/validation_valider_confirm_dialog.dart';
|
||||
import 'package:p_tits_pas/widgets/common/auth_network_image.dart';
|
||||
import 'package:p_tits_pas/widgets/common/identity_block.dart';
|
||||
|
||||
@@ -221,32 +221,32 @@ class _AmDossierWizardState extends State<AmDossierWizard> {
|
||||
|
||||
void _emitStep() => widget.onStepChanged?.call(_step, _stepCount);
|
||||
|
||||
List<AdminDetailField> _photoProFields(DossierAM d) {
|
||||
List<DetailField> _photoProFields(DossierAM d) {
|
||||
final u = d.user;
|
||||
return [
|
||||
AdminDetailField(label: 'NIR', value: _formatNirForDisplay(d.nir)),
|
||||
AdminDetailField(
|
||||
DetailField(label: 'NIR', value: _formatNirForDisplay(d.nir)),
|
||||
DetailField(
|
||||
label: 'Date de naissance',
|
||||
value: formatIsoDateFr(u.dateNaissance),
|
||||
),
|
||||
AdminDetailField(
|
||||
DetailField(
|
||||
label: 'Ville de naissance',
|
||||
value: _v(u.lieuNaissanceVille),
|
||||
),
|
||||
AdminDetailField(
|
||||
DetailField(
|
||||
label: 'Pays de naissance',
|
||||
value: _v(u.lieuNaissancePays),
|
||||
),
|
||||
AdminDetailField(label: 'N° Agrément', value: _v(d.numeroAgrement)),
|
||||
AdminDetailField(
|
||||
DetailField(label: 'N° Agrément', value: _v(d.numeroAgrement)),
|
||||
DetailField(
|
||||
label: 'Date d’agrément',
|
||||
value: formatIsoDateFr(d.dateAgrement),
|
||||
),
|
||||
AdminDetailField(
|
||||
DetailField(
|
||||
label: 'Capacité max (enfants)',
|
||||
value: d.nbMaxEnfants != null ? d.nbMaxEnfants.toString() : '–',
|
||||
),
|
||||
AdminDetailField(
|
||||
DetailField(
|
||||
label: 'Places disponibles',
|
||||
value: d.placesDisponibles != null
|
||||
? d.placesDisponibles.toString()
|
||||
@@ -741,14 +741,14 @@ class _AmDossierWizardState extends State<AmDossierWizard> {
|
||||
|
||||
Widget _buildStep1() {
|
||||
// Modale calée sur les TF ; photo étirée sur toute la hauteur utile
|
||||
// (largeur = [AdminAmPhotoFrame.columnWidthForHeight], cadre inclus).
|
||||
// (largeur = [AmPhotoFrame.columnWidthForHeight], cadre inclus).
|
||||
return LayoutBuilder(
|
||||
builder: (context, c) {
|
||||
final maxRowW = c.maxWidth;
|
||||
final maxRowH = c.maxHeight.clamp(0.0, double.infinity);
|
||||
final maxPhotoW = (maxRowW - _photoProGap - _proColumnMinWidth)
|
||||
.clamp(0.0, double.infinity);
|
||||
var photoW = AdminAmPhotoFrame.columnWidthForHeight(maxRowH)
|
||||
var photoW = AmPhotoFrame.columnWidthForHeight(maxRowH)
|
||||
.clamp(_photoColumnMinWidth, 360.0);
|
||||
if (photoW > maxPhotoW) photoW = maxPhotoW;
|
||||
|
||||
@@ -762,7 +762,7 @@ class _AmDossierWizardState extends State<AmDossierWizard> {
|
||||
|
||||
final Widget photo;
|
||||
if (_isCreate) {
|
||||
photo = AdminAmPhotoFrame(
|
||||
photo = AmPhotoFrame(
|
||||
imageBytes: _photoBytes,
|
||||
onTap: _pickPhoto,
|
||||
onClear: _photoBytes != null ? _clearPhoto : null,
|
||||
+17
-17
@@ -7,31 +7,31 @@ import 'package:p_tits_pas/utils/date_display_utils.dart';
|
||||
import 'package:p_tits_pas/utils/nir_utils.dart';
|
||||
import 'package:p_tits_pas/utils/phone_utils.dart';
|
||||
import 'package:p_tits_pas/services/user_service.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_am_children_capacity_grid.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_am_photo_frame.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_child_detail_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_select_enfant_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_status_capsule.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/validation_detail_section.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/am_children_capacity_grid.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/am_photo_frame.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/child_detail_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/select_enfant_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/status_capsule.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/common/validation_detail_section.dart';
|
||||
import 'package:p_tits_pas/widgets/common/identity_block.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/validation_modal_theme.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/validation_modal_theme.dart';
|
||||
|
||||
/// Fiche AM éditable (ticket #131) — identité | fiche pro (photo) | enfants.
|
||||
class AdminAmEditModal extends StatefulWidget {
|
||||
class AmEditModal extends StatefulWidget {
|
||||
final AssistanteMaternelleModel assistante;
|
||||
final VoidCallback? onSaved;
|
||||
|
||||
const AdminAmEditModal({
|
||||
const AmEditModal({
|
||||
super.key,
|
||||
required this.assistante,
|
||||
this.onSaved,
|
||||
});
|
||||
|
||||
@override
|
||||
State<AdminAmEditModal> createState() => _AdminAmEditModalState();
|
||||
State<AmEditModal> createState() => _AmEditModalState();
|
||||
}
|
||||
|
||||
class _AdminAmEditModalState extends State<AdminAmEditModal>
|
||||
class _AmEditModalState extends State<AmEditModal>
|
||||
with SingleTickerProviderStateMixin {
|
||||
late final TabController _tabCtrl;
|
||||
late final TextEditingController _nomCtrl;
|
||||
@@ -404,7 +404,7 @@ class _AdminAmEditModalState extends State<AdminAmEditModal>
|
||||
if (!mounted) return;
|
||||
await showDialog<void>(
|
||||
context: context,
|
||||
builder: (ctx) => AdminChildDetailModal(
|
||||
builder: (ctx) => ChildDetailModal(
|
||||
enfant: enfant,
|
||||
onSaved: _refreshChildrenDetails,
|
||||
),
|
||||
@@ -450,7 +450,7 @@ class _AdminAmEditModalState extends State<AdminAmEditModal>
|
||||
|
||||
Future<void> _attachChild() async {
|
||||
if (_capacityFull || !mounted) return;
|
||||
final selected = await AdminSelectEnfantModal.show(
|
||||
final selected = await SelectEnfantModal.show(
|
||||
context,
|
||||
excludeIds: _children.map((c) => c.id).toSet(),
|
||||
title: 'Rattacher un enfant',
|
||||
@@ -589,7 +589,7 @@ class _AdminAmEditModalState extends State<AdminAmEditModal>
|
||||
final maxRowH =
|
||||
c.maxHeight.isFinite ? c.maxHeight : _proTabHeight;
|
||||
final bodyH = maxRowH;
|
||||
final idealPhotoW = bodyH * AdminAmPhotoFrame.idPhotoAspectRatio + 16;
|
||||
final idealPhotoW = bodyH * AmPhotoFrame.idPhotoAspectRatio + 16;
|
||||
final maxPhotoW = (maxRowW - _photoProGap - _proColumnMinWidth)
|
||||
.clamp(0.0, double.infinity);
|
||||
var photoW = idealPhotoW.clamp(_photoColumnMinWidth, 220.0);
|
||||
@@ -600,7 +600,7 @@ class _AdminAmEditModalState extends State<AdminAmEditModal>
|
||||
children: [
|
||||
SizedBox(
|
||||
width: photoW,
|
||||
child: AdminAmPhotoFrame(
|
||||
child: AmPhotoFrame(
|
||||
photoUrl: widget.assistante.user.photoUrl,
|
||||
),
|
||||
),
|
||||
@@ -728,7 +728,7 @@ class _AdminAmEditModalState extends State<AdminAmEditModal>
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
AdminAmChildrenCapacityGrid(
|
||||
AmChildrenCapacityGrid(
|
||||
children: _children,
|
||||
capacity: capacity,
|
||||
onOpen: _openChild,
|
||||
@@ -820,7 +820,7 @@ class _AdminAmEditModalState extends State<AdminAmEditModal>
|
||||
const SizedBox(width: 12),
|
||||
SizedBox(
|
||||
width: 160,
|
||||
child: AdminStatusCapsule(
|
||||
child: StatusCapsule(
|
||||
statut: _statut,
|
||||
onChanged: (v) => setState(() {
|
||||
_statut = v;
|
||||
+2
-2
@@ -5,7 +5,7 @@ import 'package:p_tits_pas/services/api/api_config.dart';
|
||||
import 'package:p_tits_pas/widgets/common/auth_network_image.dart';
|
||||
|
||||
/// Cadre photo identité AM / enfant (35×45 mm) — même logique que [ValidationAmWizard].
|
||||
class AdminAmPhotoFrame extends StatelessWidget {
|
||||
class AmPhotoFrame extends StatelessWidget {
|
||||
final String? photoUrl;
|
||||
final Uint8List? imageBytes;
|
||||
final VoidCallback? onTap;
|
||||
@@ -14,7 +14,7 @@ class AdminAmPhotoFrame extends StatelessWidget {
|
||||
|
||||
static const double idPhotoAspectRatio = 35 / 45;
|
||||
|
||||
const AdminAmPhotoFrame({
|
||||
const AmPhotoFrame({
|
||||
super.key,
|
||||
this.photoUrl,
|
||||
this.imageBytes,
|
||||
+6
-6
@@ -5,10 +5,10 @@ import 'package:p_tits_pas/utils/am_vigilance.dart';
|
||||
import 'package:p_tits_pas/services/auth_service.dart';
|
||||
import 'package:p_tits_pas/services/user_service.dart';
|
||||
import 'package:p_tits_pas/utils/staff_deletion_rights.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_am_edit_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_user_card.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/suppression_confirm_dialog.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/user_list.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/am_edit_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/user_card.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/common/suppression_confirm_dialog.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/common/user_list.dart';
|
||||
|
||||
class AssistanteMaternelleManagementWidget extends StatefulWidget {
|
||||
final String searchQuery;
|
||||
@@ -130,7 +130,7 @@ class _AssistanteMaternelleManagementWidgetState
|
||||
itemBuilder: (context, index) {
|
||||
final assistante = filteredAssistantes[index];
|
||||
final vigilance = amPlacesVigilanceMessage(assistante);
|
||||
return AdminUserCard(
|
||||
return UserCard(
|
||||
title: assistante.user.fullName,
|
||||
avatarUrl: assistante.user.photoUrl,
|
||||
fallbackIcon: Icons.face,
|
||||
@@ -161,7 +161,7 @@ class _AssistanteMaternelleManagementWidgetState
|
||||
void _openAssistanteDetails(AssistanteMaternelleModel assistante) {
|
||||
showDialog<void>(
|
||||
context: context,
|
||||
builder: (context) => AdminAmEditModal(
|
||||
builder: (context) => AmEditModal(
|
||||
assistante: assistante,
|
||||
onSaved: _loadAssistantes,
|
||||
),
|
||||
+20
-20
@@ -11,24 +11,24 @@ import 'package:p_tits_pas/utils/date_display_utils.dart';
|
||||
import 'package:p_tits_pas/utils/enfant_status_utils.dart';
|
||||
import 'package:p_tits_pas/utils/name_format_utils.dart';
|
||||
import 'package:p_tits_pas/utils/staff_deletion_rights.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_am_edit_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_am_photo_frame.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_parent_edit_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_select_am_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_select_famille_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/suppression_confirm_dialog.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/validation_detail_section.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/validation_modal_theme.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/am_edit_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/am_photo_frame.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/parent_edit_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/select_am_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/select_famille_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/common/suppression_confirm_dialog.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/common/validation_detail_section.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/validation_modal_theme.dart';
|
||||
import 'package:p_tits_pas/widgets/common/auth_network_image.dart';
|
||||
|
||||
/// Fiche enfant consultation / édition (#138) ou création (#132).
|
||||
class AdminChildDetailModal extends StatefulWidget {
|
||||
class ChildDetailModal extends StatefulWidget {
|
||||
final EnfantAdminModel? enfant;
|
||||
final VoidCallback? onSaved;
|
||||
final VoidCallback? onDeleted;
|
||||
final bool isCreating;
|
||||
|
||||
const AdminChildDetailModal({
|
||||
const ChildDetailModal({
|
||||
super.key,
|
||||
required EnfantAdminModel this.enfant,
|
||||
this.onSaved,
|
||||
@@ -36,7 +36,7 @@ class AdminChildDetailModal extends StatefulWidget {
|
||||
}) : isCreating = false;
|
||||
|
||||
/// Création depuis l'onglet Enfants (#132).
|
||||
const AdminChildDetailModal.create({
|
||||
const ChildDetailModal.create({
|
||||
super.key,
|
||||
this.onSaved,
|
||||
}) : enfant = null,
|
||||
@@ -44,10 +44,10 @@ class AdminChildDetailModal extends StatefulWidget {
|
||||
isCreating = true;
|
||||
|
||||
@override
|
||||
State<AdminChildDetailModal> createState() => _AdminChildDetailModalState();
|
||||
State<ChildDetailModal> createState() => _ChildDetailModalState();
|
||||
}
|
||||
|
||||
class _AdminChildDetailModalState extends State<AdminChildDetailModal> {
|
||||
class _ChildDetailModalState extends State<ChildDetailModal> {
|
||||
late final TextEditingController _prenomCtrl;
|
||||
late final TextEditingController _nomCtrl;
|
||||
late final TextEditingController _birthCtrl;
|
||||
@@ -65,7 +65,7 @@ class _AdminChildDetailModalState extends State<AdminChildDetailModal> {
|
||||
String? _baselineAmUserId;
|
||||
|
||||
/// Famille choisie en mode création (#132).
|
||||
AdminFamilleFoyer? _selectedFamily;
|
||||
FamilleFoyer? _selectedFamily;
|
||||
|
||||
/// Liens parents locaux (édition) — mis à jour après rattachement foyer (#157).
|
||||
List<EnfantParentLink>? _localParentLinks;
|
||||
@@ -283,7 +283,7 @@ class _AdminChildDetailModalState extends State<AdminChildDetailModal> {
|
||||
if (!mounted) return;
|
||||
await showDialog<void>(
|
||||
context: context,
|
||||
builder: (ctx) => AdminParentEditModal(
|
||||
builder: (ctx) => ParentEditModal(
|
||||
parent: parent,
|
||||
onSaved: () => widget.onSaved?.call(),
|
||||
),
|
||||
@@ -624,7 +624,7 @@ class _AdminChildDetailModalState extends State<AdminChildDetailModal> {
|
||||
if (am == null) return;
|
||||
await showDialog<void>(
|
||||
context: context,
|
||||
builder: (ctx) => AdminAmEditModal(
|
||||
builder: (ctx) => AmEditModal(
|
||||
assistante: am,
|
||||
onSaved: () async {
|
||||
await _reloadPlacementFromServer();
|
||||
@@ -676,7 +676,7 @@ class _AdminChildDetailModalState extends State<AdminChildDetailModal> {
|
||||
}
|
||||
|
||||
if (!mounted) return;
|
||||
final selected = await AdminSelectAmModal.show(
|
||||
final selected = await SelectAmModal.show(
|
||||
context,
|
||||
excludeIds: {
|
||||
if (_linkedAm != null) _linkedAm!.user.id,
|
||||
@@ -986,7 +986,7 @@ class _AdminChildDetailModalState extends State<AdminChildDetailModal> {
|
||||
final maxRowW = c.maxWidth;
|
||||
final maxRowH = c.maxHeight;
|
||||
final idealPhotoW =
|
||||
maxRowH * AdminAmPhotoFrame.idPhotoAspectRatio + 16;
|
||||
maxRowH * AmPhotoFrame.idPhotoAspectRatio + 16;
|
||||
final maxPhotoW = (maxRowW - _photoProGap - _proColumnMinWidth)
|
||||
.clamp(0.0, double.infinity);
|
||||
var photoW = idealPhotoW.clamp(_photoColumnMinWidth, _photoColumnMaxWidth);
|
||||
@@ -1001,7 +1001,7 @@ class _AdminChildDetailModalState extends State<AdminChildDetailModal> {
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Expanded(
|
||||
child: AdminAmPhotoFrame(
|
||||
child: AmPhotoFrame(
|
||||
photoUrl: widget.isCreating
|
||||
? null
|
||||
: widget.enfant?.photoUrl,
|
||||
@@ -1329,7 +1329,7 @@ class _AdminChildDetailModalState extends State<AdminChildDetailModal> {
|
||||
|
||||
Future<void> _pickFamily() async {
|
||||
if (_busy) return;
|
||||
final selected = await AdminSelectFamilleModal.show(
|
||||
final selected = await SelectFamilleModal.show(
|
||||
context,
|
||||
title: 'Choisir une famille',
|
||||
);
|
||||
+4
-4
@@ -1,9 +1,9 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:p_tits_pas/models/parent_child_summary.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_enfant_user_card.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/enfant_user_card.dart';
|
||||
|
||||
/// Liste scrollable d'enfants rattachés (fiche parent / fiche AM).
|
||||
class AdminChildrenAffiliationPanel extends StatelessWidget {
|
||||
class ChildrenAffiliationPanel extends StatelessWidget {
|
||||
final List<ParentChildSummary> children;
|
||||
final ScrollController scrollController;
|
||||
final void Function(ParentChildSummary child) onOpen;
|
||||
@@ -14,7 +14,7 @@ class AdminChildrenAffiliationPanel extends StatelessWidget {
|
||||
static const double _itemHeight = 58;
|
||||
static const double defaultViewportHeight = _itemHeight * 2.5 + 8;
|
||||
|
||||
const AdminChildrenAffiliationPanel({
|
||||
const ChildrenAffiliationPanel({
|
||||
super.key,
|
||||
required this.children,
|
||||
required this.scrollController,
|
||||
@@ -62,7 +62,7 @@ class AdminChildrenAffiliationPanel extends StatelessWidget {
|
||||
itemCount: children.length,
|
||||
itemBuilder: (_, i) {
|
||||
final c = children[i];
|
||||
return AdminEnfantUserCard.fromSummary(
|
||||
return EnfantUserCard.fromSummary(
|
||||
c,
|
||||
onCardTap: () => onOpen(c),
|
||||
actions: [
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_list_state.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/user_list_state.dart';
|
||||
|
||||
class UserList extends StatelessWidget {
|
||||
final bool isLoading;
|
||||
@@ -28,7 +28,7 @@ class UserList extends StatelessWidget {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
AdminListState(
|
||||
UserListState(
|
||||
isLoading: isLoading,
|
||||
error: error,
|
||||
isEmpty: isEmpty,
|
||||
+2
-2
@@ -4,7 +4,7 @@ import 'package:p_tits_pas/utils/email_utils.dart';
|
||||
import 'package:p_tits_pas/utils/nir_utils.dart';
|
||||
import 'package:p_tits_pas/utils/phone_utils.dart';
|
||||
import 'package:p_tits_pas/utils/postal_utils.dart';
|
||||
import 'admin_detail_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/detail_modal.dart';
|
||||
|
||||
/// Réglages des formulaires validation / wizard AM — **jouer sur ces 3 leviers**.
|
||||
class ValidationFormMetrics {
|
||||
@@ -60,7 +60,7 @@ class ValidationFormMetrics {
|
||||
class ValidationDetailSection extends StatelessWidget {
|
||||
/// Si null ou vide, pas de bandeau titre (gain de place vertical, ex. wizard AM).
|
||||
final String? title;
|
||||
final List<AdminDetailField> fields;
|
||||
final List<DetailField> fields;
|
||||
|
||||
/// Nombre de champs par ligne (1 = plein largeur, 2 = deux côte à côte). Ex. [2, 2, 1, 2] pour identité.
|
||||
final List<int>? rowLayout;
|
||||
+5
-5
@@ -1,23 +1,23 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class AdminDetailField {
|
||||
class DetailField {
|
||||
final String label;
|
||||
final String value;
|
||||
|
||||
const AdminDetailField({
|
||||
const DetailField({
|
||||
required this.label,
|
||||
required this.value,
|
||||
});
|
||||
}
|
||||
|
||||
class AdminDetailModal extends StatelessWidget {
|
||||
class DetailModal extends StatelessWidget {
|
||||
final String title;
|
||||
final String? subtitle;
|
||||
final List<AdminDetailField> fields;
|
||||
final List<DetailField> fields;
|
||||
final VoidCallback onEdit;
|
||||
final VoidCallback onDelete;
|
||||
|
||||
const AdminDetailModal({
|
||||
const DetailModal({
|
||||
super.key,
|
||||
required this.title,
|
||||
this.subtitle,
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_user_card.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/suppression_confirm_dialog.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/user_card.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/common/suppression_confirm_dialog.dart';
|
||||
|
||||
/// Carte dossier unifiée (#153) — fond neutre, accent couleur sur l’icône.
|
||||
class DossierListCard extends StatelessWidget {
|
||||
@@ -54,7 +54,7 @@ class DossierListCard extends StatelessWidget {
|
||||
if (!emptyKids && countLabel != null) countLabel,
|
||||
];
|
||||
|
||||
return AdminUserCard(
|
||||
return UserCard(
|
||||
title: num,
|
||||
subtitleLines: subtitle,
|
||||
avatarUrl: !isFamille && avatar.isNotEmpty ? avatar : null,
|
||||
+4
-4
@@ -3,10 +3,10 @@ import 'package:p_tits_pas/models/dossier_list_item.dart';
|
||||
import 'package:p_tits_pas/services/auth_service.dart';
|
||||
import 'package:p_tits_pas/services/user_service.dart';
|
||||
import 'package:p_tits_pas/utils/staff_deletion_rights.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/dossier_list_card.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/pending_validation_widget.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/suppression_confirm_dialog.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/validation_dossier_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/dossier_list_card.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/pending_validation_widget.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/common/suppression_confirm_dialog.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/validation_dossier_modal.dart';
|
||||
|
||||
/// Onglet permanent « Dossiers » (#153) : pending en haut + liste unifiée en bas.
|
||||
class DossiersManagementWidget extends StatefulWidget {
|
||||
+6
-6
@@ -5,10 +5,10 @@ import 'package:p_tits_pas/models/enfant_admin_model.dart';
|
||||
import 'package:p_tits_pas/services/auth_service.dart';
|
||||
import 'package:p_tits_pas/services/user_service.dart';
|
||||
import 'package:p_tits_pas/utils/staff_deletion_rights.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_child_detail_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_enfant_user_card.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/suppression_confirm_dialog.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/user_list.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/child_detail_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/enfant_user_card.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/common/suppression_confirm_dialog.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/common/user_list.dart';
|
||||
|
||||
/// Onglet liste globale des enfants (doc 28 §6.2, ticket #137).
|
||||
class EnfantManagementWidget extends StatefulWidget {
|
||||
@@ -68,7 +68,7 @@ class _EnfantManagementWidgetState extends State<EnfantManagementWidget> {
|
||||
Future<void> _openEnfant(EnfantAdminModel enfant) async {
|
||||
await showDialog<void>(
|
||||
context: context,
|
||||
builder: (ctx) => AdminChildDetailModal(
|
||||
builder: (ctx) => ChildDetailModal(
|
||||
enfant: enfant,
|
||||
onSaved: _loadEnfants,
|
||||
onDeleted: _loadEnfants,
|
||||
@@ -224,7 +224,7 @@ class _EnfantManagementWidgetState extends State<EnfantManagementWidget> {
|
||||
itemCount: filtered.length,
|
||||
itemBuilder: (context, index) {
|
||||
final enfant = filtered[index];
|
||||
return AdminEnfantUserCard.fromEnfant(
|
||||
return EnfantUserCard.fromEnfant(
|
||||
enfant,
|
||||
onCardTap: () => _openEnfant(enfant),
|
||||
actions: [
|
||||
+8
-8
@@ -4,7 +4,7 @@ import 'package:p_tits_pas/models/parent_child_summary.dart';
|
||||
import 'package:p_tits_pas/utils/date_display_utils.dart';
|
||||
import 'package:p_tits_pas/utils/enfant_status_utils.dart';
|
||||
import 'package:p_tits_pas/utils/enfant_vigilance.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_user_card.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/user_card.dart';
|
||||
|
||||
List<String> enfantAdminSubtitleLines({
|
||||
required String status,
|
||||
@@ -29,7 +29,7 @@ List<String> enfantAdminSubtitleLines({
|
||||
}
|
||||
|
||||
/// Carte enfant admin (photo, nom, âge) — même rendu onglet Enfants / fiche parent.
|
||||
class AdminEnfantUserCard extends StatelessWidget {
|
||||
class EnfantUserCard extends StatelessWidget {
|
||||
final String title;
|
||||
final String? photoUrl;
|
||||
final List<String> subtitleLines;
|
||||
@@ -40,7 +40,7 @@ class AdminEnfantUserCard extends StatelessWidget {
|
||||
final Color? borderColor;
|
||||
final String? vigilanceTooltip;
|
||||
|
||||
const AdminEnfantUserCard({
|
||||
const EnfantUserCard({
|
||||
super.key,
|
||||
required this.title,
|
||||
this.photoUrl,
|
||||
@@ -53,7 +53,7 @@ class AdminEnfantUserCard extends StatelessWidget {
|
||||
this.vigilanceTooltip,
|
||||
});
|
||||
|
||||
factory AdminEnfantUserCard.fromEnfant(
|
||||
factory EnfantUserCard.fromEnfant(
|
||||
EnfantAdminModel enfant, {
|
||||
List<String> extraSubtitleLines = const [],
|
||||
List<Widget> actions = const [],
|
||||
@@ -67,7 +67,7 @@ class AdminEnfantUserCard extends StatelessWidget {
|
||||
.map((l) => l.parentName ?? 'Parent')
|
||||
.join(', ');
|
||||
final orphan = enfantHasNoResponsable(enfant);
|
||||
return AdminEnfantUserCard(
|
||||
return EnfantUserCard(
|
||||
title: enfant.fullName,
|
||||
photoUrl: enfant.photoUrl,
|
||||
subtitleLines: enfantAdminSubtitleLines(
|
||||
@@ -92,7 +92,7 @@ class AdminEnfantUserCard extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
factory AdminEnfantUserCard.fromSummary(
|
||||
factory EnfantUserCard.fromSummary(
|
||||
ParentChildSummary child, {
|
||||
List<String> extraSubtitleLines = const [],
|
||||
List<Widget> actions = const [],
|
||||
@@ -100,7 +100,7 @@ class AdminEnfantUserCard extends StatelessWidget {
|
||||
EdgeInsetsGeometry? margin,
|
||||
EdgeInsetsGeometry? contentPadding,
|
||||
}) {
|
||||
return AdminEnfantUserCard(
|
||||
return EnfantUserCard(
|
||||
title: child.fullName,
|
||||
photoUrl: child.photoUrl,
|
||||
subtitleLines: enfantAdminSubtitleLines(
|
||||
@@ -118,7 +118,7 @@ class AdminEnfantUserCard extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AdminUserCard(
|
||||
return UserCard(
|
||||
title: title,
|
||||
fallbackIcon: Icons.child_care_outlined,
|
||||
avatarUrl: photoUrl,
|
||||
+4
-4
@@ -4,9 +4,9 @@ import 'package:p_tits_pas/screens/administrateurs/creation/gestionnaires_create
|
||||
import 'package:p_tits_pas/services/auth_service.dart';
|
||||
import 'package:p_tits_pas/services/user_service.dart';
|
||||
import 'package:p_tits_pas/utils/staff_deletion_rights.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_user_card.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/suppression_confirm_dialog.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/user_list.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/user_card.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/common/suppression_confirm_dialog.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/common/user_list.dart';
|
||||
|
||||
class GestionnaireManagementWidget extends StatefulWidget {
|
||||
final String searchQuery;
|
||||
@@ -141,7 +141,7 @@ class _GestionnaireManagementWidgetState
|
||||
final user = filteredGestionnaires[index];
|
||||
final isSelf =
|
||||
_currentUserId != null && _currentUserId == user.id;
|
||||
return AdminUserCard(
|
||||
return UserCard(
|
||||
title: user.fullName,
|
||||
fallbackIcon: Icons.assignment_ind_outlined,
|
||||
avatarUrl: user.photoUrl,
|
||||
+1
-1
@@ -2,7 +2,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';
|
||||
import 'package:p_tits_pas/widgets/dashboard/relais_management_panel.dart';
|
||||
|
||||
/// Panneau Paramètres admin : Email (SMTP), Personnalisation, Avancé.
|
||||
class ParametresPanel extends StatefulWidget {
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/parent_dossier_wizard.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/parent_dossier_wizard.dart';
|
||||
|
||||
/// Modale de création dossier famille (#129) — même shell que [AmDossierCreateModal].
|
||||
class ParentDossierCreateModal extends StatefulWidget {
|
||||
+6
-6
@@ -14,11 +14,11 @@ import 'package:p_tits_pas/utils/enfant_status_utils.dart';
|
||||
import 'package:p_tits_pas/utils/name_format_utils.dart';
|
||||
import 'package:p_tits_pas/utils/phone_utils.dart';
|
||||
import 'package:p_tits_pas/utils/postal_utils.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_am_photo_frame.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/validation_detail_section.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/validation_modal_theme.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/validation_refus_form.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/validation_valider_confirm_dialog.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/am_photo_frame.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/common/validation_detail_section.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/validation_modal_theme.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/validation_refus_form.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/validation_valider_confirm_dialog.dart';
|
||||
import 'package:p_tits_pas/widgets/common/auth_network_image.dart';
|
||||
import 'package:p_tits_pas/widgets/common/identity_block.dart';
|
||||
|
||||
@@ -860,7 +860,7 @@ class _ParentDossierWizardState extends State<ParentDossierWizard> {
|
||||
child: SizedBox(
|
||||
width: pw,
|
||||
height: ph,
|
||||
child: AdminAmPhotoFrame(
|
||||
child: AmPhotoFrame(
|
||||
photoUrl: child.photoBytes == null
|
||||
? child.existingPhotoUrl
|
||||
: null,
|
||||
+14
-14
@@ -4,30 +4,30 @@ import 'package:p_tits_pas/models/parent_child_summary.dart';
|
||||
import 'package:p_tits_pas/models/parent_model.dart';
|
||||
import 'package:p_tits_pas/models/user.dart';
|
||||
import 'package:p_tits_pas/services/user_service.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_child_detail_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_children_affiliation_panel.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_select_enfant_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_status_capsule.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/child_detail_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/children_affiliation_panel.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/select_enfant_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/status_capsule.dart';
|
||||
import 'package:p_tits_pas/widgets/common/identity_block.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/validation_modal_theme.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/validation_modal_theme.dart';
|
||||
|
||||
/// Fiche parent éditable (doc 28 §6.1, tickets #131 / #138).
|
||||
/// Shell et typo alignés sur [ValidationDossierModal] / wizards validation.
|
||||
class AdminParentEditModal extends StatefulWidget {
|
||||
class ParentEditModal extends StatefulWidget {
|
||||
final ParentModel parent;
|
||||
final VoidCallback? onSaved;
|
||||
|
||||
const AdminParentEditModal({
|
||||
const ParentEditModal({
|
||||
super.key,
|
||||
required this.parent,
|
||||
this.onSaved,
|
||||
});
|
||||
|
||||
@override
|
||||
State<AdminParentEditModal> createState() => _AdminParentEditModalState();
|
||||
State<ParentEditModal> createState() => _ParentEditModalState();
|
||||
}
|
||||
|
||||
class _AdminParentEditModalState extends State<AdminParentEditModal> {
|
||||
class _ParentEditModalState extends State<ParentEditModal> {
|
||||
late final TextEditingController _nomCtrl;
|
||||
late final TextEditingController _prenomCtrl;
|
||||
late final TextEditingController _emailCtrl;
|
||||
@@ -129,7 +129,7 @@ class _AdminParentEditModalState extends State<AdminParentEditModal> {
|
||||
if (!mounted) return;
|
||||
await showDialog<void>(
|
||||
context: context,
|
||||
builder: (ctx) => AdminParentEditModal(
|
||||
builder: (ctx) => ParentEditModal(
|
||||
parent: parent,
|
||||
onSaved: () async {
|
||||
try {
|
||||
@@ -244,7 +244,7 @@ class _AdminParentEditModalState extends State<AdminParentEditModal> {
|
||||
if (!mounted) return;
|
||||
await showDialog<void>(
|
||||
context: context,
|
||||
builder: (ctx) => AdminChildDetailModal(
|
||||
builder: (ctx) => ChildDetailModal(
|
||||
enfant: enfant,
|
||||
onSaved: _reloadChildren,
|
||||
),
|
||||
@@ -322,7 +322,7 @@ class _AdminParentEditModalState extends State<AdminParentEditModal> {
|
||||
|
||||
Future<void> _attachChild() async {
|
||||
if (!mounted) return;
|
||||
final selected = await AdminSelectEnfantModal.show(
|
||||
final selected = await SelectEnfantModal.show(
|
||||
context,
|
||||
excludeIds: _children.map((c) => c.id).toSet(),
|
||||
title: 'Rattacher un enfant',
|
||||
@@ -350,7 +350,7 @@ class _AdminParentEditModalState extends State<AdminParentEditModal> {
|
||||
}
|
||||
|
||||
Widget _childrenPanel() {
|
||||
return AdminChildrenAffiliationPanel(
|
||||
return ChildrenAffiliationPanel(
|
||||
children: _children,
|
||||
scrollController: _childrenScrollCtrl,
|
||||
onOpen: _openChild,
|
||||
@@ -437,7 +437,7 @@ class _AdminParentEditModalState extends State<AdminParentEditModal> {
|
||||
const SizedBox(width: 12),
|
||||
SizedBox(
|
||||
width: 160,
|
||||
child: AdminStatusCapsule(
|
||||
child: StatusCapsule(
|
||||
statut: _statut,
|
||||
onChanged: (v) => setState(() {
|
||||
_statut = v;
|
||||
+6
-6
@@ -4,10 +4,10 @@ import 'package:p_tits_pas/models/parent_model.dart';
|
||||
import 'package:p_tits_pas/services/auth_service.dart';
|
||||
import 'package:p_tits_pas/services/user_service.dart';
|
||||
import 'package:p_tits_pas/utils/staff_deletion_rights.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_parent_edit_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_user_card.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/suppression_confirm_dialog.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/user_list.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/parent_edit_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/user_card.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/common/suppression_confirm_dialog.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/common/user_list.dart';
|
||||
|
||||
class ParentManagementWidget extends StatefulWidget {
|
||||
final String searchQuery;
|
||||
@@ -146,7 +146,7 @@ class _ParentManagementWidgetState extends State<ParentManagementWidget> {
|
||||
itemCount: filteredParents.length,
|
||||
itemBuilder: (context, index) {
|
||||
final parent = filteredParents[index];
|
||||
return AdminUserCard(
|
||||
return UserCard(
|
||||
title: parent.user.fullName,
|
||||
fallbackIcon: Icons.supervisor_account_outlined,
|
||||
avatarUrl: parent.user.photoUrl,
|
||||
@@ -189,7 +189,7 @@ class _ParentManagementWidgetState extends State<ParentManagementWidget> {
|
||||
void _openParentDetails(ParentModel parent) {
|
||||
showDialog<void>(
|
||||
context: context,
|
||||
builder: (context) => AdminParentEditModal(
|
||||
builder: (context) => ParentEditModal(
|
||||
parent: parent,
|
||||
onSaved: _loadParents,
|
||||
),
|
||||
+3
-3
@@ -3,9 +3,9 @@ import 'package:p_tits_pas/models/dossier_list_item.dart';
|
||||
import 'package:p_tits_pas/models/user.dart';
|
||||
import 'package:p_tits_pas/models/pending_family.dart';
|
||||
import 'package:p_tits_pas/services/user_service.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/dossier_list_card.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/suppression_confirm_dialog.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/validation_dossier_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/dossier_list_card.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/common/suppression_confirm_dialog.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/validation_dossier_modal.dart';
|
||||
|
||||
/// Section « dossiers à valider » (liste unifiée AM + familles). Ticket #107 / #153.
|
||||
class PendingValidationWidget extends StatefulWidget {
|
||||
+1
-1
@@ -3,7 +3,7 @@ import 'package:flutter/services.dart';
|
||||
import 'package:p_tits_pas/models/relais_model.dart';
|
||||
import 'package:p_tits_pas/utils/phone_utils.dart';
|
||||
import 'package:p_tits_pas/services/relais_service.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/suppression_confirm_dialog.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/common/suppression_confirm_dialog.dart';
|
||||
|
||||
class RelaisManagementPanel extends StatefulWidget {
|
||||
const RelaisManagementPanel({super.key});
|
||||
+11
-11
@@ -3,10 +3,10 @@ import 'package:flutter/material.dart';
|
||||
import 'package:p_tits_pas/models/assistante_maternelle_model.dart';
|
||||
import 'package:p_tits_pas/services/user_service.dart';
|
||||
import 'package:p_tits_pas/utils/am_vigilance.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_am_edit_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_select_list_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_user_card.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/validation_modal_theme.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/am_edit_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/select_list_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/user_card.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/validation_modal_theme.dart';
|
||||
|
||||
List<String> _amSelectSubtitleLines(AssistanteMaternelleModel am) {
|
||||
final lines = <String>[];
|
||||
@@ -28,22 +28,22 @@ List<String> _amSelectSubtitleLines(AssistanteMaternelleModel am) {
|
||||
}
|
||||
|
||||
/// Sélection d'une AM à rattacher (fiche enfant) — ticket #147.
|
||||
/// S'appuie sur [AdminSelectListModal] (shell partagé avec #146).
|
||||
class AdminSelectAmModal {
|
||||
AdminSelectAmModal._();
|
||||
/// S'appuie sur [SelectListModal] (shell partagé avec #146).
|
||||
class SelectAmModal {
|
||||
SelectAmModal._();
|
||||
|
||||
static Future<AssistanteMaternelleModel?> show(
|
||||
BuildContext context, {
|
||||
Set<String> excludeIds = const {},
|
||||
String title = 'Choisir une assistante maternelle',
|
||||
}) {
|
||||
return AdminSelectListModal.show<AssistanteMaternelleModel>(
|
||||
return SelectListModal.show<AssistanteMaternelleModel>(
|
||||
context,
|
||||
title: title,
|
||||
searchHint: 'Rechercher par nom, prénom ou zone…',
|
||||
emptyMessage: 'Aucune assistante maternelle disponible',
|
||||
noResultsMessage: 'Aucune AM avec place libre pour cette recherche',
|
||||
toggleFilter: const AdminSelectToggleFilter<AssistanteMaternelleModel>(
|
||||
toggleFilter: const SelectToggleFilter<AssistanteMaternelleModel>(
|
||||
label: 'Libre',
|
||||
initialValue: true,
|
||||
whenEnabled: amHasFreePlace,
|
||||
@@ -76,7 +76,7 @@ class AdminSelectAmModal {
|
||||
_resolveAmSelection(ctx, am, reload),
|
||||
itemBuilder: (context, am, onSelect) {
|
||||
final full = !amHasFreePlace(am);
|
||||
return AdminUserCard(
|
||||
return UserCard(
|
||||
title: am.user.fullName,
|
||||
avatarUrl: am.user.photoUrl,
|
||||
fallbackIcon: Icons.face,
|
||||
@@ -150,7 +150,7 @@ class _AmNoPlaceWarningDialogState extends State<_AmNoPlaceWarningDialog> {
|
||||
if (!mounted) return;
|
||||
await showDialog<void>(
|
||||
context: context,
|
||||
builder: (ctx) => AdminAmEditModal(
|
||||
builder: (ctx) => AmEditModal(
|
||||
assistante: _am,
|
||||
onSaved: () async {
|
||||
try {
|
||||
+8
-8
@@ -2,13 +2,13 @@ import 'package:flutter/material.dart';
|
||||
import 'package:p_tits_pas/models/enfant_admin_model.dart';
|
||||
import 'package:p_tits_pas/services/user_service.dart';
|
||||
import 'package:p_tits_pas/utils/enfant_status_utils.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_enfant_user_card.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_select_list_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/enfant_user_card.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/select_list_modal.dart';
|
||||
|
||||
/// Sélection d'un enfant à rattacher (fiche AM / fiche parent) — ticket #146.
|
||||
/// S'appuie sur [AdminSelectListModal] (shell partagé avec #147).
|
||||
class AdminSelectEnfantModal {
|
||||
AdminSelectEnfantModal._();
|
||||
/// S'appuie sur [SelectListModal] (shell partagé avec #147).
|
||||
class SelectEnfantModal {
|
||||
SelectEnfantModal._();
|
||||
|
||||
static Future<EnfantAdminModel?> show(
|
||||
BuildContext context, {
|
||||
@@ -17,7 +17,7 @@ class AdminSelectEnfantModal {
|
||||
/// Affiché uniquement depuis la fiche AM : filtre les enfants déjà en garde.
|
||||
bool showSansGardeFilter = false,
|
||||
}) {
|
||||
return AdminSelectListModal.show<EnfantAdminModel>(
|
||||
return SelectListModal.show<EnfantAdminModel>(
|
||||
context,
|
||||
title: title,
|
||||
searchHint: 'Rechercher par nom ou prénom…',
|
||||
@@ -26,7 +26,7 @@ class AdminSelectEnfantModal {
|
||||
? 'Aucun enfant sans garde pour cette recherche'
|
||||
: 'Aucun résultat pour cette recherche',
|
||||
toggleFilter: showSansGardeFilter
|
||||
? AdminSelectToggleFilter<EnfantAdminModel>(
|
||||
? SelectToggleFilter<EnfantAdminModel>(
|
||||
label: 'Sans garde',
|
||||
initialValue: true,
|
||||
whenEnabled: (e) =>
|
||||
@@ -50,7 +50,7 @@ class AdminSelectEnfantModal {
|
||||
return name.contains(q) || fn.contains(q) || ln.contains(q);
|
||||
},
|
||||
itemBuilder: (context, e, onSelect) {
|
||||
return AdminEnfantUserCard.fromEnfant(
|
||||
return EnfantUserCard.fromEnfant(
|
||||
e,
|
||||
onCardTap: onSelect,
|
||||
margin: const EdgeInsets.only(bottom: 4),
|
||||
+12
-12
@@ -1,11 +1,11 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:p_tits_pas/models/parent_model.dart';
|
||||
import 'package:p_tits_pas/services/user_service.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_select_list_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_user_card.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/select_list_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/user_card.dart';
|
||||
|
||||
/// Foyer / famille sélectionnable pour rattacher un nouvel enfant (#132 / #157).
|
||||
class AdminFamilleFoyer {
|
||||
class FamilleFoyer {
|
||||
/// Parent pivot pour `POST /enfants` (`parent_user_id`).
|
||||
final String pivotParentUserId;
|
||||
/// Co-parent éventuel (rattachement foyer #157).
|
||||
@@ -14,7 +14,7 @@ class AdminFamilleFoyer {
|
||||
final String displayTitle;
|
||||
final List<String> parentNames;
|
||||
|
||||
const AdminFamilleFoyer({
|
||||
const FamilleFoyer({
|
||||
required this.pivotParentUserId,
|
||||
required this.displayTitle,
|
||||
required this.parentNames,
|
||||
@@ -42,10 +42,10 @@ class AdminFamilleFoyer {
|
||||
}
|
||||
|
||||
/// Construit la liste des foyers uniques à partir de `GET /parents`.
|
||||
List<AdminFamilleFoyer> buildFamilleFoyers(List<ParentModel> parents) {
|
||||
List<FamilleFoyer> buildFamilleFoyers(List<ParentModel> parents) {
|
||||
final seenDossiers = <String>{};
|
||||
final seenUserIds = <String>{};
|
||||
final foyers = <AdminFamilleFoyer>[];
|
||||
final foyers = <FamilleFoyer>[];
|
||||
|
||||
for (final p in parents) {
|
||||
final dossier = (p.user.numeroDossier ?? '').trim();
|
||||
@@ -70,7 +70,7 @@ List<AdminFamilleFoyer> buildFamilleFoyers(List<ParentModel> parents) {
|
||||
: (names.isNotEmpty ? names.first : 'Famille');
|
||||
|
||||
foyers.add(
|
||||
AdminFamilleFoyer(
|
||||
FamilleFoyer(
|
||||
pivotParentUserId: p.user.id,
|
||||
coParentUserId: co?.id,
|
||||
numeroDossier: dossier.isNotEmpty ? dossier : null,
|
||||
@@ -87,14 +87,14 @@ List<AdminFamilleFoyer> buildFamilleFoyers(List<ParentModel> parents) {
|
||||
}
|
||||
|
||||
/// Sélection d'une famille / dossier pour créer un enfant — ticket #132.
|
||||
class AdminSelectFamilleModal {
|
||||
AdminSelectFamilleModal._();
|
||||
class SelectFamilleModal {
|
||||
SelectFamilleModal._();
|
||||
|
||||
static Future<AdminFamilleFoyer?> show(
|
||||
static Future<FamilleFoyer?> show(
|
||||
BuildContext context, {
|
||||
String title = 'Choisir une famille',
|
||||
}) {
|
||||
return AdminSelectListModal.show<AdminFamilleFoyer>(
|
||||
return SelectListModal.show<FamilleFoyer>(
|
||||
context,
|
||||
title: title,
|
||||
searchHint: 'Rechercher par dossier, nom…',
|
||||
@@ -111,7 +111,7 @@ class AdminSelectFamilleModal {
|
||||
return dossier.contains(q) || title.contains(q) || names.contains(q);
|
||||
},
|
||||
itemBuilder: (context, f, onSelect) {
|
||||
return AdminUserCard(
|
||||
return UserCard(
|
||||
title: f.displayTitle,
|
||||
fallbackIcon: Icons.family_restroom,
|
||||
subtitleLines: [
|
||||
+11
-11
@@ -1,8 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/validation_modal_theme.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/validation_modal_theme.dart';
|
||||
|
||||
/// Filtre optionnel (switch) sur la même ligne que la barre de recherche.
|
||||
class AdminSelectToggleFilter<T> {
|
||||
class SelectToggleFilter<T> {
|
||||
final String label;
|
||||
final bool initialValue;
|
||||
|
||||
@@ -10,7 +10,7 @@ class AdminSelectToggleFilter<T> {
|
||||
/// [whenEnabled] renvoie `true`.
|
||||
final bool Function(T item) whenEnabled;
|
||||
|
||||
const AdminSelectToggleFilter({
|
||||
const SelectToggleFilter({
|
||||
required this.label,
|
||||
required this.whenEnabled,
|
||||
this.initialValue = true,
|
||||
@@ -19,7 +19,7 @@ class AdminSelectToggleFilter<T> {
|
||||
|
||||
/// Shell générique « rechercher + liste + sélection » pour les modales admin.
|
||||
/// Utilisé par la sélection d'enfant (#146) et la sélection d'AM (#147).
|
||||
class AdminSelectListModal<T> extends StatefulWidget {
|
||||
class SelectListModal<T> extends StatefulWidget {
|
||||
final String title;
|
||||
final String searchHint;
|
||||
final Future<List<T>> Function() loadItems;
|
||||
@@ -40,7 +40,7 @@ class AdminSelectListModal<T> extends StatefulWidget {
|
||||
final int minVisibleCards;
|
||||
|
||||
/// Switch optionnel à droite du champ de recherche (ex. « Sans garde », « Libre »).
|
||||
final AdminSelectToggleFilter<T>? toggleFilter;
|
||||
final SelectToggleFilter<T>? toggleFilter;
|
||||
|
||||
/// Si fourni, appelé avant de valider la sélection.
|
||||
/// Retourne l'élément à pop (éventuellement rafraîchi), ou `null` pour annuler.
|
||||
@@ -50,7 +50,7 @@ class AdminSelectListModal<T> extends StatefulWidget {
|
||||
Future<void> Function() reload,
|
||||
)? resolveSelect;
|
||||
|
||||
const AdminSelectListModal({
|
||||
const SelectListModal({
|
||||
super.key,
|
||||
required this.title,
|
||||
required this.loadItems,
|
||||
@@ -82,7 +82,7 @@ class AdminSelectListModal<T> extends StatefulWidget {
|
||||
double modalWidth = 930,
|
||||
double cardExtent = 52,
|
||||
int minVisibleCards = 8,
|
||||
AdminSelectToggleFilter<T>? toggleFilter,
|
||||
SelectToggleFilter<T>? toggleFilter,
|
||||
Future<T?> Function(
|
||||
BuildContext context,
|
||||
T item,
|
||||
@@ -91,7 +91,7 @@ class AdminSelectListModal<T> extends StatefulWidget {
|
||||
}) {
|
||||
return showDialog<T>(
|
||||
context: context,
|
||||
builder: (ctx) => AdminSelectListModal<T>(
|
||||
builder: (ctx) => SelectListModal<T>(
|
||||
title: title,
|
||||
loadItems: loadItems,
|
||||
matchesQuery: matchesQuery,
|
||||
@@ -109,11 +109,11 @@ class AdminSelectListModal<T> extends StatefulWidget {
|
||||
}
|
||||
|
||||
@override
|
||||
State<AdminSelectListModal<T>> createState() =>
|
||||
_AdminSelectListModalState<T>();
|
||||
State<SelectListModal<T>> createState() =>
|
||||
_SelectListModalState<T>();
|
||||
}
|
||||
|
||||
class _AdminSelectListModalState<T> extends State<AdminSelectListModal<T>> {
|
||||
class _SelectListModalState<T> extends State<SelectListModal<T>> {
|
||||
final _searchCtrl = TextEditingController();
|
||||
List<T> _all = [];
|
||||
bool _loading = true;
|
||||
+2
-2
@@ -1,13 +1,13 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// Gélule de sélection du statut utilisateur (fiches admin parent / AM).
|
||||
class AdminStatusCapsule extends StatelessWidget {
|
||||
class StatusCapsule extends StatelessWidget {
|
||||
final String statut;
|
||||
final ValueChanged<String>? onChanged;
|
||||
|
||||
static const statuts = ['actif', 'en_attente', 'suspendu', 'refuse'];
|
||||
|
||||
const AdminStatusCapsule({
|
||||
const StatusCapsule({
|
||||
super.key,
|
||||
required this.statut,
|
||||
this.onChanged,
|
||||
+4
-4
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:p_tits_pas/services/api/api_config.dart';
|
||||
import 'package:p_tits_pas/widgets/common/auth_network_image.dart';
|
||||
|
||||
class AdminUserCard extends StatefulWidget {
|
||||
class UserCard extends StatefulWidget {
|
||||
final String title;
|
||||
final List<String> subtitleLines;
|
||||
final String? avatarUrl;
|
||||
@@ -21,7 +21,7 @@ class AdminUserCard extends StatefulWidget {
|
||||
final EdgeInsetsGeometry? margin;
|
||||
final EdgeInsetsGeometry? contentPadding;
|
||||
|
||||
const AdminUserCard({
|
||||
const UserCard({
|
||||
super.key,
|
||||
required this.title,
|
||||
required this.subtitleLines,
|
||||
@@ -41,10 +41,10 @@ class AdminUserCard extends StatefulWidget {
|
||||
});
|
||||
|
||||
@override
|
||||
State<AdminUserCard> createState() => _AdminUserCardState();
|
||||
State<UserCard> createState() => _UserCardState();
|
||||
}
|
||||
|
||||
class _AdminUserCardState extends State<AdminUserCard> {
|
||||
class _UserCardState extends State<UserCard> {
|
||||
bool _isHovered = false;
|
||||
|
||||
@override
|
||||
+2
-2
@@ -1,13 +1,13 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class AdminListState extends StatelessWidget {
|
||||
class UserListState extends StatelessWidget {
|
||||
final bool isLoading;
|
||||
final String? error;
|
||||
final bool isEmpty;
|
||||
final String emptyMessage;
|
||||
final Widget list;
|
||||
|
||||
const AdminListState({
|
||||
const UserListState({
|
||||
super.key,
|
||||
required this.isLoading,
|
||||
required this.error,
|
||||
+10
-10
@@ -1,15 +1,15 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:p_tits_pas/screens/administrateurs/creation/gestionnaires_create.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/admin_management_widget.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/am_dossier_create_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/assistante_maternelle_management_widget.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_child_detail_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/dashboard_admin.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/dossiers_management_widget.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/enfant_management_widget.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/gestionnaire_management_widget.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/parent_dossier_create_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/parent_managmant_widget.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/am_dossier_create_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/assistante_maternelle_management_widget.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/child_detail_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/user_management_sub_bar.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/dossiers_management_widget.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/enfant_management_widget.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/gestionnaire_management_widget.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/parent_dossier_create_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/parent_managmant_widget.dart';
|
||||
|
||||
class UserManagementPanel extends StatefulWidget {
|
||||
/// Afficher l'onglet Administrateurs (sinon sans Administrateurs).
|
||||
@@ -348,7 +348,7 @@ class _UserManagementPanelState extends State<UserManagementPanel> {
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (dialogContext) {
|
||||
return AdminChildDetailModal.create(
|
||||
return ChildDetailModal.create(
|
||||
onSaved: () {
|
||||
if (!mounted) return;
|
||||
setState(() => _enfantRefreshTick++);
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:p_tits_pas/models/dossier_unifie.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/am_dossier_wizard.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/am_dossier_wizard.dart';
|
||||
|
||||
/// Wrapper historique (#107) — délègue à [AmDossierWizard.review].
|
||||
class ValidationAmWizard extends StatelessWidget {
|
||||
+4
-4
@@ -1,10 +1,10 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:p_tits_pas/models/dossier_unifie.dart';
|
||||
import 'package:p_tits_pas/services/user_service.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/am_dossier_wizard.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/parent_dossier_wizard.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/validation_am_wizard.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/validation_family_wizard.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/am_dossier_wizard.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/parent_dossier_wizard.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/validation_am_wizard.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/validation_family_wizard.dart';
|
||||
|
||||
/// Modale (dialog) : charge le dossier par numéro puis affiche le wizard AM ou Famille.
|
||||
/// Ticket #107 / #119 (review), #135 (`openAsEdit`).
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:p_tits_pas/models/dossier_unifie.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/parent_dossier_wizard.dart';
|
||||
import 'package:p_tits_pas/widgets/dashboard/parent_dossier_wizard.dart';
|
||||
|
||||
/// Wrapper historique (#107) — délègue à [ParentDossierWizard.review].
|
||||
class ValidationFamilyWizard extends StatelessWidget {
|
||||
Reference in New Issue
Block a user