From a312d9c0fa32a7ad3d518f1cc528a860c6377871 Mon Sep 17 00:00:00 2001 From: Julien Martin Date: Thu, 10 Sep 2026 23:13:53 +0200 Subject: [PATCH] =?UTF-8?q?refactor(#155):=20option=20C=20=E2=80=94=20widg?= =?UTF-8?q?ets=20partag=C3=A9s=20sans=20pr=C3=A9fixe=20Admin.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Déplace les composants Admin* du dashboard partagé vers widgets/dashboard/ (ChildDetailModal, AmEditModal, UserCard, Select*, …). Conserve AdminManagementWidget et screens/administrateurs. Rename mécanique, aucun changement de comportement. Co-authored-by: Cursor --- docs/tmp/155-mini-spec-rename-admin-prefix.md | 52 +++++++++++++++++++ .../admin_dashboardScreen.dart | 2 +- .../admin/admin_management_widget.dart | 4 +- .../lib/widgets/admin/am_dossier_wizard.dart | 28 +++++----- ...sistante_maternelle_management_widget.dart | 8 +-- .../lib/widgets/admin/common/user_list.dart | 4 +- .../common/validation_detail_section.dart | 4 +- .../lib/widgets/admin/dossier_list_card.dart | 4 +- .../admin/enfant_management_widget.dart | 8 +-- .../admin/gestionnaire_management_widget.dart | 4 +- .../widgets/admin/parent_dossier_wizard.dart | 4 +- .../admin/parent_managmant_widget.dart | 8 +-- .../widgets/admin/user_management_panel.dart | 6 +-- .../am_children_capacity_grid.dart} | 4 +- .../am_edit_modal.dart} | 30 +++++------ .../am_photo_frame.dart} | 4 +- .../child_detail_modal.dart} | 34 ++++++------ .../children_affiliation_panel.dart} | 8 +-- .../detail_modal.dart} | 10 ++-- .../enfant_user_card.dart} | 16 +++--- .../parent_edit_modal.dart} | 26 +++++----- .../select_am_modal.dart} | 20 +++---- .../select_enfant_modal.dart} | 16 +++--- .../select_famille_modal.dart} | 24 ++++----- .../select_list_modal.dart} | 20 +++---- .../status_capsule.dart} | 4 +- .../user_card.dart} | 8 +-- .../user_list_state.dart} | 4 +- .../user_management_sub_bar.dart} | 0 29 files changed, 208 insertions(+), 156 deletions(-) create mode 100644 docs/tmp/155-mini-spec-rename-admin-prefix.md rename frontend/lib/widgets/{admin/common/admin_am_children_capacity_grid.dart => dashboard/am_children_capacity_grid.dart} (99%) rename frontend/lib/widgets/{admin/common/admin_am_edit_modal.dart => dashboard/am_edit_modal.dart} (96%) rename frontend/lib/widgets/{admin/common/admin_am_photo_frame.dart => dashboard/am_photo_frame.dart} (98%) rename frontend/lib/widgets/{admin/common/admin_child_detail_modal.dart => dashboard/child_detail_modal.dart} (98%) rename frontend/lib/widgets/{admin/common/admin_children_affiliation_panel.dart => dashboard/children_affiliation_panel.dart} (91%) rename frontend/lib/widgets/{admin/common/admin_detail_modal.dart => dashboard/detail_modal.dart} (96%) rename frontend/lib/widgets/{admin/common/admin_enfant_user_card.dart => dashboard/enfant_user_card.dart} (91%) rename frontend/lib/widgets/{admin/common/admin_parent_edit_modal.dart => dashboard/parent_edit_modal.dart} (94%) rename frontend/lib/widgets/{admin/common/admin_select_am_modal.dart => dashboard/select_am_modal.dart} (92%) rename frontend/lib/widgets/{admin/common/admin_select_enfant_modal.dart => dashboard/select_enfant_modal.dart} (83%) rename frontend/lib/widgets/{admin/common/admin_select_famille_modal.dart => dashboard/select_famille_modal.dart} (88%) rename frontend/lib/widgets/{admin/common/admin_select_list_modal.dart => dashboard/select_list_modal.dart} (95%) rename frontend/lib/widgets/{admin/common/admin_status_capsule.dart => dashboard/status_capsule.dart} (95%) rename frontend/lib/widgets/{admin/common/admin_user_card.dart => dashboard/user_card.dart} (97%) rename frontend/lib/widgets/{admin/common/admin_list_state.dart => dashboard/user_list_state.dart} (92%) rename frontend/lib/widgets/{admin/dashboard_admin.dart => dashboard/user_management_sub_bar.dart} (100%) diff --git a/docs/tmp/155-mini-spec-rename-admin-prefix.md b/docs/tmp/155-mini-spec-rename-admin-prefix.md new file mode 100644 index 0000000..dc8344b --- /dev/null +++ b/docs/tmp/155-mini-spec-rename-admin-prefix.md @@ -0,0 +1,52 @@ +# 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 les panels métier (`user_management_panel`, wizards, etc.) + `AdminManagementWidget`. + +## 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) diff --git a/frontend/lib/screens/administrateurs/admin_dashboardScreen.dart b/frontend/lib/screens/administrateurs/admin_dashboardScreen.dart index 20a9678..43c6f97 100644 --- a/frontend/lib/screens/administrateurs/admin_dashboardScreen.dart +++ b/frontend/lib/screens/administrateurs/admin_dashboardScreen.dart @@ -2,7 +2,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/services/configuration_service.dart'; -import 'package:p_tits_pas/widgets/admin/dashboard_admin.dart'; +import 'package:p_tits_pas/widgets/dashboard/user_management_sub_bar.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/app_footer.dart'; diff --git a/frontend/lib/widgets/admin/admin_management_widget.dart b/frontend/lib/widgets/admin/admin_management_widget.dart index 08d40a3..3538efc 100644 --- a/frontend/lib/widgets/admin/admin_management_widget.dart +++ b/frontend/lib/widgets/admin/admin_management_widget.dart @@ -5,7 +5,7 @@ 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/dashboard/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'; @@ -183,7 +183,7 @@ class _AdminManagementWidgetState extends State { 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 diff --git a/frontend/lib/widgets/admin/am_dossier_wizard.dart b/frontend/lib/widgets/admin/am_dossier_wizard.dart index dd6b0cb..e8f8b19 100644 --- a/frontend/lib/widgets/admin/am_dossier_wizard.dart +++ b/frontend/lib/widgets/admin/am_dossier_wizard.dart @@ -14,8 +14,8 @@ 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/dashboard/am_photo_frame.dart'; +import 'package:p_tits_pas/widgets/dashboard/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'; @@ -221,32 +221,32 @@ class _AmDossierWizardState extends State { void _emitStep() => widget.onStepChanged?.call(_step, _stepCount); - List _photoProFields(DossierAM d) { + List _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 { 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 { final Widget photo; if (_isCreate) { - photo = AdminAmPhotoFrame( + photo = AmPhotoFrame( imageBytes: _photoBytes, onTap: _pickPhoto, onClear: _photoBytes != null ? _clearPhoto : null, diff --git a/frontend/lib/widgets/admin/assistante_maternelle_management_widget.dart b/frontend/lib/widgets/admin/assistante_maternelle_management_widget.dart index b48212b..8da3c30 100644 --- a/frontend/lib/widgets/admin/assistante_maternelle_management_widget.dart +++ b/frontend/lib/widgets/admin/assistante_maternelle_management_widget.dart @@ -5,8 +5,8 @@ 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/dashboard/am_edit_modal.dart'; +import 'package:p_tits_pas/widgets/dashboard/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'; @@ -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( context: context, - builder: (context) => AdminAmEditModal( + builder: (context) => AmEditModal( assistante: assistante, onSaved: _loadAssistantes, ), diff --git a/frontend/lib/widgets/admin/common/user_list.dart b/frontend/lib/widgets/admin/common/user_list.dart index 1df400c..3b439d5 100644 --- a/frontend/lib/widgets/admin/common/user_list.dart +++ b/frontend/lib/widgets/admin/common/user_list.dart @@ -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, diff --git a/frontend/lib/widgets/admin/common/validation_detail_section.dart b/frontend/lib/widgets/admin/common/validation_detail_section.dart index 80f5a42..5683859 100644 --- a/frontend/lib/widgets/admin/common/validation_detail_section.dart +++ b/frontend/lib/widgets/admin/common/validation_detail_section.dart @@ -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 fields; + final List fields; /// Nombre de champs par ligne (1 = plein largeur, 2 = deux côte à côte). Ex. [2, 2, 1, 2] pour identité. final List? rowLayout; diff --git a/frontend/lib/widgets/admin/dossier_list_card.dart b/frontend/lib/widgets/admin/dossier_list_card.dart index 7608df2..ad66e88 100644 --- a/frontend/lib/widgets/admin/dossier_list_card.dart +++ b/frontend/lib/widgets/admin/dossier_list_card.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:p_tits_pas/widgets/admin/common/admin_user_card.dart'; +import 'package:p_tits_pas/widgets/dashboard/user_card.dart'; import 'package:p_tits_pas/widgets/admin/common/suppression_confirm_dialog.dart'; /// Carte dossier unifiée (#153) — fond neutre, accent couleur sur l’icône. @@ -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, diff --git a/frontend/lib/widgets/admin/enfant_management_widget.dart b/frontend/lib/widgets/admin/enfant_management_widget.dart index 6731ff7..61f2ce9 100644 --- a/frontend/lib/widgets/admin/enfant_management_widget.dart +++ b/frontend/lib/widgets/admin/enfant_management_widget.dart @@ -5,8 +5,8 @@ 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/dashboard/child_detail_modal.dart'; +import 'package:p_tits_pas/widgets/dashboard/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'; @@ -68,7 +68,7 @@ class _EnfantManagementWidgetState extends State { Future _openEnfant(EnfantAdminModel enfant) async { await showDialog( context: context, - builder: (ctx) => AdminChildDetailModal( + builder: (ctx) => ChildDetailModal( enfant: enfant, onSaved: _loadEnfants, onDeleted: _loadEnfants, @@ -224,7 +224,7 @@ class _EnfantManagementWidgetState extends State { itemCount: filtered.length, itemBuilder: (context, index) { final enfant = filtered[index]; - return AdminEnfantUserCard.fromEnfant( + return EnfantUserCard.fromEnfant( enfant, onCardTap: () => _openEnfant(enfant), actions: [ diff --git a/frontend/lib/widgets/admin/gestionnaire_management_widget.dart b/frontend/lib/widgets/admin/gestionnaire_management_widget.dart index f5cda69..468f43f 100644 --- a/frontend/lib/widgets/admin/gestionnaire_management_widget.dart +++ b/frontend/lib/widgets/admin/gestionnaire_management_widget.dart @@ -4,7 +4,7 @@ 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/dashboard/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'; @@ -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, diff --git a/frontend/lib/widgets/admin/parent_dossier_wizard.dart b/frontend/lib/widgets/admin/parent_dossier_wizard.dart index 7ff061a..e50ca2a 100644 --- a/frontend/lib/widgets/admin/parent_dossier_wizard.dart +++ b/frontend/lib/widgets/admin/parent_dossier_wizard.dart @@ -14,7 +14,7 @@ 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/dashboard/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'; @@ -860,7 +860,7 @@ class _ParentDossierWizardState extends State { child: SizedBox( width: pw, height: ph, - child: AdminAmPhotoFrame( + child: AmPhotoFrame( photoUrl: child.photoBytes == null ? child.existingPhotoUrl : null, diff --git a/frontend/lib/widgets/admin/parent_managmant_widget.dart b/frontend/lib/widgets/admin/parent_managmant_widget.dart index 69b2683..96d912a 100644 --- a/frontend/lib/widgets/admin/parent_managmant_widget.dart +++ b/frontend/lib/widgets/admin/parent_managmant_widget.dart @@ -4,8 +4,8 @@ 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/dashboard/parent_edit_modal.dart'; +import 'package:p_tits_pas/widgets/dashboard/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'; @@ -146,7 +146,7 @@ class _ParentManagementWidgetState extends State { 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 { void _openParentDetails(ParentModel parent) { showDialog( context: context, - builder: (context) => AdminParentEditModal( + builder: (context) => ParentEditModal( parent: parent, onSaved: _loadParents, ), diff --git a/frontend/lib/widgets/admin/user_management_panel.dart b/frontend/lib/widgets/admin/user_management_panel.dart index fb22c19..270cee3 100644 --- a/frontend/lib/widgets/admin/user_management_panel.dart +++ b/frontend/lib/widgets/admin/user_management_panel.dart @@ -3,8 +3,8 @@ import 'package:p_tits_pas/screens/administrateurs/creation/gestionnaires_create 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/dashboard/child_detail_modal.dart'; +import 'package:p_tits_pas/widgets/dashboard/user_management_sub_bar.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'; @@ -348,7 +348,7 @@ class _UserManagementPanelState extends State { context: context, barrierDismissible: false, builder: (dialogContext) { - return AdminChildDetailModal.create( + return ChildDetailModal.create( onSaved: () { if (!mounted) return; setState(() => _enfantRefreshTick++); diff --git a/frontend/lib/widgets/admin/common/admin_am_children_capacity_grid.dart b/frontend/lib/widgets/dashboard/am_children_capacity_grid.dart similarity index 99% rename from frontend/lib/widgets/admin/common/admin_am_children_capacity_grid.dart rename to frontend/lib/widgets/dashboard/am_children_capacity_grid.dart index 5b28e3c..a475c06 100644 --- a/frontend/lib/widgets/admin/common/admin_am_children_capacity_grid.dart +++ b/frontend/lib/widgets/dashboard/am_children_capacity_grid.dart @@ -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, diff --git a/frontend/lib/widgets/admin/common/admin_am_edit_modal.dart b/frontend/lib/widgets/dashboard/am_edit_modal.dart similarity index 96% rename from frontend/lib/widgets/admin/common/admin_am_edit_modal.dart rename to frontend/lib/widgets/dashboard/am_edit_modal.dart index 5855e69..1ee2cf1 100644 --- a/frontend/lib/widgets/admin/common/admin_am_edit_modal.dart +++ b/frontend/lib/widgets/dashboard/am_edit_modal.dart @@ -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/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/admin/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'; /// 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 createState() => _AdminAmEditModalState(); + State createState() => _AmEditModalState(); } -class _AdminAmEditModalState extends State +class _AmEditModalState extends State with SingleTickerProviderStateMixin { late final TabController _tabCtrl; late final TextEditingController _nomCtrl; @@ -404,7 +404,7 @@ class _AdminAmEditModalState extends State if (!mounted) return; await showDialog( context: context, - builder: (ctx) => AdminChildDetailModal( + builder: (ctx) => ChildDetailModal( enfant: enfant, onSaved: _refreshChildrenDetails, ), @@ -450,7 +450,7 @@ class _AdminAmEditModalState extends State Future _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 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 children: [ SizedBox( width: photoW, - child: AdminAmPhotoFrame( + child: AmPhotoFrame( photoUrl: widget.assistante.user.photoUrl, ), ), @@ -728,7 +728,7 @@ class _AdminAmEditModalState extends State ), ), const SizedBox(height: 8), - AdminAmChildrenCapacityGrid( + AmChildrenCapacityGrid( children: _children, capacity: capacity, onOpen: _openChild, @@ -820,7 +820,7 @@ class _AdminAmEditModalState extends State const SizedBox(width: 12), SizedBox( width: 160, - child: AdminStatusCapsule( + child: StatusCapsule( statut: _statut, onChanged: (v) => setState(() { _statut = v; diff --git a/frontend/lib/widgets/admin/common/admin_am_photo_frame.dart b/frontend/lib/widgets/dashboard/am_photo_frame.dart similarity index 98% rename from frontend/lib/widgets/admin/common/admin_am_photo_frame.dart rename to frontend/lib/widgets/dashboard/am_photo_frame.dart index 3da8051..dd990fd 100644 --- a/frontend/lib/widgets/admin/common/admin_am_photo_frame.dart +++ b/frontend/lib/widgets/dashboard/am_photo_frame.dart @@ -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, diff --git a/frontend/lib/widgets/admin/common/admin_child_detail_modal.dart b/frontend/lib/widgets/dashboard/child_detail_modal.dart similarity index 98% rename from frontend/lib/widgets/admin/common/admin_child_detail_modal.dart rename to frontend/lib/widgets/dashboard/child_detail_modal.dart index 30aec24..3701b27 100644 --- a/frontend/lib/widgets/admin/common/admin_child_detail_modal.dart +++ b/frontend/lib/widgets/dashboard/child_detail_modal.dart @@ -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/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/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/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 createState() => _AdminChildDetailModalState(); + State createState() => _ChildDetailModalState(); } -class _AdminChildDetailModalState extends State { +class _ChildDetailModalState extends State { late final TextEditingController _prenomCtrl; late final TextEditingController _nomCtrl; late final TextEditingController _birthCtrl; @@ -65,7 +65,7 @@ class _AdminChildDetailModalState extends State { 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? _localParentLinks; @@ -283,7 +283,7 @@ class _AdminChildDetailModalState extends State { if (!mounted) return; await showDialog( context: context, - builder: (ctx) => AdminParentEditModal( + builder: (ctx) => ParentEditModal( parent: parent, onSaved: () => widget.onSaved?.call(), ), @@ -624,7 +624,7 @@ class _AdminChildDetailModalState extends State { if (am == null) return; await showDialog( context: context, - builder: (ctx) => AdminAmEditModal( + builder: (ctx) => AmEditModal( assistante: am, onSaved: () async { await _reloadPlacementFromServer(); @@ -676,7 +676,7 @@ class _AdminChildDetailModalState extends State { } 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 { 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 { crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Expanded( - child: AdminAmPhotoFrame( + child: AmPhotoFrame( photoUrl: widget.isCreating ? null : widget.enfant?.photoUrl, @@ -1329,7 +1329,7 @@ class _AdminChildDetailModalState extends State { Future _pickFamily() async { if (_busy) return; - final selected = await AdminSelectFamilleModal.show( + final selected = await SelectFamilleModal.show( context, title: 'Choisir une famille', ); diff --git a/frontend/lib/widgets/admin/common/admin_children_affiliation_panel.dart b/frontend/lib/widgets/dashboard/children_affiliation_panel.dart similarity index 91% rename from frontend/lib/widgets/admin/common/admin_children_affiliation_panel.dart rename to frontend/lib/widgets/dashboard/children_affiliation_panel.dart index 526d7f8..2cacec5 100644 --- a/frontend/lib/widgets/admin/common/admin_children_affiliation_panel.dart +++ b/frontend/lib/widgets/dashboard/children_affiliation_panel.dart @@ -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 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: [ diff --git a/frontend/lib/widgets/admin/common/admin_detail_modal.dart b/frontend/lib/widgets/dashboard/detail_modal.dart similarity index 96% rename from frontend/lib/widgets/admin/common/admin_detail_modal.dart rename to frontend/lib/widgets/dashboard/detail_modal.dart index affc0d8..255d2bb 100644 --- a/frontend/lib/widgets/admin/common/admin_detail_modal.dart +++ b/frontend/lib/widgets/dashboard/detail_modal.dart @@ -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 fields; + final List fields; final VoidCallback onEdit; final VoidCallback onDelete; - const AdminDetailModal({ + const DetailModal({ super.key, required this.title, this.subtitle, diff --git a/frontend/lib/widgets/admin/common/admin_enfant_user_card.dart b/frontend/lib/widgets/dashboard/enfant_user_card.dart similarity index 91% rename from frontend/lib/widgets/admin/common/admin_enfant_user_card.dart rename to frontend/lib/widgets/dashboard/enfant_user_card.dart index 04b22e5..347fccb 100644 --- a/frontend/lib/widgets/admin/common/admin_enfant_user_card.dart +++ b/frontend/lib/widgets/dashboard/enfant_user_card.dart @@ -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 enfantAdminSubtitleLines({ required String status, @@ -29,7 +29,7 @@ List 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 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 extraSubtitleLines = const [], List 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 extraSubtitleLines = const [], List 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, diff --git a/frontend/lib/widgets/admin/common/admin_parent_edit_modal.dart b/frontend/lib/widgets/dashboard/parent_edit_modal.dart similarity index 94% rename from frontend/lib/widgets/admin/common/admin_parent_edit_modal.dart rename to frontend/lib/widgets/dashboard/parent_edit_modal.dart index 101b6a5..c3c7093 100644 --- a/frontend/lib/widgets/admin/common/admin_parent_edit_modal.dart +++ b/frontend/lib/widgets/dashboard/parent_edit_modal.dart @@ -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'; /// 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 createState() => _AdminParentEditModalState(); + State createState() => _ParentEditModalState(); } -class _AdminParentEditModalState extends State { +class _ParentEditModalState extends State { late final TextEditingController _nomCtrl; late final TextEditingController _prenomCtrl; late final TextEditingController _emailCtrl; @@ -129,7 +129,7 @@ class _AdminParentEditModalState extends State { if (!mounted) return; await showDialog( context: context, - builder: (ctx) => AdminParentEditModal( + builder: (ctx) => ParentEditModal( parent: parent, onSaved: () async { try { @@ -244,7 +244,7 @@ class _AdminParentEditModalState extends State { if (!mounted) return; await showDialog( context: context, - builder: (ctx) => AdminChildDetailModal( + builder: (ctx) => ChildDetailModal( enfant: enfant, onSaved: _reloadChildren, ), @@ -322,7 +322,7 @@ class _AdminParentEditModalState extends State { Future _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 { } Widget _childrenPanel() { - return AdminChildrenAffiliationPanel( + return ChildrenAffiliationPanel( children: _children, scrollController: _childrenScrollCtrl, onOpen: _openChild, @@ -437,7 +437,7 @@ class _AdminParentEditModalState extends State { const SizedBox(width: 12), SizedBox( width: 160, - child: AdminStatusCapsule( + child: StatusCapsule( statut: _statut, onChanged: (v) => setState(() { _statut = v; diff --git a/frontend/lib/widgets/admin/common/admin_select_am_modal.dart b/frontend/lib/widgets/dashboard/select_am_modal.dart similarity index 92% rename from frontend/lib/widgets/admin/common/admin_select_am_modal.dart rename to frontend/lib/widgets/dashboard/select_am_modal.dart index ab46601..b35c5a7 100644 --- a/frontend/lib/widgets/admin/common/admin_select_am_modal.dart +++ b/frontend/lib/widgets/dashboard/select_am_modal.dart @@ -3,9 +3,9 @@ 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/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/admin/validation_modal_theme.dart'; List _amSelectSubtitleLines(AssistanteMaternelleModel am) { @@ -28,22 +28,22 @@ List _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 show( BuildContext context, { Set excludeIds = const {}, String title = 'Choisir une assistante maternelle', }) { - return AdminSelectListModal.show( + return SelectListModal.show( 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( + toggleFilter: const SelectToggleFilter( 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( context: context, - builder: (ctx) => AdminAmEditModal( + builder: (ctx) => AmEditModal( assistante: _am, onSaved: () async { try { diff --git a/frontend/lib/widgets/admin/common/admin_select_enfant_modal.dart b/frontend/lib/widgets/dashboard/select_enfant_modal.dart similarity index 83% rename from frontend/lib/widgets/admin/common/admin_select_enfant_modal.dart rename to frontend/lib/widgets/dashboard/select_enfant_modal.dart index dafe5d4..785c04e 100644 --- a/frontend/lib/widgets/admin/common/admin_select_enfant_modal.dart +++ b/frontend/lib/widgets/dashboard/select_enfant_modal.dart @@ -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 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( + return SelectListModal.show( 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( + ? SelectToggleFilter( 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), diff --git a/frontend/lib/widgets/admin/common/admin_select_famille_modal.dart b/frontend/lib/widgets/dashboard/select_famille_modal.dart similarity index 88% rename from frontend/lib/widgets/admin/common/admin_select_famille_modal.dart rename to frontend/lib/widgets/dashboard/select_famille_modal.dart index 4fbd3a3..abddc2e 100644 --- a/frontend/lib/widgets/admin/common/admin_select_famille_modal.dart +++ b/frontend/lib/widgets/dashboard/select_famille_modal.dart @@ -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 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 buildFamilleFoyers(List parents) { +List buildFamilleFoyers(List parents) { final seenDossiers = {}; final seenUserIds = {}; - final foyers = []; + final foyers = []; for (final p in parents) { final dossier = (p.user.numeroDossier ?? '').trim(); @@ -70,7 +70,7 @@ List buildFamilleFoyers(List 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 buildFamilleFoyers(List parents) { } /// Sélection d'une famille / dossier pour créer un enfant — ticket #132. -class AdminSelectFamilleModal { - AdminSelectFamilleModal._(); +class SelectFamilleModal { + SelectFamilleModal._(); - static Future show( + static Future show( BuildContext context, { String title = 'Choisir une famille', }) { - return AdminSelectListModal.show( + return SelectListModal.show( 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: [ diff --git a/frontend/lib/widgets/admin/common/admin_select_list_modal.dart b/frontend/lib/widgets/dashboard/select_list_modal.dart similarity index 95% rename from frontend/lib/widgets/admin/common/admin_select_list_modal.dart rename to frontend/lib/widgets/dashboard/select_list_modal.dart index 4fdc70c..0335cc7 100644 --- a/frontend/lib/widgets/admin/common/admin_select_list_modal.dart +++ b/frontend/lib/widgets/dashboard/select_list_modal.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:p_tits_pas/widgets/admin/validation_modal_theme.dart'; /// Filtre optionnel (switch) sur la même ligne que la barre de recherche. -class AdminSelectToggleFilter { +class SelectToggleFilter { final String label; final bool initialValue; @@ -10,7 +10,7 @@ class AdminSelectToggleFilter { /// [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 { /// 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 extends StatefulWidget { +class SelectListModal extends StatefulWidget { final String title; final String searchHint; final Future> Function() loadItems; @@ -40,7 +40,7 @@ class AdminSelectListModal extends StatefulWidget { final int minVisibleCards; /// Switch optionnel à droite du champ de recherche (ex. « Sans garde », « Libre »). - final AdminSelectToggleFilter? toggleFilter; + final SelectToggleFilter? 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 extends StatefulWidget { Future Function() reload, )? resolveSelect; - const AdminSelectListModal({ + const SelectListModal({ super.key, required this.title, required this.loadItems, @@ -82,7 +82,7 @@ class AdminSelectListModal extends StatefulWidget { double modalWidth = 930, double cardExtent = 52, int minVisibleCards = 8, - AdminSelectToggleFilter? toggleFilter, + SelectToggleFilter? toggleFilter, Future Function( BuildContext context, T item, @@ -91,7 +91,7 @@ class AdminSelectListModal extends StatefulWidget { }) { return showDialog( context: context, - builder: (ctx) => AdminSelectListModal( + builder: (ctx) => SelectListModal( title: title, loadItems: loadItems, matchesQuery: matchesQuery, @@ -109,11 +109,11 @@ class AdminSelectListModal extends StatefulWidget { } @override - State> createState() => - _AdminSelectListModalState(); + State> createState() => + _SelectListModalState(); } -class _AdminSelectListModalState extends State> { +class _SelectListModalState extends State> { final _searchCtrl = TextEditingController(); List _all = []; bool _loading = true; diff --git a/frontend/lib/widgets/admin/common/admin_status_capsule.dart b/frontend/lib/widgets/dashboard/status_capsule.dart similarity index 95% rename from frontend/lib/widgets/admin/common/admin_status_capsule.dart rename to frontend/lib/widgets/dashboard/status_capsule.dart index a42b015..e22b665 100644 --- a/frontend/lib/widgets/admin/common/admin_status_capsule.dart +++ b/frontend/lib/widgets/dashboard/status_capsule.dart @@ -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? onChanged; static const statuts = ['actif', 'en_attente', 'suspendu', 'refuse']; - const AdminStatusCapsule({ + const StatusCapsule({ super.key, required this.statut, this.onChanged, diff --git a/frontend/lib/widgets/admin/common/admin_user_card.dart b/frontend/lib/widgets/dashboard/user_card.dart similarity index 97% rename from frontend/lib/widgets/admin/common/admin_user_card.dart rename to frontend/lib/widgets/dashboard/user_card.dart index 640d293..07798dd 100644 --- a/frontend/lib/widgets/admin/common/admin_user_card.dart +++ b/frontend/lib/widgets/dashboard/user_card.dart @@ -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 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 createState() => _AdminUserCardState(); + State createState() => _UserCardState(); } -class _AdminUserCardState extends State { +class _UserCardState extends State { bool _isHovered = false; @override diff --git a/frontend/lib/widgets/admin/common/admin_list_state.dart b/frontend/lib/widgets/dashboard/user_list_state.dart similarity index 92% rename from frontend/lib/widgets/admin/common/admin_list_state.dart rename to frontend/lib/widgets/dashboard/user_list_state.dart index 41b497c..d7b9526 100644 --- a/frontend/lib/widgets/admin/common/admin_list_state.dart +++ b/frontend/lib/widgets/dashboard/user_list_state.dart @@ -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, diff --git a/frontend/lib/widgets/admin/dashboard_admin.dart b/frontend/lib/widgets/dashboard/user_management_sub_bar.dart similarity index 100% rename from frontend/lib/widgets/admin/dashboard_admin.dart rename to frontend/lib/widgets/dashboard/user_management_sub_bar.dart