Initial commit: unionflow-mobile-apps
Application Flutter complète (sans build artifacts). Signed-off-by: lions dev Team
This commit is contained in:
@@ -0,0 +1,260 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../../../../shared/design_system/unionflow_design_system.dart';
|
||||
|
||||
/// Carte de performance système réutilisable
|
||||
///
|
||||
/// Widget spécialisé pour afficher les métriques de performance
|
||||
/// avec barres de progression et indicateurs colorés.
|
||||
///
|
||||
/// REFACTORISÉ pour utiliser le Design System UnionFlow.
|
||||
class PerformanceCard extends StatelessWidget {
|
||||
/// Titre de la carte
|
||||
final String title;
|
||||
|
||||
/// Sous-titre optionnel
|
||||
final String? subtitle;
|
||||
|
||||
/// Liste des métriques de performance
|
||||
final List<PerformanceMetric> metrics;
|
||||
|
||||
/// Style de la carte
|
||||
final PerformanceCardStyle style;
|
||||
|
||||
/// Callback lors du tap sur la carte
|
||||
final VoidCallback? onTap;
|
||||
|
||||
/// Afficher ou non les valeurs numériques
|
||||
final bool showValues;
|
||||
|
||||
/// Afficher ou non les barres de progression
|
||||
final bool showProgressBars;
|
||||
|
||||
const PerformanceCard({
|
||||
super.key,
|
||||
required this.title,
|
||||
this.subtitle,
|
||||
required this.metrics,
|
||||
this.style = PerformanceCardStyle.elevated,
|
||||
this.onTap,
|
||||
this.showValues = true,
|
||||
this.showProgressBars = true,
|
||||
});
|
||||
|
||||
/// Constructeur pour les métriques serveur
|
||||
const PerformanceCard.server({
|
||||
super.key,
|
||||
this.onTap,
|
||||
}) : title = 'Performance Serveur',
|
||||
subtitle = 'Métriques temps réel',
|
||||
metrics = const [
|
||||
PerformanceMetric(
|
||||
label: 'CPU',
|
||||
value: 67.3,
|
||||
unit: '%',
|
||||
color: ColorTokens.warning,
|
||||
threshold: 80,
|
||||
),
|
||||
PerformanceMetric(
|
||||
label: 'RAM',
|
||||
value: 78.5,
|
||||
unit: '%',
|
||||
color: ColorTokens.info,
|
||||
threshold: 85,
|
||||
),
|
||||
PerformanceMetric(
|
||||
label: 'Disque',
|
||||
value: 45.2,
|
||||
unit: '%',
|
||||
color: ColorTokens.success,
|
||||
threshold: 90,
|
||||
),
|
||||
],
|
||||
style = PerformanceCardStyle.elevated,
|
||||
showValues = true,
|
||||
showProgressBars = true;
|
||||
|
||||
/// Constructeur pour les métriques réseau
|
||||
const PerformanceCard.network({
|
||||
super.key,
|
||||
this.onTap,
|
||||
}) : title = 'Performance Réseau',
|
||||
subtitle = 'Métriques temps réel',
|
||||
metrics = const [
|
||||
PerformanceMetric(
|
||||
label: 'Latence',
|
||||
value: 12.0,
|
||||
unit: 'ms',
|
||||
color: ColorTokens.success,
|
||||
threshold: 100.0,
|
||||
),
|
||||
PerformanceMetric(
|
||||
label: 'Débit',
|
||||
value: 85.0,
|
||||
unit: 'Mbps',
|
||||
color: ColorTokens.primary,
|
||||
threshold: 100.0,
|
||||
),
|
||||
PerformanceMetric(
|
||||
label: 'Paquets perdus',
|
||||
value: 0.2,
|
||||
unit: '%',
|
||||
color: ColorTokens.secondary,
|
||||
threshold: 5.0,
|
||||
),
|
||||
],
|
||||
style = PerformanceCardStyle.elevated,
|
||||
showValues = true,
|
||||
showProgressBars = true;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: onTap,
|
||||
child: UFCard(
|
||||
padding: const EdgeInsets.all(SpacingTokens.lg),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_buildHeader(),
|
||||
const SizedBox(height: SpacingTokens.lg),
|
||||
_buildMetrics(),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// En-tête de la carte
|
||||
Widget _buildHeader() {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: TypographyTokens.titleMedium.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: ColorTokens.primary,
|
||||
),
|
||||
),
|
||||
if (subtitle != null) ...[
|
||||
const SizedBox(height: SpacingTokens.xs),
|
||||
Text(
|
||||
subtitle!,
|
||||
style: TypographyTokens.bodySmall.copyWith(
|
||||
color: ColorTokens.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
/// Construction des métriques
|
||||
Widget _buildMetrics() {
|
||||
return Column(
|
||||
children: metrics.map((metric) => Padding(
|
||||
padding: const EdgeInsets.only(bottom: SpacingTokens.md),
|
||||
child: _buildMetricRow(metric),
|
||||
)).toList(),
|
||||
);
|
||||
}
|
||||
|
||||
/// Ligne de métrique
|
||||
Widget _buildMetricRow(PerformanceMetric metric) {
|
||||
final isWarning = metric.value > metric.threshold * 0.8;
|
||||
final isCritical = metric.value > metric.threshold;
|
||||
|
||||
Color effectiveColor = metric.color;
|
||||
if (isCritical) {
|
||||
effectiveColor = ColorTokens.error;
|
||||
} else if (isWarning) {
|
||||
effectiveColor = ColorTokens.warning;
|
||||
}
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 8,
|
||||
height: 8,
|
||||
decoration: BoxDecoration(
|
||||
color: effectiveColor,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: SpacingTokens.md),
|
||||
Text(
|
||||
metric.label,
|
||||
style: TypographyTokens.labelMedium.copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
if (showValues)
|
||||
Text(
|
||||
'${metric.value.toStringAsFixed(1)}${metric.unit}',
|
||||
style: TypographyTokens.labelMedium.copyWith(
|
||||
color: effectiveColor,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (showProgressBars) ...[
|
||||
const SizedBox(height: SpacingTokens.xs),
|
||||
_buildProgressBar(metric, effectiveColor),
|
||||
],
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
/// Barre de progression
|
||||
Widget _buildProgressBar(PerformanceMetric metric, Color color) {
|
||||
final progress = (metric.value / metric.threshold).clamp(0.0, 1.0);
|
||||
|
||||
return Container(
|
||||
height: 4,
|
||||
decoration: BoxDecoration(
|
||||
color: ColorTokens.surfaceVariant,
|
||||
borderRadius: BorderRadius.circular(SpacingTokens.radiusXs),
|
||||
),
|
||||
child: FractionallySizedBox(
|
||||
alignment: Alignment.centerLeft,
|
||||
widthFactor: progress,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: color,
|
||||
borderRadius: BorderRadius.circular(SpacingTokens.radiusXs),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// Modèle de données pour une métrique de performance
|
||||
class PerformanceMetric {
|
||||
final String label;
|
||||
final double value;
|
||||
final String unit;
|
||||
final Color color;
|
||||
final double threshold;
|
||||
|
||||
const PerformanceMetric({
|
||||
required this.label,
|
||||
required this.value,
|
||||
required this.unit,
|
||||
required this.color,
|
||||
required this.threshold,
|
||||
});
|
||||
}
|
||||
|
||||
/// Styles de carte de performance
|
||||
enum PerformanceCardStyle {
|
||||
elevated,
|
||||
outlined,
|
||||
minimal,
|
||||
}
|
||||
Reference in New Issue
Block a user