diff --git a/frontend/lib/widgets/admin/common/admin_child_detail_modal.dart b/frontend/lib/widgets/admin/common/admin_child_detail_modal.dart index df2c7bc..df063f2 100644 --- a/frontend/lib/widgets/admin/common/admin_child_detail_modal.dart +++ b/frontend/lib/widgets/admin/common/admin_child_detail_modal.dart @@ -57,6 +57,7 @@ class _AdminChildDetailModalState extends State { bool get _isUnborn => _status == 'a_naitre'; bool get _isScolarise => _status == 'scolarise'; + bool get _isSansGarde => _status == 'sans_garde'; bool get _showsAmPlacement => !_isScolarise; List get _availableGenders => @@ -294,7 +295,7 @@ class _AdminChildDetailModalState extends State { return; } - if (_linkedAm != null) { + if (_linkedAm != null && !_isSansGarde) { if (!mounted) return; ScaffoldMessenger.of(context).showSnackBar( const SnackBar( @@ -332,11 +333,25 @@ class _AdminChildDetailModalState extends State { setState(() => _placementBusy = true); try { + // Sans garde : éventuel lien résiduel à clôturer avant rattachement. + final previousAm = _linkedAm; + if (previousAm != null) { + await UserService.detachEnfantFromAm( + amUserId: previousAm.user.id, + enfantId: widget.enfant.id, + ); + } await UserService.attachEnfantToAm( amUserId: selected.user.id, enfantId: widget.enfant.id, ); if (!mounted) return; + setState(() { + // Le back passe déjà sans_garde → garde à l'attach ; on aligne l'UI. + if (_status == 'sans_garde') { + _status = 'garde'; + } + }); await _loadLinkedAm(); widget.onSaved?.call(); if (!mounted) return; @@ -386,7 +401,13 @@ class _AdminChildDetailModalState extends State { enfantId: widget.enfant.id, ); if (!mounted) return; - await _loadLinkedAm(); + setState(() { + // Le back repasse en sans_garde sauf a_naitre / scolarise. + if (_status != 'a_naitre' && _status != 'scolarise') { + _status = 'sans_garde'; + } + _linkedAm = null; + }); widget.onSaved?.call(); if (!mounted) return; ScaffoldMessenger.of(context).showSnackBar( @@ -402,6 +423,30 @@ class _AdminChildDetailModalState extends State { } } + /// Passe en « Sans garde » : cadre vide + détachement AM si besoin. + Future _applySansGardeStatus() async { + final am = _linkedAm; + if (am == null) return; + + setState(() => _placementBusy = true); + try { + await UserService.detachEnfantFromAm( + amUserId: am.user.id, + enfantId: widget.enfant.id, + ); + if (!mounted) return; + setState(() => _linkedAm = null); + widget.onSaved?.call(); + } catch (e) { + if (!mounted) return; + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text(e.toString().replaceFirst('Exception: ', ''))), + ); + } finally { + if (mounted) setState(() => _placementBusy = false); + } + } + InputDecoration _inputDecoration({String? hint}) { return ValidationFieldDecoration.input(hint: hint).copyWith( isDense: false, @@ -479,11 +524,16 @@ class _AdminChildDetailModalState extends State { ), ) .toList(), - onChanged: (v) => setState(() { - _status = v; - _coerceGenderForStatus(); - _dirty = true; - }), + onChanged: (v) { + setState(() { + _status = v; + _coerceGenderForStatus(); + _dirty = true; + }); + if (v == 'sans_garde') { + _applySansGardeStatus(); + } + }, ), ), ValidationLabeledField( @@ -731,6 +781,8 @@ class _AdminChildDetailModalState extends State { ); } + // Sans garde : toujours le cadre vide (comme après détachement AM). + if (_isSansGarde) return _emptyAmSlot(); if (_linkedAm != null) return _linkedAmCard(); return _emptyAmSlot(); }