From 8b1b9e79179fb484c126c3be29e78a0506957aaa Mon Sep 17 00:00:00 2001 From: Julien Martin Date: Thu, 24 Sep 2026 12:13:20 +0200 Subject: [PATCH] feat(front): implement AM dashboard shell with 3 columns (#169) Co-authored-by: Cursor --- .../lib/screens/am/am_dashboard_screen.dart | 100 ++++++++++-------- .../widgets/quotidien/quotidien_bandeau.dart | 17 +-- 2 files changed, 63 insertions(+), 54 deletions(-) diff --git a/frontend/lib/screens/am/am_dashboard_screen.dart b/frontend/lib/screens/am/am_dashboard_screen.dart index fea0afe..f245013 100644 --- a/frontend/lib/screens/am/am_dashboard_screen.dart +++ b/frontend/lib/screens/am/am_dashboard_screen.dart @@ -1,11 +1,12 @@ import 'package:flutter/material.dart'; import 'package:p_tits_pas/models/user.dart'; import 'package:p_tits_pas/services/auth_service.dart'; -import 'package:p_tits_pas/widgets/app_footer.dart'; -import 'package:p_tits_pas/widgets/dashboard/dashboard_bandeau.dart'; +import 'package:p_tits_pas/widgets/quotidien/quotidien_shell.dart'; +import 'package:p_tits_pas/widgets/quotidien/quotidien_theme.dart'; -/// Dashboard assistante maternelle – page blanche avec bandeau générique. -/// Contenu détaillé à venir. +/// Dashboard assistante maternelle – coquille 3 colonnes quotidien (#169). +/// Colonne gauche : sélecteur de couple enfant–parent(s) (à venir #170). +/// Métier cartes / blog / messagerie : tickets C/D/E. class AmDashboardScreen extends StatefulWidget { const AmDashboardScreen({super.key}); @@ -14,7 +15,7 @@ class AmDashboardScreen extends StatefulWidget { } class _AmDashboardScreenState extends State { - int selectedTabIndex = 0; + QuotidienNavSection _section = QuotidienNavSection.liaison; AppUser? _user; @override @@ -28,51 +29,58 @@ class _AmDashboardScreenState extends State { if (mounted) setState(() => _user = user); } + String get _displayName { + final n = _user?.fullName.trim() ?? ''; + if (n.isNotEmpty) return n; + final email = _user?.email.trim() ?? ''; + if (email.isNotEmpty) return email.split('@').first; + return 'Assistante maternelle'; + } + + void _soon(String label) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('$label — à venir')), + ); + } + @override Widget build(BuildContext context) { - return Scaffold( - appBar: PreferredSize( - preferredSize: const Size.fromHeight(60.0), - child: DashboardBandeau( - tabItems: const [ - DashboardTabItem(label: 'Mon tableau de bord'), - DashboardTabItem(label: 'Paramètres'), - ], - selectedTabIndex: selectedTabIndex, - onTabSelected: (index) => setState(() => selectedTabIndex = index), - userDisplayName: _user?.fullName.isNotEmpty == true - ? _user!.fullName - : 'Assistante maternelle', - userEmail: _user?.email, - userRole: _user?.role, - onProfileTap: () { - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: Text('Modification du profil – à venir')), - ); - }, - onSettingsTap: () { - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar(content: Text('Paramètres – à venir')), - ); - }, - onLogout: () {}, - showLogoutConfirmation: true, - ), + return QuotidienShell( + selectedSection: _section, + onSectionSelected: (s) => setState(() => _section = s), + userDisplayName: _displayName, + userEmail: _user?.email, + onProfileTap: () => _soon('Profil'), + onSettingsTap: () => _soon('Paramètres'), + // L'AM n'a pas de bouton "Recherche AM" dans le bandeau + onSearchAmTap: null, + leftColumn: const QuotidienColumnPlaceholder( + title: 'Cartes', + subtitle: + 'Couple enfant–parent(s) et flux de cartes\n(à brancher — tickets #170 / #174).', + icon: Icons.style_outlined, ), - body: Column( - children: [ - Expanded( - child: Center( - child: Text( - 'Dashboard AM – à venir', - style: Theme.of(context).textTheme.titleLarge, - ), - ), - ), - const AppFooter(), - ], + centerColumn: const QuotidienColumnPlaceholder( + title: 'Blog', + subtitle: + 'Fil du quotidien (affichage par défaut)\n(à brancher — ticket #179).', + icon: Icons.auto_stories_outlined, + ), + rightColumn: const QuotidienColumnPlaceholder( + title: 'Messagerie', + subtitle: + 'Mess. Parents · Mess. RPE\n(à brancher — ticket #185).', + icon: Icons.chat_bubble_outline, + ), + agendaBody: const QuotidienStubPage( + title: 'Agenda', + message: 'Agenda — contenu à venir (stub #187).', + ), + contratBody: const QuotidienStubPage( + title: 'Contrat', + message: 'Contrat — contenu à venir (stub #187).', ), ); } } + diff --git a/frontend/lib/widgets/quotidien/quotidien_bandeau.dart b/frontend/lib/widgets/quotidien/quotidien_bandeau.dart index 16e0399..2bb5e98 100644 --- a/frontend/lib/widgets/quotidien/quotidien_bandeau.dart +++ b/frontend/lib/widgets/quotidien/quotidien_bandeau.dart @@ -183,15 +183,16 @@ class _UserMenu extends StatelessWidget { title: Text('Profil'), ), ), - const PopupMenuItem( - value: 'search_am', - child: ListTile( - dense: true, - contentPadding: EdgeInsets.zero, - leading: Icon(Icons.search, size: 20), - title: Text('Recherche AM'), + if (onSearchAmTap != null) + const PopupMenuItem( + value: 'search_am', + child: ListTile( + dense: true, + contentPadding: EdgeInsets.zero, + leading: Icon(Icons.search, size: 20), + title: Text('Recherche AM'), + ), ), - ), const PopupMenuItem( value: 'settings', child: ListTile(