feat(#138): ouvrir la fiche parent depuis les responsables de la modale enfant.

Les noms du sous-titre deviennent des liens cliquables vers
AdminParentEditModal, comme l'ouverture de fiche AM.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
MARTIN Julien 2026-07-17 12:54:32 +02:00
parent b903dbf60b
commit 90b185740c

View File

@ -8,6 +8,7 @@ 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_status_utils.dart';
import 'package:p_tits_pas/widgets/admin/common/admin_am_edit_modal.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_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/validation_detail_section.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_modal_theme.dart';
import 'package:p_tits_pas/widgets/common/auth_network_image.dart'; import 'package:p_tits_pas/widgets/common/auth_network_image.dart';
@ -170,16 +171,77 @@ class _AdminChildDetailModalState extends State<AdminChildDetailModal> {
return '$fn $ln'.trim(); return '$fn $ln'.trim();
} }
String? _parentsSubtitle() { List<EnfantParentLink> get _parentLinks => widget.enfant.parentLinks
final names = widget.enfant.parentLinks .where((l) => l.parentId.trim().isNotEmpty)
.map((l) { .toList();
final n = (l.parentName ?? '').trim();
return n.isNotEmpty ? n : 'Parent rattaché'; Future<void> _openParent(EnfantParentLink link) async {
}) if (_busy) return;
.where((s) => s.isNotEmpty) final id = link.parentId.trim();
.toList(); if (id.isEmpty) return;
if (names.isEmpty) return null;
return 'Responsables : ${names.join(', ')}'; try {
final parent = await UserService.getParent(id);
if (!mounted) return;
await showDialog<void>(
context: context,
builder: (ctx) => AdminParentEditModal(
parent: parent,
onSaved: () => widget.onSaved?.call(),
),
);
} catch (e) {
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(e.toString().replaceFirst('Exception: ', ''))),
);
}
}
Widget? _parentsSubtitle() {
final links = _parentLinks;
if (links.isEmpty) return null;
return Wrap(
crossAxisAlignment: WrapCrossAlignment.center,
children: [
const Text(
'Responsables : ',
style: TextStyle(fontSize: 13, color: Colors.black54),
),
for (var i = 0; i < links.length; i++) ...[
if (i > 0)
const Text(
', ',
style: TextStyle(fontSize: 13, color: Colors.black54),
),
_parentNameLink(links[i]),
],
],
);
}
Widget _parentNameLink(EnfantParentLink link) {
final name = (link.parentName ?? '').trim();
final label = name.isNotEmpty ? name : 'Parent rattaché';
return InkWell(
onTap: _busy ? null : () => _openParent(link),
borderRadius: BorderRadius.circular(4),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 2, vertical: 2),
child: Text(
label,
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.w600,
color: ValidationModalTheme.primaryActionBackground,
decoration: TextDecoration.underline,
decorationColor: ValidationModalTheme.primaryActionBackground
.withValues(alpha: 0.5),
),
),
),
);
} }
Future<void> _save() async { Future<void> _save() async {
@ -994,13 +1056,7 @@ class _AdminChildDetailModalState extends State<AdminChildDetailModal> {
), ),
if (_parentsSubtitle() != null) ...[ if (_parentsSubtitle() != null) ...[
const SizedBox(height: 4), const SizedBox(height: 4),
Text( _parentsSubtitle()!,
_parentsSubtitle()!,
style: const TextStyle(
fontSize: 13,
color: Colors.black54,
),
),
], ],
], ],
), ),