diff --git a/frontend/lib/widgets/admin/common/admin_am_edit_modal.dart b/frontend/lib/widgets/admin/common/admin_am_edit_modal.dart index 082356e..b3ca7f1 100644 --- a/frontend/lib/widgets/admin/common/admin_am_edit_modal.dart +++ b/frontend/lib/widgets/admin/common/admin_am_edit_modal.dart @@ -53,6 +53,7 @@ class _AdminAmEditModalState extends State late bool _disponible; late int? _placesAvailable; late List _children; + late Set _baselineChildIds; bool _saving = false; bool _dirty = false; @@ -124,6 +125,7 @@ class _AdminAmEditModalState extends State _disponible = am.available ?? true; _placesAvailable = am.placesAvailable; _children = List.of(am.children); + _baselineChildIds = _children.map((c) => c.id).toSet(); for (final c in [ _nomCtrl, @@ -147,7 +149,18 @@ class _AdminAmEditModalState extends State _nomCtrl.addListener(_onNameFieldChanged); _prenomCtrl.addListener(_onNameFieldChanged); _tabCtrl.addListener(_onTabChanged); - _reloadChildren(); + _fetchChildrenFromServer(); + } + + bool _childrenChanged() { + final current = _children.map((c) => c.id).toSet(); + return current.length != _baselineChildIds.length || + !current.containsAll(_baselineChildIds); + } + + void _syncPlacesAfterChildrenChange() { + final expected = _computedPlacesAvailable(); + if (expected != null) _placesAvailable = expected; } void _onTabChanged() { @@ -288,6 +301,22 @@ class _AdminAmEditModalState extends State setState(() => _saving = true); try { + if (_childrenChanged()) _syncPlacesAfterChildrenChange(); + + final currentIds = _children.map((c) => c.id).toSet(); + for (final id in _baselineChildIds.difference(currentIds)) { + await UserService.detachEnfantFromAm( + amUserId: widget.assistante.user.id, + enfantId: id, + ); + } + for (final id in currentIds.difference(_baselineChildIds)) { + await UserService.attachEnfantToAm( + amUserId: widget.assistante.user.id, + enfantId: id, + ); + } + await UserService.updateAmFiche( amUserId: widget.assistante.user.id, body: { @@ -308,8 +337,7 @@ class _AdminAmEditModalState extends State if (_frDateToIso(_dateAgrementCtrl.text) != null) 'agreement_date': _frDateToIso(_dateAgrementCtrl.text), if (_capaciteMax() != null) 'max_children': _capaciteMax(), - if (_placesAvailable != widget.assistante.placesAvailable) - 'places_available': _placesAvailable, + if (_placesAvailable != null) 'places_available': _placesAvailable, 'available': _disponible, }, ); @@ -317,6 +345,7 @@ class _AdminAmEditModalState extends State setState(() { _dirty = false; _saving = false; + _baselineChildIds = currentIds; }); widget.onSaved?.call(); ScaffoldMessenger.of(context).showSnackBar( @@ -331,7 +360,7 @@ class _AdminAmEditModalState extends State } } - Future _reloadChildren() async { + Future _fetchChildrenFromServer() async { try { final refreshed = await UserService.getAssistanteMaternelle(widget.assistante.user.id); @@ -345,7 +374,26 @@ class _AdminAmEditModalState extends State }).toList(); if (!mounted) return; - setState(() => _children = kids); + setState(() { + _children = kids; + _baselineChildIds = kids.map((c) => c.id).toSet(); + }); + } catch (_) {} + } + + Future _refreshChildrenDetails() async { + try { + final all = await UserService.getEnfants(); + final byId = {for (final e in all) e.id: e}; + + if (!mounted) return; + setState(() { + _children = _children.map((c) { + final full = byId[c.id]; + if (full != null) return ParentChildSummary.fromEnfant(full); + return c; + }).toList(); + }); } catch (_) {} } @@ -357,7 +405,7 @@ class _AdminAmEditModalState extends State context: context, builder: (ctx) => AdminChildDetailModal( enfant: enfant, - onSaved: _reloadChildren, + onSaved: _refreshChildrenDetails, ), ); } catch (e) { @@ -392,23 +440,11 @@ class _AdminAmEditModalState extends State ); if (confirmed != true || !mounted) return; - try { - await UserService.detachEnfantFromAm( - amUserId: widget.assistante.user.id, - enfantId: child.id, - ); - if (!mounted) return; - await _reloadChildren(); - if (!mounted) return; - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar(content: Text('Enfant détaché')), - ); - } catch (e) { - if (!mounted) return; - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text(e.toString().replaceFirst('Exception: ', ''))), - ); - } + setState(() { + _children = _children.where((c) => c.id != child.id).toList(); + _syncPlacesAfterChildrenChange(); + _dirty = true; + }); } Future _attachChild() async { @@ -450,23 +486,14 @@ class _AdminAmEditModalState extends State ); if (selected == null || !mounted) return; - try { - await UserService.attachEnfantToAm( - amUserId: widget.assistante.user.id, - enfantId: selected.id, - ); - if (!mounted) return; - await _reloadChildren(); - if (!mounted) return; - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar(content: Text('Enfant rattaché')), - ); - } catch (e) { - if (!mounted) return; - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text(e.toString().replaceFirst('Exception: ', ''))), - ); - } + setState(() { + _children = [ + ..._children, + ParentChildSummary.fromEnfant(selected), + ]; + _syncPlacesAfterChildrenChange(); + _dirty = true; + }); }