Refactoring - Version OK

This commit is contained in:
dahoud
2025-11-17 16:02:04 +00:00
parent 3f00a26308
commit 3b9ffac8cd
198 changed files with 18010 additions and 11383 deletions

View File

@@ -0,0 +1,509 @@
import 'package:flutter/material.dart';
import 'dart:async';
import '../../../../../shared/design_system/dashboard_theme.dart';
import '../../../data/services/dashboard_performance_monitor.dart';
/// Widget de monitoring des performances en temps réel
class PerformanceMonitorWidget extends StatefulWidget {
final bool showDetails;
final Duration updateInterval;
const PerformanceMonitorWidget({
super.key,
this.showDetails = false,
this.updateInterval = const Duration(seconds: 2),
});
@override
State<PerformanceMonitorWidget> createState() => _PerformanceMonitorWidgetState();
}
class _PerformanceMonitorWidgetState extends State<PerformanceMonitorWidget>
with TickerProviderStateMixin {
final DashboardPerformanceMonitor _monitor = DashboardPerformanceMonitor();
StreamSubscription<PerformanceMetrics>? _metricsSubscription;
StreamSubscription<PerformanceAlert>? _alertSubscription;
PerformanceMetrics? _currentMetrics;
final List<PerformanceAlert> _recentAlerts = [];
late AnimationController _pulseController;
late Animation<double> _pulseAnimation;
bool _isExpanded = false;
@override
void initState() {
super.initState();
_setupAnimations();
_startMonitoring();
}
void _setupAnimations() {
_pulseController = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
);
_pulseAnimation = Tween<double>(
begin: 0.8,
end: 1.0,
).animate(CurvedAnimation(
parent: _pulseController,
curve: Curves.easeInOut,
));
_pulseController.repeat(reverse: true);
}
Future<void> _startMonitoring() async {
await _monitor.startMonitoring();
_metricsSubscription = _monitor.metricsStream.listen((metrics) {
if (mounted) {
setState(() {
_currentMetrics = metrics;
});
}
});
_alertSubscription = _monitor.alertStream.listen((alert) {
if (mounted) {
setState(() {
_recentAlerts.insert(0, alert);
if (_recentAlerts.length > 5) {
_recentAlerts.removeLast();
}
});
// Afficher une notification pour les alertes critiques
if (alert.severity == AlertSeverity.error ||
alert.severity == AlertSeverity.critical) {
_showAlertSnackBar(alert);
}
}
});
}
void _showAlertSnackBar(PerformanceAlert alert) {
final color = _getAlertColor(alert.severity);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Row(
children: [
Icon(
_getAlertIcon(alert.type),
color: Colors.white,
size: 20,
),
const SizedBox(width: 8),
Expanded(
child: Text(
alert.message,
style: const TextStyle(color: Colors.white),
),
),
],
),
backgroundColor: color,
duration: const Duration(seconds: 4),
action: SnackBarAction(
label: 'Détails',
textColor: Colors.white,
onPressed: () {
setState(() {
_isExpanded = true;
});
},
),
),
);
}
@override
Widget build(BuildContext context) {
if (_currentMetrics == null) {
return _buildLoadingWidget();
}
return Container(
margin: const EdgeInsets.all(DashboardTheme.spacing8),
decoration: BoxDecoration(
color: DashboardTheme.white,
borderRadius: BorderRadius.circular(DashboardTheme.borderRadius),
boxShadow: DashboardTheme.subtleShadow,
),
child: Column(
children: [
_buildHeader(),
if (_isExpanded || widget.showDetails) ...[
const Divider(height: 1),
_buildDetailedMetrics(),
if (_recentAlerts.isNotEmpty) ...[
const Divider(height: 1),
_buildAlertsSection(),
],
],
],
),
);
}
Widget _buildLoadingWidget() {
return Container(
padding: const EdgeInsets.all(DashboardTheme.spacing16),
decoration: BoxDecoration(
color: DashboardTheme.white,
borderRadius: BorderRadius.circular(DashboardTheme.borderRadius),
boxShadow: DashboardTheme.subtleShadow,
),
child: const Row(
children: [
SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(
strokeWidth: 2,
valueColor: AlwaysStoppedAnimation<Color>(DashboardTheme.royalBlue),
),
),
SizedBox(width: DashboardTheme.spacing12),
Text(
'Initialisation du monitoring...',
style: DashboardTheme.bodyMedium,
),
],
),
);
}
Widget _buildHeader() {
return InkWell(
onTap: () {
setState(() {
_isExpanded = !_isExpanded;
});
},
borderRadius: BorderRadius.circular(DashboardTheme.borderRadius),
child: Padding(
padding: const EdgeInsets.all(DashboardTheme.spacing16),
child: Row(
children: [
AnimatedBuilder(
animation: _pulseAnimation,
builder: (context, child) {
return Transform.scale(
scale: _pulseAnimation.value,
child: Container(
width: 12,
height: 12,
decoration: BoxDecoration(
color: _getOverallHealthColor(),
shape: BoxShape.circle,
boxShadow: [
BoxShadow(
color: _getOverallHealthColor().withOpacity(0.5),
blurRadius: 4,
spreadRadius: 1,
),
],
),
),
);
},
),
const SizedBox(width: DashboardTheme.spacing12),
const Expanded(
child: Text(
'Performances Système',
style: DashboardTheme.titleSmall,
),
),
_buildQuickMetrics(),
const SizedBox(width: DashboardTheme.spacing8),
Icon(
_isExpanded ? Icons.expand_less : Icons.expand_more,
color: DashboardTheme.grey600,
),
],
),
),
);
}
Widget _buildQuickMetrics() {
return Row(
mainAxisSize: MainAxisSize.min,
children: [
_buildQuickMetric(
'MEM',
'${_currentMetrics!.memoryUsage.toStringAsFixed(0)}MB',
_getMetricColor(_currentMetrics!.memoryUsage, 400, 600),
),
const SizedBox(width: DashboardTheme.spacing8),
_buildQuickMetric(
'CPU',
'${_currentMetrics!.cpuUsage.toStringAsFixed(0)}%',
_getMetricColor(_currentMetrics!.cpuUsage, 50, 80),
),
const SizedBox(width: DashboardTheme.spacing8),
_buildQuickMetric(
'NET',
'${_currentMetrics!.networkLatency}ms',
_getMetricColor(_currentMetrics!.networkLatency.toDouble(), 200, 1000),
),
],
);
}
Widget _buildQuickMetric(String label, String value, Color color) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
label,
style: const TextStyle(
fontSize: 10,
color: DashboardTheme.grey600,
fontWeight: FontWeight.w500,
),
),
Text(
value,
style: TextStyle(
fontSize: 12,
color: color,
fontWeight: FontWeight.bold,
),
),
],
);
}
Widget _buildDetailedMetrics() {
return Padding(
padding: const EdgeInsets.all(DashboardTheme.spacing16),
child: Column(
children: [
_buildMetricRow(
'Mémoire',
'${_currentMetrics!.memoryUsage.toStringAsFixed(1)} MB',
_currentMetrics!.memoryUsage / 1000, // Normaliser sur 1000MB
_getMetricColor(_currentMetrics!.memoryUsage, 400, 600),
Icons.memory,
),
const SizedBox(height: DashboardTheme.spacing12),
_buildMetricRow(
'Processeur',
'${_currentMetrics!.cpuUsage.toStringAsFixed(1)}%',
_currentMetrics!.cpuUsage / 100,
_getMetricColor(_currentMetrics!.cpuUsage, 50, 80),
Icons.speed,
),
const SizedBox(height: DashboardTheme.spacing12),
_buildMetricRow(
'Réseau',
'${_currentMetrics!.networkLatency} ms',
(_currentMetrics!.networkLatency / 2000).clamp(0.0, 1.0),
_getMetricColor(_currentMetrics!.networkLatency.toDouble(), 200, 1000),
Icons.wifi,
),
const SizedBox(height: DashboardTheme.spacing12),
_buildMetricRow(
'Images/sec',
'${_currentMetrics!.frameRate.toStringAsFixed(1)} fps',
_currentMetrics!.frameRate / 60,
_getMetricColor(60 - _currentMetrics!.frameRate, 10, 30), // Inversé car plus c'est haut, mieux c'est
Icons.videocam,
),
const SizedBox(height: DashboardTheme.spacing12),
_buildMetricRow(
'Batterie',
'${_currentMetrics!.batteryLevel.toStringAsFixed(0)}%',
_currentMetrics!.batteryLevel / 100,
_getBatteryColor(_currentMetrics!.batteryLevel),
Icons.battery_std,
),
],
),
);
}
Widget _buildMetricRow(
String label,
String value,
double progress,
Color color,
IconData icon,
) {
return Row(
children: [
Icon(icon, size: 16, color: color),
const SizedBox(width: DashboardTheme.spacing8),
Expanded(
flex: 2,
child: Text(
label,
style: DashboardTheme.bodySmall,
),
),
Expanded(
flex: 3,
child: LinearProgressIndicator(
value: progress.clamp(0.0, 1.0),
backgroundColor: DashboardTheme.grey200,
valueColor: AlwaysStoppedAnimation<Color>(color),
),
),
const SizedBox(width: DashboardTheme.spacing8),
SizedBox(
width: 60,
child: Text(
value,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
color: color,
),
textAlign: TextAlign.end,
),
),
],
);
}
Widget _buildAlertsSection() {
return Padding(
padding: const EdgeInsets.all(DashboardTheme.spacing16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Alertes Récentes',
style: DashboardTheme.titleSmall,
),
const SizedBox(height: DashboardTheme.spacing8),
..._recentAlerts.take(3).map((alert) => _buildAlertItem(alert)),
],
),
);
}
Widget _buildAlertItem(PerformanceAlert alert) {
final color = _getAlertColor(alert.severity);
return Padding(
padding: const EdgeInsets.symmetric(vertical: 4),
child: Row(
children: [
Icon(
_getAlertIcon(alert.type),
size: 16,
color: color,
),
const SizedBox(width: DashboardTheme.spacing8),
Expanded(
child: Text(
alert.message,
style: const TextStyle(
fontSize: 12,
color: DashboardTheme.grey700,
),
),
),
Text(
_formatTime(alert.timestamp),
style: const TextStyle(
fontSize: 10,
color: DashboardTheme.grey500,
),
),
],
),
);
}
Color _getOverallHealthColor() {
if (_currentMetrics == null) return DashboardTheme.grey400;
final metrics = _currentMetrics!;
// Calculer un score de santé global
int issues = 0;
if (metrics.memoryUsage > 500) issues++;
if (metrics.cpuUsage > 70) issues++;
if (metrics.networkLatency > 1000) issues++;
if (metrics.frameRate < 30) issues++;
switch (issues) {
case 0:
return DashboardTheme.success;
case 1:
return DashboardTheme.warning;
default:
return DashboardTheme.error;
}
}
Color _getMetricColor(double value, double warningThreshold, double errorThreshold) {
if (value >= errorThreshold) return DashboardTheme.error;
if (value >= warningThreshold) return DashboardTheme.warning;
return DashboardTheme.success;
}
Color _getBatteryColor(double batteryLevel) {
if (batteryLevel <= 20) return DashboardTheme.error;
if (batteryLevel <= 50) return DashboardTheme.warning;
return DashboardTheme.success;
}
Color _getAlertColor(AlertSeverity severity) {
switch (severity) {
case AlertSeverity.info:
return DashboardTheme.info;
case AlertSeverity.warning:
return DashboardTheme.warning;
case AlertSeverity.error:
return DashboardTheme.error;
case AlertSeverity.critical:
return DashboardTheme.error;
}
}
IconData _getAlertIcon(AlertType type) {
switch (type) {
case AlertType.memory:
return Icons.memory;
case AlertType.cpu:
return Icons.speed;
case AlertType.network:
return Icons.wifi_off;
case AlertType.performance:
return Icons.slow_motion_video;
case AlertType.battery:
return Icons.battery_alert;
case AlertType.disk:
return Icons.storage;
}
}
String _formatTime(DateTime time) {
final now = DateTime.now();
final diff = now.difference(time);
if (diff.inMinutes < 1) return 'maintenant';
if (diff.inMinutes < 60) return '${diff.inMinutes}min';
if (diff.inHours < 24) return '${diff.inHours}h';
return '${diff.inDays}j';
}
@override
void dispose() {
_pulseController.dispose();
_metricsSubscription?.cancel();
_alertSubscription?.cancel();
_monitor.dispose();
super.dispose();
}
}