Files
unionflow-client-quarkus-pr…/unionflow-mobile-apps/lib/features/dashboard/presentation/widgets/dashboard_header.dart

360 lines
10 KiB
Dart

import 'package:flutter/material.dart';
import 'common/section_header.dart';
/// Widget d'en-tête principal du dashboard
///
/// Composant réutilisable pour l'en-tête des dashboards avec
/// informations système, statut et actions rapides.
class DashboardHeader extends StatelessWidget {
/// Titre principal du dashboard
final String title;
/// Sous-titre ou description
final String? subtitle;
/// Afficher les informations système
final bool showSystemInfo;
/// Afficher les actions rapides
final bool showQuickActions;
/// Callback pour les actions personnalisées
final List<DashboardAction>? actions;
/// Métriques système à afficher
final List<SystemMetric>? systemMetrics;
/// Style de l'en-tête
final DashboardHeaderStyle style;
const DashboardHeader({
super.key,
required this.title,
this.subtitle,
this.showSystemInfo = true,
this.showQuickActions = true,
this.actions,
this.systemMetrics,
this.style = DashboardHeaderStyle.gradient,
});
/// Constructeur pour un en-tête Super Admin
const DashboardHeader.superAdmin({
super.key,
this.actions,
}) : title = 'Administration Système',
subtitle = 'Surveillance et gestion globale',
showSystemInfo = true,
showQuickActions = true,
systemMetrics = null,
style = DashboardHeaderStyle.gradient;
/// Constructeur pour un en-tête Admin Organisation
const DashboardHeader.orgAdmin({
super.key,
this.actions,
}) : title = 'Administration Organisation',
subtitle = 'Gestion de votre organisation',
showSystemInfo = false,
showQuickActions = true,
systemMetrics = null,
style = DashboardHeaderStyle.gradient;
/// Constructeur pour un en-tête Membre
const DashboardHeader.member({
super.key,
this.actions,
}) : title = 'Tableau de bord',
subtitle = 'Bienvenue dans UnionFlow',
showSystemInfo = false,
showQuickActions = false,
systemMetrics = null,
style = DashboardHeaderStyle.simple;
@override
Widget build(BuildContext context) {
switch (style) {
case DashboardHeaderStyle.gradient:
return _buildGradientHeader();
case DashboardHeaderStyle.simple:
return _buildSimpleHeader();
case DashboardHeaderStyle.card:
return _buildCardHeader();
}
}
/// En-tête avec gradient (style principal)
Widget _buildGradientHeader() {
return Container(
margin: const EdgeInsets.all(12),
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
gradient: const LinearGradient(
colors: [Color(0xFF6C5CE7), Color(0xFF5A4FCF)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
borderRadius: BorderRadius.circular(16),
boxShadow: [
BoxShadow(
color: const Color(0xFF6C5CE7).withOpacity(0.3),
blurRadius: 20,
offset: const Offset(0, 8),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildHeaderContent(),
if (showSystemInfo && systemMetrics != null) ...[
const SizedBox(height: 16),
_buildSystemMetrics(),
],
if (showQuickActions && actions != null) ...[
const SizedBox(height: 16),
_buildQuickActions(),
],
],
),
);
}
/// En-tête simple sans fond
Widget _buildSimpleHeader() {
return Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SectionHeader.primary(
title: title,
subtitle: subtitle,
action: actions?.isNotEmpty == true ? _buildActionsRow() : null,
),
],
),
);
}
/// En-tête avec fond de carte
Widget _buildCardHeader() {
return Container(
margin: const EdgeInsets.all(12),
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 2),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildHeaderContent(isWhiteBackground: true),
if (showSystemInfo && systemMetrics != null) ...[
const SizedBox(height: 16),
_buildSystemMetrics(isWhiteBackground: true),
],
],
),
);
}
/// Contenu principal de l'en-tête
Widget _buildHeaderContent({bool isWhiteBackground = false}) {
final textColor = isWhiteBackground ? const Color(0xFF1F2937) : Colors.white;
final subtitleColor = isWhiteBackground ? Colors.grey[600] : Colors.white.withOpacity(0.8);
return Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
color: textColor,
),
),
if (subtitle != null) ...[
const SizedBox(height: 4),
Text(
subtitle!,
style: TextStyle(
fontSize: 16,
color: subtitleColor,
),
),
],
],
),
),
if (actions?.isNotEmpty == true) _buildActionsRow(isWhiteBackground: isWhiteBackground),
],
);
}
/// Métriques système
Widget _buildSystemMetrics({bool isWhiteBackground = false}) {
if (systemMetrics == null || systemMetrics!.isEmpty) {
return _buildDefaultSystemMetrics(isWhiteBackground: isWhiteBackground);
}
return Wrap(
spacing: 12,
runSpacing: 8,
children: systemMetrics!.map((metric) => _buildMetricChip(
metric.label,
metric.value,
metric.icon,
isWhiteBackground: isWhiteBackground,
)).toList(),
);
}
/// Métriques système par défaut
Widget _buildDefaultSystemMetrics({bool isWhiteBackground = false}) {
return Row(
children: [
Expanded(child: _buildMetricChip('Uptime', '99.97%', Icons.trending_up, isWhiteBackground: isWhiteBackground)),
const SizedBox(width: 12),
Expanded(child: _buildMetricChip('CPU', '23%', Icons.memory, isWhiteBackground: isWhiteBackground)),
const SizedBox(width: 12),
Expanded(child: _buildMetricChip('Users', '1,247', Icons.people, isWhiteBackground: isWhiteBackground)),
],
);
}
/// Chip de métrique
Widget _buildMetricChip(String label, String value, IconData icon, {bool isWhiteBackground = false}) {
final backgroundColor = isWhiteBackground
? const Color(0xFF6C5CE7).withOpacity(0.1)
: Colors.white.withOpacity(0.15);
final textColor = isWhiteBackground ? const Color(0xFF6C5CE7) : Colors.white;
return Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
decoration: BoxDecoration(
color: backgroundColor,
borderRadius: BorderRadius.circular(20),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(icon, color: textColor, size: 16),
const SizedBox(width: 6),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
value,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: textColor,
),
),
Text(
label,
style: TextStyle(
fontSize: 10,
color: textColor.withOpacity(0.8),
),
),
],
),
],
),
);
}
/// Actions rapides
Widget _buildQuickActions({bool isWhiteBackground = false}) {
if (actions == null || actions!.isEmpty) return const SizedBox.shrink();
return Row(
children: actions!.map((action) => Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: _buildActionButton(action, isWhiteBackground: isWhiteBackground),
),
)).toList(),
);
}
/// Ligne d'actions
Widget _buildActionsRow({bool isWhiteBackground = false}) {
if (actions == null || actions!.isEmpty) return const SizedBox.shrink();
return Row(
mainAxisSize: MainAxisSize.min,
children: actions!.map((action) => Padding(
padding: const EdgeInsets.only(left: 8),
child: _buildActionButton(action, isWhiteBackground: isWhiteBackground),
)).toList(),
);
}
/// Bouton d'action
Widget _buildActionButton(DashboardAction action, {bool isWhiteBackground = false}) {
final backgroundColor = isWhiteBackground
? Colors.white
: Colors.white.withOpacity(0.2);
final iconColor = isWhiteBackground ? const Color(0xFF6C5CE7) : Colors.white;
return Container(
decoration: BoxDecoration(
color: backgroundColor,
borderRadius: BorderRadius.circular(8),
),
child: IconButton(
onPressed: action.onPressed,
icon: Icon(action.icon, color: iconColor),
tooltip: action.tooltip,
),
);
}
}
/// Action du dashboard
class DashboardAction {
final IconData icon;
final String tooltip;
final VoidCallback onPressed;
const DashboardAction({
required this.icon,
required this.tooltip,
required this.onPressed,
});
}
/// Métrique système
class SystemMetric {
final String label;
final String value;
final IconData icon;
const SystemMetric({
required this.label,
required this.value,
required this.icon,
});
}
/// Styles d'en-tête de dashboard
enum DashboardHeaderStyle {
gradient,
simple,
card,
}