Maxiwere45 749314d312 refactor(system): extract system_page sub-widgets into separate files (<150 lines)
Move SystemHeader, SectionTitle, StatsGrid/StatItem and PalettePicker into
widgets/system/. system_page.dart 260 -> 80 lines.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 11:51:15 +02:00

64 lines
1.9 KiB
Dart

import 'package:flutter/material.dart';
/// Donnée d'une statistique affichée dans la grille.
class StatItem {
final String label;
final String value;
final IconData icon;
const StatItem({required this.label, required this.value, required this.icon});
}
/// Grille 2 colonnes de cartes de statistiques.
class StatsGrid extends StatelessWidget {
final Color primaryColor;
final List<StatItem> items;
const StatsGrid({super.key, required this.primaryColor, required this.items});
@override
Widget build(BuildContext context) {
return GridView.count(
crossAxisCount: 2,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
crossAxisSpacing: 12,
mainAxisSpacing: 12,
childAspectRatio: 1.4,
children: items.map((item) => _StatCard(item: item, color: primaryColor)).toList(),
);
}
}
class _StatCard extends StatelessWidget {
final StatItem item;
final Color color;
const _StatCard({required this.item, required this.color});
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
border: Border.all(color: color.withAlpha(80), width: 2),
boxShadow: [
BoxShadow(color: Colors.black.withAlpha(25), blurRadius: 4, offset: const Offset(0, 2)),
],
),
padding: const EdgeInsets.all(12),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(item.icon, color: color, size: 28),
const SizedBox(height: 6),
Text(item.value, style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold, color: color)),
Text(
item.label,
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 12, color: Colors.black54),
),
],
),
);
}
}