feat(#131): fiche AM éditable en 3 onglets et widgets admin partagés.
Modale admin AM (identité, dossier pro, enfants), API front avec repli, note back affiliation, et extraction gélule statut / liste enfants pour la fiche parent. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -6,7 +6,8 @@ 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_enfant_user_card.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_children_affiliation_panel.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_status_capsule.dart';
|
||||
import 'package:p_tits_pas/widgets/common/identity_block.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/validation_modal_theme.dart';
|
||||
|
||||
@@ -42,13 +43,7 @@ class _AdminParentEditModalState extends State<AdminParentEditModal> {
|
||||
bool _saving = false;
|
||||
bool _dirty = false;
|
||||
|
||||
static const _statuts = ['actif', 'en_attente', 'suspendu', 'refuse'];
|
||||
|
||||
static const double _modalWidth = 930;
|
||||
/// Hauteur d'une ligne enfant (carte + marge) — viewport = 2,5 lignes visibles.
|
||||
static const double _childListItemHeight = 58;
|
||||
static const double _childrenListViewportHeight =
|
||||
_childListItemHeight * 2.5 + 8;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -124,21 +119,6 @@ class _AdminParentEditModalState extends State<AdminParentEditModal> {
|
||||
return 'Co-parent : $name';
|
||||
}
|
||||
|
||||
String _displayStatus(String status) {
|
||||
switch (status) {
|
||||
case 'actif':
|
||||
return 'Actif';
|
||||
case 'en_attente':
|
||||
return 'En attente';
|
||||
case 'suspendu':
|
||||
return 'Suspendu';
|
||||
case 'refuse':
|
||||
return 'Refusé';
|
||||
default:
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _save() async {
|
||||
if (!_dirty) return;
|
||||
final confirmed = await showDialog<bool>(
|
||||
@@ -337,39 +317,12 @@ class _AdminParentEditModalState extends State<AdminParentEditModal> {
|
||||
}
|
||||
}
|
||||
|
||||
Widget _statusDropdown() {
|
||||
return Container(
|
||||
height: 34,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(18),
|
||||
border: Border.all(color: Colors.black26),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||
child: DropdownButtonHideUnderline(
|
||||
child: DropdownButton<String>(
|
||||
value: _statuts.contains(_statut) ? _statut : _statuts.first,
|
||||
isExpanded: true,
|
||||
isDense: true,
|
||||
style: const TextStyle(fontSize: 13, color: Colors.black87),
|
||||
icon: const Icon(Icons.arrow_drop_down, size: 20),
|
||||
items: _statuts
|
||||
.map(
|
||||
(s) => DropdownMenuItem(
|
||||
value: s,
|
||||
child: Text(_displayStatus(s)),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
onChanged: (v) {
|
||||
if (v == null) return;
|
||||
setState(() {
|
||||
_statut = v;
|
||||
_dirty = true;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
Widget _childrenPanel() {
|
||||
return AdminChildrenAffiliationPanel(
|
||||
children: _children,
|
||||
scrollController: _childrenScrollCtrl,
|
||||
onOpen: _openChild,
|
||||
onDetach: _detachChild,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -385,49 +338,6 @@ class _AdminParentEditModalState extends State<AdminParentEditModal> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _childrenPanel() {
|
||||
return Container(
|
||||
height: _childrenListViewportHeight,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(color: Colors.grey.shade300),
|
||||
),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: _children.isEmpty
|
||||
? const Center(
|
||||
child: Text(
|
||||
'Aucun enfant rattaché',
|
||||
style: TextStyle(fontSize: 14, color: Colors.black54),
|
||||
),
|
||||
)
|
||||
: ListView.builder(
|
||||
controller: _childrenScrollCtrl,
|
||||
padding: const EdgeInsets.fromLTRB(8, 8, 8, 4),
|
||||
itemExtent: _childListItemHeight,
|
||||
itemCount: _children.length,
|
||||
itemBuilder: (_, i) {
|
||||
final c = _children[i];
|
||||
return AdminEnfantUserCard.fromSummary(
|
||||
c,
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.visibility_outlined),
|
||||
tooltip: 'Voir / modifier',
|
||||
onPressed: () => _openChild(c),
|
||||
),
|
||||
IconButton(
|
||||
tooltip: 'Détacher',
|
||||
icon: Icon(Icons.link_off, color: Colors.orange.shade800),
|
||||
onPressed: () => _detachChild(c),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildFooter() {
|
||||
return Row(
|
||||
children: [
|
||||
@@ -465,10 +375,7 @@ class _AdminParentEditModalState extends State<AdminParentEditModal> {
|
||||
return Dialog(
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: _modalWidth,
|
||||
maxHeight: MediaQuery.of(context).size.height * 0.85,
|
||||
),
|
||||
constraints: const BoxConstraints(maxWidth: _modalWidth),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
@@ -502,7 +409,16 @@ class _AdminParentEditModalState extends State<AdminParentEditModal> {
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
SizedBox(width: 160, child: _statusDropdown()),
|
||||
SizedBox(
|
||||
width: 160,
|
||||
child: AdminStatusCapsule(
|
||||
statut: _statut,
|
||||
onChanged: (v) => setState(() {
|
||||
_statut = v;
|
||||
_dirty = true;
|
||||
}),
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
padding: EdgeInsets.zero,
|
||||
constraints: const BoxConstraints(
|
||||
@@ -518,13 +434,13 @@ class _AdminParentEditModalState extends State<AdminParentEditModal> {
|
||||
),
|
||||
const Divider(height: 1),
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(20, 16, 20, 16),
|
||||
padding: const EdgeInsets.fromLTRB(20, 12, 20, 12),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
_identityFields(),
|
||||
const SizedBox(height: 12),
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
'Nombre d\'enfants : ${_children.length}',
|
||||
style: const TextStyle(
|
||||
@@ -533,9 +449,9 @@ class _AdminParentEditModalState extends State<AdminParentEditModal> {
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
const SizedBox(height: 6),
|
||||
_childrenPanel(),
|
||||
const SizedBox(height: 16),
|
||||
const SizedBox(height: 12),
|
||||
_buildFooter(),
|
||||
],
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user