- Bandeau générique (DashboardBandeau) pour Parent, Admin, Gestionnaire, AM - ParentDashboardScreen, AdminDashboardScreen, GestionnaireDashboardScreen, AM dashboard - AppFooter responsive, scripts Gitea (create/list issues parent API) - Doc: ticket #101 Inscription Parent API, mise à jour 23_LISTE-TICKETS - User.fromJson robustesse (nullable id/email/role) - Suppression dashboard_app_bar.dart au profit de dashboard_bandeau.dart Refs: #100, #101 Made-with: Cursor
264 lines
8.4 KiB
Dart
264 lines
8.4 KiB
Dart
import 'package:flutter/material.dart';
|
||
import 'package:p_tits_pas/controllers/parent_dashboard_controller.dart';
|
||
import 'package:p_tits_pas/models/user.dart';
|
||
import 'package:p_tits_pas/services/auth_service.dart';
|
||
import 'package:p_tits_pas/services/dashboardService.dart';
|
||
import 'package:p_tits_pas/widgets/app_footer.dart';
|
||
import 'package:p_tits_pas/widgets/dashbord_parent/children_sidebar.dart';
|
||
import 'package:p_tits_pas/widgets/dashbord_parent/wid_dashbord.dart';
|
||
import 'package:p_tits_pas/widgets/dashboard/dashboard_bandeau.dart';
|
||
import 'package:p_tits_pas/widgets/main_content_area.dart';
|
||
import 'package:p_tits_pas/widgets/messaging_sidebar.dart';
|
||
import 'package:provider/provider.dart';
|
||
|
||
class ParentDashboardScreen extends StatefulWidget {
|
||
const ParentDashboardScreen({Key? key}) : super(key: key);
|
||
|
||
@override
|
||
State<ParentDashboardScreen> createState() => _ParentDashboardScreenState();
|
||
}
|
||
|
||
class _ParentDashboardScreenState extends State<ParentDashboardScreen> {
|
||
int selectedIndex = 0;
|
||
AppUser? _user;
|
||
|
||
void onTabChange(int index) {
|
||
setState(() {
|
||
selectedIndex = index;
|
||
});
|
||
}
|
||
|
||
@override
|
||
void initState() {
|
||
super.initState();
|
||
_loadUser();
|
||
// Initialiser les données du dashboard
|
||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||
context.read<ParentDashboardController>().initDashboard();
|
||
});
|
||
}
|
||
|
||
Future<void> _loadUser() async {
|
||
final user = await AuthService.getCurrentUser();
|
||
if (mounted) setState(() => _user = user);
|
||
}
|
||
|
||
Widget _getBody() {
|
||
switch (selectedIndex) {
|
||
case 0:
|
||
return Dashbord_body();
|
||
case 1:
|
||
return const Center(child: Text("🔍 Trouver une nounou"));
|
||
case 2:
|
||
return const Center(child: Text("⚙️ Paramètres"));
|
||
default:
|
||
return const Center(child: Text("Page non trouvée"));
|
||
}
|
||
}
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
return ChangeNotifierProvider(
|
||
create: (context) => ParentDashboardController(DashboardService())..initDashboard(),
|
||
child: Scaffold(
|
||
appBar: PreferredSize(
|
||
preferredSize: const Size.fromHeight(60.0),
|
||
child: DashboardBandeau(
|
||
tabItems: const [
|
||
DashboardTabItem(label: 'Mon tableau de bord'),
|
||
DashboardTabItem(label: 'Trouver une nounou'),
|
||
DashboardTabItem(label: 'Paramètres'),
|
||
],
|
||
selectedTabIndex: selectedIndex,
|
||
onTabSelected: onTabChange,
|
||
userDisplayName: _user?.fullName.isNotEmpty == true
|
||
? _user!.fullName
|
||
: 'Parent',
|
||
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,
|
||
),
|
||
),
|
||
body: Column(
|
||
children: [
|
||
Expanded(child: _getBody()),
|
||
const AppFooter(),
|
||
],
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
Widget _buildResponsiveBody(BuildContext context, ParentDashboardController controller) {
|
||
return LayoutBuilder(
|
||
builder: (context, constraints) {
|
||
if (constraints.maxWidth < 768) {
|
||
// Layout mobile : colonnes empilées
|
||
return _buildMobileLayout(controller);
|
||
} else if (constraints.maxWidth < 1024) {
|
||
// Layout tablette : 2 colonnes
|
||
return _buildTabletLayout(controller);
|
||
} else {
|
||
// Layout desktop : 3 colonnes
|
||
return _buildDesktopLayout(controller);
|
||
}
|
||
},
|
||
);
|
||
}
|
||
|
||
Widget _buildDesktopLayout(ParentDashboardController controller) {
|
||
return Row(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
// Sidebar gauche - Enfants
|
||
SizedBox(
|
||
width: 280,
|
||
child: ChildrenSidebar(
|
||
children: controller.children,
|
||
selectedChildId: controller.selectedChildId,
|
||
onChildSelected: controller.selectChild,
|
||
onAddChild: controller.showAddChildModal,
|
||
),
|
||
),
|
||
|
||
// Contenu central
|
||
Expanded(
|
||
flex: 2,
|
||
child: MainContentArea(
|
||
selectedChild: controller.selectedChild,
|
||
selectedAssistant: controller.selectedAssistant,
|
||
events: controller.upcomingEvents,
|
||
contracts: controller.contracts,
|
||
),
|
||
),
|
||
|
||
// Sidebar droite - Messagerie
|
||
SizedBox(
|
||
width: 320,
|
||
child: MessagingSidebar(
|
||
conversations: controller.conversations,
|
||
notifications: controller.notifications,
|
||
),
|
||
),
|
||
],
|
||
);
|
||
}
|
||
|
||
Widget _buildTabletLayout(ParentDashboardController controller) {
|
||
return Row(
|
||
children: [
|
||
// Sidebar enfants plus étroite
|
||
SizedBox(
|
||
width: 240,
|
||
child: ChildrenSidebar(
|
||
children: controller.children,
|
||
selectedChildId: controller.selectedChildId,
|
||
onChildSelected: controller.selectChild,
|
||
onAddChild: controller.showAddChildModal,
|
||
isCompact: true,
|
||
),
|
||
),
|
||
|
||
// Contenu principal avec messagerie intégrée
|
||
Expanded(
|
||
child: Column(
|
||
children: [
|
||
Expanded(
|
||
flex: 2,
|
||
child: MainContentArea(
|
||
selectedChild: controller.selectedChild,
|
||
selectedAssistant: controller.selectedAssistant,
|
||
events: controller.upcomingEvents,
|
||
contracts: controller.contracts,
|
||
),
|
||
),
|
||
SizedBox(
|
||
height: 200,
|
||
child: MessagingSidebar(
|
||
conversations: controller.conversations,
|
||
notifications: controller.notifications,
|
||
isCompact: true,
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
],
|
||
);
|
||
}
|
||
|
||
Widget _buildMobileLayout(ParentDashboardController controller) {
|
||
return DefaultTabController(
|
||
length: 4,
|
||
child: Column(
|
||
children: [
|
||
// Navigation par onglets sur mobile
|
||
Container(
|
||
color: Theme.of(context).primaryColor.withOpacity(0.1),
|
||
child: const TabBar(
|
||
isScrollable: true,
|
||
tabs: [
|
||
Tab(text: 'Enfants', icon: Icon(Icons.child_care)),
|
||
Tab(text: 'Planning', icon: Icon(Icons.calendar_month)),
|
||
Tab(text: 'Contrats', icon: Icon(Icons.description)),
|
||
Tab(text: 'Messages', icon: Icon(Icons.message)),
|
||
],
|
||
),
|
||
),
|
||
|
||
Expanded(
|
||
child: TabBarView(
|
||
children: [
|
||
// Onglet Enfants
|
||
ChildrenSidebar(
|
||
children: controller.children,
|
||
selectedChildId: controller.selectedChildId,
|
||
onChildSelected: controller.selectChild,
|
||
onAddChild: controller.showAddChildModal,
|
||
isMobile: true,
|
||
),
|
||
|
||
// Onglet Planning
|
||
MainContentArea(
|
||
selectedChild: controller.selectedChild,
|
||
selectedAssistant: controller.selectedAssistant,
|
||
events: controller.upcomingEvents,
|
||
contracts: controller.contracts,
|
||
showOnlyCalendar: true,
|
||
),
|
||
|
||
// Onglet Contrats
|
||
MainContentArea(
|
||
selectedChild: controller.selectedChild,
|
||
selectedAssistant: controller.selectedAssistant,
|
||
events: controller.upcomingEvents,
|
||
contracts: controller.contracts,
|
||
showOnlyContracts: true,
|
||
),
|
||
|
||
// Onglet Messages
|
||
MessagingSidebar(
|
||
conversations: controller.conversations,
|
||
notifications: controller.notifications,
|
||
isMobile: true,
|
||
),
|
||
],
|
||
),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
} |