petitspas/frontend/lib/widgets/admin/common/admin_children_affiliation_panel.dart
Julien Martin 003fe6b762 feat(#131): fiches parent/AM éditable, placement AM↔enfant, statuts garde/sans_garde
Squash merge develop → master.

- Fiche parent éditable (co-parent, PATCH fiche, GET /parents)
- Fiche AM 3 onglets (PATCH fiche, rattacher/détacher enfants)
- Table enfants_assistantes_maternelles + enum garde/sans_garde
- Migration SQL + BDD.sql canonique
- Correctifs recette : @Get() parents, DTO fiche AM, fix NIR

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-11 22:49:57 +02:00

85 lines
2.7 KiB
Dart

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';
/// Liste scrollable d'enfants rattachés (fiche parent / fiche AM).
class AdminChildrenAffiliationPanel extends StatelessWidget {
final List<ParentChildSummary> children;
final ScrollController scrollController;
final void Function(ParentChildSummary child) onOpen;
final void Function(ParentChildSummary child) onDetach;
final String emptyMessage;
final double? height;
static const double _itemHeight = 58;
static const double defaultViewportHeight = _itemHeight * 2.5 + 8;
const AdminChildrenAffiliationPanel({
super.key,
required this.children,
required this.scrollController,
required this.onOpen,
required this.onDetach,
this.emptyMessage = 'Aucun enfant rattaché',
this.height,
});
@override
Widget build(BuildContext context) {
if (height != null) {
return _panel(height!);
}
return LayoutBuilder(
builder: (context, constraints) {
final h = constraints.maxHeight.isFinite && constraints.maxHeight > 0
? constraints.maxHeight
: defaultViewportHeight;
return _panel(h);
},
);
}
Widget _panel(double panelHeight) {
return Container(
height: panelHeight,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.grey.shade300),
),
clipBehavior: Clip.antiAlias,
child: children.isEmpty
? Center(
child: Text(
emptyMessage,
style: const TextStyle(fontSize: 14, color: Colors.black54),
),
)
: ListView.builder(
controller: scrollController,
padding: const EdgeInsets.fromLTRB(8, 8, 8, 4),
itemExtent: _itemHeight,
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: () => onOpen(c),
),
IconButton(
tooltip: 'Détacher',
icon: Icon(Icons.link_off, color: Colors.orange.shade800),
onPressed: () => onDetach(c),
),
],
);
},
),
);
}
}