338 lines
10 KiB
Dart
338 lines
10 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
/// Gestionnaire de thèmes personnalisables pour le Dashboard
|
|
class DashboardThemeManager {
|
|
static const String _themeKey = 'dashboard_theme';
|
|
static DashboardThemeData _currentTheme = DashboardThemeData.royalTeal();
|
|
static SharedPreferences? _prefs;
|
|
|
|
/// Initialise le gestionnaire de thèmes
|
|
static Future<void> initialize() async {
|
|
_prefs = await SharedPreferences.getInstance();
|
|
await _loadSavedTheme();
|
|
}
|
|
|
|
/// Charge le thème sauvegardé
|
|
static Future<void> _loadSavedTheme() async {
|
|
final themeName = _prefs?.getString(_themeKey) ?? 'royalTeal';
|
|
_currentTheme = _getThemeByName(themeName);
|
|
}
|
|
|
|
/// Obtient le thème actuel
|
|
static DashboardThemeData get currentTheme => _currentTheme;
|
|
|
|
/// Change le thème et le sauvegarde
|
|
static Future<void> setTheme(String themeName) async {
|
|
_currentTheme = _getThemeByName(themeName);
|
|
await _prefs?.setString(_themeKey, themeName);
|
|
}
|
|
|
|
/// Obtient un thème par son nom
|
|
static DashboardThemeData _getThemeByName(String name) {
|
|
switch (name) {
|
|
case 'royalTeal':
|
|
return DashboardThemeData.royalTeal();
|
|
case 'oceanBlue':
|
|
return DashboardThemeData.oceanBlue();
|
|
case 'forestGreen':
|
|
return DashboardThemeData.forestGreen();
|
|
case 'sunsetOrange':
|
|
return DashboardThemeData.sunsetOrange();
|
|
case 'purpleNight':
|
|
return DashboardThemeData.purpleNight();
|
|
case 'darkMode':
|
|
return DashboardThemeData.darkMode();
|
|
default:
|
|
return DashboardThemeData.royalTeal();
|
|
}
|
|
}
|
|
|
|
/// Obtient la liste des thèmes disponibles
|
|
static List<ThemeOption> get availableThemes => [
|
|
ThemeOption('royalTeal', 'Bleu Roi & Pétrole', DashboardThemeData.royalTeal()),
|
|
ThemeOption('oceanBlue', 'Bleu Océan', DashboardThemeData.oceanBlue()),
|
|
ThemeOption('forestGreen', 'Vert Forêt', DashboardThemeData.forestGreen()),
|
|
ThemeOption('sunsetOrange', 'Orange Coucher', DashboardThemeData.sunsetOrange()),
|
|
ThemeOption('purpleNight', 'Violet Nuit', DashboardThemeData.purpleNight()),
|
|
ThemeOption('darkMode', 'Mode Sombre', DashboardThemeData.darkMode()),
|
|
];
|
|
}
|
|
|
|
/// Option de thème
|
|
class ThemeOption {
|
|
final String key;
|
|
final String name;
|
|
final DashboardThemeData theme;
|
|
|
|
const ThemeOption(this.key, this.name, this.theme);
|
|
}
|
|
|
|
/// Données d'un thème de dashboard
|
|
class DashboardThemeData {
|
|
final String name;
|
|
final Color primaryColor;
|
|
final Color secondaryColor;
|
|
final Color primaryLight;
|
|
final Color primaryDark;
|
|
final Color secondaryLight;
|
|
final Color secondaryDark;
|
|
final Color backgroundColor;
|
|
final Color surfaceColor;
|
|
final Color cardColor;
|
|
final Color textPrimary;
|
|
final Color textSecondary;
|
|
final Color success;
|
|
final Color warning;
|
|
final Color error;
|
|
final Color info;
|
|
final bool isDark;
|
|
|
|
const DashboardThemeData({
|
|
required this.name,
|
|
required this.primaryColor,
|
|
required this.secondaryColor,
|
|
required this.primaryLight,
|
|
required this.primaryDark,
|
|
required this.secondaryLight,
|
|
required this.secondaryDark,
|
|
required this.backgroundColor,
|
|
required this.surfaceColor,
|
|
required this.cardColor,
|
|
required this.textPrimary,
|
|
required this.textSecondary,
|
|
required this.success,
|
|
required this.warning,
|
|
required this.error,
|
|
required this.info,
|
|
this.isDark = false,
|
|
});
|
|
|
|
/// Thème Bleu Roi & Pétrole (par défaut)
|
|
factory DashboardThemeData.royalTeal() {
|
|
return const DashboardThemeData(
|
|
name: 'Bleu Roi & Pétrole',
|
|
primaryColor: Color(0xFF4169E1),
|
|
secondaryColor: Color(0xFF008B8B),
|
|
primaryLight: Color(0xFF6A8EF7),
|
|
primaryDark: Color(0xFF2E4BC6),
|
|
secondaryLight: Color(0xFF20B2AA),
|
|
secondaryDark: Color(0xFF006666),
|
|
backgroundColor: Color(0xFFF9FAFB),
|
|
surfaceColor: Color(0xFFFFFFFF),
|
|
cardColor: Color(0xFFFFFFFF),
|
|
textPrimary: Color(0xFF111827),
|
|
textSecondary: Color(0xFF6B7280),
|
|
success: Color(0xFF10B981),
|
|
warning: Color(0xFFF59E0B),
|
|
error: Color(0xFFEF4444),
|
|
info: Color(0xFF3B82F6),
|
|
);
|
|
}
|
|
|
|
/// Thème Bleu Océan
|
|
factory DashboardThemeData.oceanBlue() {
|
|
return const DashboardThemeData(
|
|
name: 'Bleu Océan',
|
|
primaryColor: Color(0xFF0EA5E9),
|
|
secondaryColor: Color(0xFF0284C7),
|
|
primaryLight: Color(0xFF38BDF8),
|
|
primaryDark: Color(0xFF0369A1),
|
|
secondaryLight: Color(0xFF0EA5E9),
|
|
secondaryDark: Color(0xFF075985),
|
|
backgroundColor: Color(0xFFF0F9FF),
|
|
surfaceColor: Color(0xFFFFFFFF),
|
|
cardColor: Color(0xFFFFFFFF),
|
|
textPrimary: Color(0xFF0C4A6E),
|
|
textSecondary: Color(0xFF64748B),
|
|
success: Color(0xFF059669),
|
|
warning: Color(0xFFD97706),
|
|
error: Color(0xFFDC2626),
|
|
info: Color(0xFF2563EB),
|
|
);
|
|
}
|
|
|
|
/// Thème Vert Forêt
|
|
factory DashboardThemeData.forestGreen() {
|
|
return const DashboardThemeData(
|
|
name: 'Vert Forêt',
|
|
primaryColor: Color(0xFF059669),
|
|
secondaryColor: Color(0xFF047857),
|
|
primaryLight: Color(0xFF10B981),
|
|
primaryDark: Color(0xFF065F46),
|
|
secondaryLight: Color(0xFF059669),
|
|
secondaryDark: Color(0xFF064E3B),
|
|
backgroundColor: Color(0xFFF0FDF4),
|
|
surfaceColor: Color(0xFFFFFFFF),
|
|
cardColor: Color(0xFFFFFFFF),
|
|
textPrimary: Color(0xFF064E3B),
|
|
textSecondary: Color(0xFF6B7280),
|
|
success: Color(0xFF10B981),
|
|
warning: Color(0xFFF59E0B),
|
|
error: Color(0xFFEF4444),
|
|
info: Color(0xFF3B82F6),
|
|
);
|
|
}
|
|
|
|
/// Thème Orange Coucher de Soleil
|
|
factory DashboardThemeData.sunsetOrange() {
|
|
return const DashboardThemeData(
|
|
name: 'Orange Coucher',
|
|
primaryColor: Color(0xFFEA580C),
|
|
secondaryColor: Color(0xFFDC2626),
|
|
primaryLight: Color(0xFFF97316),
|
|
primaryDark: Color(0xFFC2410C),
|
|
secondaryLight: Color(0xFFEF4444),
|
|
secondaryDark: Color(0xFFB91C1C),
|
|
backgroundColor: Color(0xFFFFF7ED),
|
|
surfaceColor: Color(0xFFFFFFFF),
|
|
cardColor: Color(0xFFFFFFFF),
|
|
textPrimary: Color(0xFF9A3412),
|
|
textSecondary: Color(0xFF78716C),
|
|
success: Color(0xFF059669),
|
|
warning: Color(0xFFF59E0B),
|
|
error: Color(0xFFDC2626),
|
|
info: Color(0xFF2563EB),
|
|
);
|
|
}
|
|
|
|
/// Thème Violet Nuit
|
|
factory DashboardThemeData.purpleNight() {
|
|
return const DashboardThemeData(
|
|
name: 'Violet Nuit',
|
|
primaryColor: Color(0xFF7C3AED),
|
|
secondaryColor: Color(0xFF9333EA),
|
|
primaryLight: Color(0xFF8B5CF6),
|
|
primaryDark: Color(0xFF5B21B6),
|
|
secondaryLight: Color(0xFFA855F7),
|
|
secondaryDark: Color(0xFF7E22CE),
|
|
backgroundColor: Color(0xFFFAF5FF),
|
|
surfaceColor: Color(0xFFFFFFFF),
|
|
cardColor: Color(0xFFFFFFFF),
|
|
textPrimary: Color(0xFF581C87),
|
|
textSecondary: Color(0xFF6B7280),
|
|
success: Color(0xFF059669),
|
|
warning: Color(0xFFF59E0B),
|
|
error: Color(0xFFEF4444),
|
|
info: Color(0xFF3B82F6),
|
|
);
|
|
}
|
|
|
|
/// Thème Mode Sombre
|
|
factory DashboardThemeData.darkMode() {
|
|
return const DashboardThemeData(
|
|
name: 'Mode Sombre',
|
|
primaryColor: Color(0xFF60A5FA),
|
|
secondaryColor: Color(0xFF34D399),
|
|
primaryLight: Color(0xFF93C5FD),
|
|
primaryDark: Color(0xFF3B82F6),
|
|
secondaryLight: Color(0xFF6EE7B7),
|
|
secondaryDark: Color(0xFF10B981),
|
|
backgroundColor: Color(0xFF111827),
|
|
surfaceColor: Color(0xFF1F2937),
|
|
cardColor: Color(0xFF374151),
|
|
textPrimary: Color(0xFFF9FAFB),
|
|
textSecondary: Color(0xFFD1D5DB),
|
|
success: Color(0xFF34D399),
|
|
warning: Color(0xFFFBBF24),
|
|
error: Color(0xFFF87171),
|
|
info: Color(0xFF60A5FA),
|
|
isDark: true,
|
|
);
|
|
}
|
|
|
|
/// Gradient primaire
|
|
LinearGradient get primaryGradient => LinearGradient(
|
|
colors: [primaryColor, secondaryColor],
|
|
begin: Alignment.topLeft,
|
|
end: Alignment.bottomRight,
|
|
);
|
|
|
|
/// Gradient de carte
|
|
LinearGradient get cardGradient => LinearGradient(
|
|
colors: [
|
|
cardColor,
|
|
isDark ? surfaceColor : const Color(0xFFF8FAFC),
|
|
],
|
|
begin: Alignment.topCenter,
|
|
end: Alignment.bottomCenter,
|
|
);
|
|
|
|
/// Gradient d'en-tête
|
|
LinearGradient get headerGradient => LinearGradient(
|
|
colors: [primaryColor, primaryDark],
|
|
begin: Alignment.topLeft,
|
|
end: Alignment.bottomRight,
|
|
);
|
|
|
|
/// Style de bouton primaire
|
|
ButtonStyle get primaryButtonStyle => ElevatedButton.styleFrom(
|
|
backgroundColor: primaryColor,
|
|
foregroundColor: isDark ? textPrimary : Colors.white,
|
|
elevation: 2,
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(8),
|
|
),
|
|
);
|
|
|
|
/// Style de bouton secondaire
|
|
ButtonStyle get secondaryButtonStyle => OutlinedButton.styleFrom(
|
|
foregroundColor: primaryColor,
|
|
side: BorderSide(color: primaryColor),
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(8),
|
|
),
|
|
);
|
|
|
|
/// Thème Flutter complet
|
|
ThemeData get flutterTheme => ThemeData(
|
|
useMaterial3: true,
|
|
brightness: isDark ? Brightness.dark : Brightness.light,
|
|
primaryColor: primaryColor,
|
|
colorScheme: ColorScheme.fromSeed(
|
|
seedColor: primaryColor,
|
|
brightness: isDark ? Brightness.dark : Brightness.light,
|
|
secondary: secondaryColor,
|
|
surface: surfaceColor,
|
|
background: backgroundColor,
|
|
),
|
|
scaffoldBackgroundColor: backgroundColor,
|
|
cardColor: cardColor,
|
|
appBarTheme: AppBarTheme(
|
|
backgroundColor: primaryColor,
|
|
foregroundColor: isDark ? textPrimary : Colors.white,
|
|
elevation: 0,
|
|
centerTitle: true,
|
|
),
|
|
elevatedButtonTheme: ElevatedButtonThemeData(style: primaryButtonStyle),
|
|
outlinedButtonTheme: OutlinedButtonThemeData(style: secondaryButtonStyle),
|
|
cardTheme: CardTheme(
|
|
color: cardColor,
|
|
elevation: 2,
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(8),
|
|
),
|
|
),
|
|
textTheme: TextTheme(
|
|
displayLarge: TextStyle(
|
|
fontSize: 24,
|
|
fontWeight: FontWeight.bold,
|
|
color: textPrimary,
|
|
),
|
|
displayMedium: TextStyle(
|
|
fontSize: 20,
|
|
fontWeight: FontWeight.w600,
|
|
color: textPrimary,
|
|
),
|
|
bodyLarge: TextStyle(
|
|
fontSize: 16,
|
|
color: textPrimary,
|
|
),
|
|
bodyMedium: TextStyle(
|
|
fontSize: 14,
|
|
color: textSecondary,
|
|
),
|
|
),
|
|
);
|
|
}
|