feat: add support for dynamic background and gradient colors in theme configuration

This commit is contained in:
Suherdy Yacob 2026-06-14 12:02:05 +07:00
parent 6ff44041f0
commit b2363b6c6b
4 changed files with 30 additions and 6 deletions

View File

@ -191,9 +191,9 @@ class _MainShellState extends State<MainShell> {
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
colorScheme.surfaceContainerLowest,
colorScheme.surface,
const Color(0xFFF3EAD3), // Warm traditional restaurant sand/cream
ThemeManager.instance.backgroundColor,
ThemeManager.instance.backgroundColor,
ThemeManager.instance.backgroundGradientColor,
],
),
),

View File

@ -116,11 +116,15 @@ class OdooService {
'brand_logo': (res['brand_logo'] as String?) ?? '',
'primary_color': (res['primary_color'] as String?) ?? '#C62828',
'secondary_color': (res['secondary_color'] as String?) ?? '#FF8F00',
'background_color': (res['background_color'] as String?) ?? '#FAF6EE',
'background_gradient_color': (res['background_gradient_color'] as String?) ?? '#F3EAD3',
};
// Save and apply new branding and theme colors dynamically
await ThemeManager.instance.updateConfig(
primaryHex: configMap['primary_color']!,
secondaryHex: configMap['secondary_color']!,
backgroundHex: configMap['background_color']!,
backgroundGradientHex: configMap['background_gradient_color']!,
brandLogoB64: configMap['brand_logo']!,
);
return configMap;

View File

@ -11,15 +11,20 @@ class ThemeManager extends ChangeNotifier {
Color _primaryColor = AppTheme.primary;
Color _secondaryColor = AppTheme.secondary;
Color _backgroundColor = AppTheme.surface;
Color _backgroundGradientColor = const Color(0xFFF3EAD3);
String _brandLogo = '';
Color get primaryColor => _primaryColor;
Color get secondaryColor => _secondaryColor;
Color get backgroundColor => _backgroundColor;
Color get backgroundGradientColor => _backgroundGradientColor;
String get brandLogo => _brandLogo;
ThemeData get themeData => AppTheme.getTheme(
primaryColor: _primaryColor,
secondaryColor: _secondaryColor,
backgroundColor: _backgroundColor,
);
/// Initialize cached settings on app launch
@ -27,6 +32,8 @@ class ThemeManager extends ChangeNotifier {
final prefs = await SharedPreferences.getInstance();
final primHex = prefs.getString('theme_primary_color');
final secHex = prefs.getString('theme_secondary_color');
final bgHex = prefs.getString('theme_background_color');
final bgGradHex = prefs.getString('theme_background_gradient_color');
_brandLogo = prefs.getString('theme_brand_logo') ?? '';
if (primHex != null) {
@ -35,21 +42,33 @@ class ThemeManager extends ChangeNotifier {
if (secHex != null) {
_secondaryColor = _parseHexColor(secHex) ?? AppTheme.secondary;
}
if (bgHex != null) {
_backgroundColor = _parseHexColor(bgHex) ?? AppTheme.surface;
}
if (bgGradHex != null) {
_backgroundGradientColor = _parseHexColor(bgGradHex) ?? const Color(0xFFF3EAD3);
}
}
/// Update theme options and persist them to SharedPreferences
Future<void> updateConfig({
required String primaryHex,
required String secondaryHex,
required String backgroundHex,
required String backgroundGradientHex,
required String brandLogoB64,
}) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString('theme_primary_color', primaryHex);
await prefs.setString('theme_secondary_color', secondaryHex);
await prefs.setString('theme_background_color', backgroundHex);
await prefs.setString('theme_background_gradient_color', backgroundGradientHex);
await prefs.setString('theme_brand_logo', brandLogoB64);
_primaryColor = _parseHexColor(primaryHex) ?? AppTheme.primary;
_secondaryColor = _parseHexColor(secondaryHex) ?? AppTheme.secondary;
_backgroundColor = _parseHexColor(backgroundHex) ?? AppTheme.surface;
_backgroundGradientColor = _parseHexColor(backgroundGradientHex) ?? const Color(0xFFF3EAD3);
_brandLogo = brandLogoB64;
notifyListeners();
}

View File

@ -25,10 +25,11 @@ class AppTheme {
static ThemeData get lightTheme => getTheme();
static ThemeData getTheme({Color? primaryColor, Color? secondaryColor}) {
static ThemeData getTheme({Color? primaryColor, Color? secondaryColor, Color? backgroundColor}) {
final baseTheme = ThemeData.light();
final pColor = primaryColor ?? primary;
final sColor = secondaryColor ?? secondary;
final bg = backgroundColor ?? surface;
// Dynamically compute readable contrast text colors
final onPrimaryColor = pColor.computeLuminance() > 0.5 ? Color(0xFF2E251B) : Colors.white;
@ -36,14 +37,14 @@ class AppTheme {
return ThemeData(
useMaterial3: true,
scaffoldBackgroundColor: surface,
scaffoldBackgroundColor: bg,
colorScheme: ColorScheme.light(
primary: pColor,
primaryContainer: pColor,
secondary: sColor,
secondaryContainer: sColor.withValues(alpha: 0.15),
onSecondaryContainer: onSecondaryColor,
surface: surface,
surface: bg,
onSurface: onSurface,
onSurfaceVariant: onSurfaceVariant,
onPrimary: onPrimaryColor,