petitspas/frontend/lib/widgets/dashbord_parent/children_sidebar.dart
Julien Martin 9cb4162165 feat: Intégration du frontend Flutter depuis YNOV
- Framework: Flutter web
- Pages: Login, inscription, dashboards
- Services: API client, authentification, gestion d'état
- Intégration avec backend NestJS
- Dockerfile pour déploiement web
2025-11-24 15:44:15 +01:00

203 lines
5.5 KiB
Dart

import 'package:flutter/material.dart';
import 'package:p_tits_pas/models/m_dashbord/child_model.dart';
class ChildrenSidebar extends StatelessWidget {
final List<ChildModel> children;
final String? selectedChildId;
final Function(String) onChildSelected;
final VoidCallback onAddChild;
final bool isCompact;
final bool isMobile;
const ChildrenSidebar({
Key? key,
required this.children,
this.selectedChildId,
required this.onChildSelected,
required this.onAddChild,
this.isCompact = false,
this.isMobile = false,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(isMobile ? 16 : 24),
color: Colors.white,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildHeader(context),
const SizedBox(height: 20),
_buildAddChildButton(context),
const SizedBox(height: 16),
Expanded(child: _buildChildrenList()),
],
),
);
}
Widget _buildHeader(BuildContext context) {
return Row(
children: [
// UserAvatar(
// size: isCompact ? 40 : 60,
// name: 'Emma Dupont', // TODO: Récupérer depuis le contexte utilisateur
// ),
if (!isCompact) ...[
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
Text(
'Emma Dupont',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
Icon(Icons.keyboard_arrow_down),
],
),
),
],
],
);
}
Widget _buildAddChildButton(BuildContext context) {
return SizedBox(
width: double.infinity,
child: OutlinedButton.icon(
onPressed: onAddChild,
icon: const Icon(Icons.add),
label: Text(isCompact ? 'Ajouter' : 'Ajouter un enfant'),
style: OutlinedButton.styleFrom(
padding: EdgeInsets.symmetric(
horizontal: 16,
vertical: isCompact ? 8 : 12,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
),
);
}
Widget _buildChildrenList() {
if (children.isEmpty) {
return const Center(
child: Text(
'Aucun enfant ajouté',
style: TextStyle(
color: Colors.grey,
fontSize: 14,
),
),
);
}
return ListView.separated(
itemCount: children.length,
separatorBuilder: (context, index) => const SizedBox(height: 12),
itemBuilder: (context, index) {
final child = children[index];
final isSelected = child.id == selectedChildId;
return _buildChildCard(context, child, isSelected);
},
);
}
Widget _buildChildCard(BuildContext context, ChildModel child, bool isSelected) {
return InkWell(
onTap: () => onChildSelected(child.id),
borderRadius: BorderRadius.circular(12),
child: Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: isSelected ? const Color(0xFF9CC5C0).withOpacity(0.1) : Colors.transparent,
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: isSelected ? const Color(0xFF9CC5C0) : Colors.grey.shade300,
width: isSelected ? 2 : 1,
),
),
child: Row(
children: [
// UserAvatar(
// // size: isCompact ? 32 : 40,
// // name: child.fullName,
// // imageUrl: child.photoUrl,
// ),
if (!isCompact) ...[
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
child.firstName,
style: TextStyle(
fontSize: 14,
fontWeight: isSelected ? FontWeight.w600 : FontWeight.w500,
),
),
const SizedBox(height: 4),
_buildChildStatus(child.status),
],
),
),
],
],
),
),
);
}
Widget _buildChildStatus(ChildStatus status) {
String label;
Color color;
switch (status) {
case ChildStatus.withAssistant:
label = 'En garde';
color = Colors.green;
break;
case ChildStatus.available:
label = 'Disponible';
color = Colors.blue;
break;
case ChildStatus.onHoliday:
label = 'En vacances';
color = Colors.orange;
break;
case ChildStatus.sick:
label = 'Malade';
color = Colors.red;
break;
case ChildStatus.searching:
label = 'Recherche AM';
color = Colors.purple;
break;
}
return Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
decoration: BoxDecoration(
color: color.withOpacity(0.1),
borderRadius: BorderRadius.circular(12),
),
child: Text(
label,
style: TextStyle(
fontSize: 11,
color: color,
fontWeight: FontWeight.w500,
),
),
);
}
}