import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:worker/core/constants/ui_constants.dart'; import 'package:worker/core/theme/colors.dart'; import 'package:worker/core/theme/theme_provider.dart'; /// Theme Settings Page /// /// Allows user to customize app theme: /// - Select seed color from predefined options /// - Toggle light/dark mode class ThemeSettingsPage extends ConsumerWidget { const ThemeSettingsPage({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final settings = ref.watch(themeSettingsProvider); final colorScheme = Theme.of(context).colorScheme; return Scaffold( appBar: AppBar( title: const Text('Giao diện'), leading: IconButton( icon: const Icon(Icons.arrow_back), onPressed: () => Navigator.of(context).pop(), ), ), body: ListView( padding: const EdgeInsets.all(AppSpacing.md), children: [ // Color Selection Section _buildSectionTitle('Màu chủ đề'), const SizedBox(height: AppSpacing.sm), _buildColorGrid(context, ref, settings), const SizedBox(height: AppSpacing.lg), // Theme Mode Section _buildSectionTitle('Chế độ hiển thị'), const SizedBox(height: AppSpacing.sm), _buildThemeModeSelector(context, ref, settings, colorScheme), ], ), ); } Widget _buildSectionTitle(String title) { return Text( title, style: const TextStyle( fontSize: 16, fontWeight: FontWeight.w600, ), ); } Widget _buildColorGrid( BuildContext context, WidgetRef ref, ThemeSettings settings, ) { const options = AppColors.seedColorOptions; return Container( padding: const EdgeInsets.all(AppSpacing.md), decoration: BoxDecoration( color: Theme.of(context).colorScheme.surface, borderRadius: BorderRadius.circular(AppRadius.card), border: Border.all( color: Theme.of(context).colorScheme.outlineVariant, ), ), child: Column( children: [ GridView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 4, mainAxisSpacing: AppSpacing.md, crossAxisSpacing: AppSpacing.md, childAspectRatio: 1, ), itemCount: options.length, itemBuilder: (context, index) { final option = options[index]; final isSelected = option.id == settings.seedColorId; return _ColorOption( option: option, isSelected: isSelected, onTap: () { ref.read(themeSettingsProvider.notifier).setSeedColor(option.id); }, ); }, ), const SizedBox(height: AppSpacing.md), // Current color name Text( settings.seedColorOption.name, style: TextStyle( fontSize: 14, color: Theme.of(context).colorScheme.onSurfaceVariant, ), ), ], ), ); } Widget _buildThemeModeSelector( BuildContext context, WidgetRef ref, ThemeSettings settings, ColorScheme colorScheme, ) { return Container( decoration: BoxDecoration( color: colorScheme.surface, borderRadius: BorderRadius.circular(AppRadius.card), border: Border.all(color: colorScheme.outlineVariant), ), child: Column( children: [ _ThemeModeOption( icon: FontAwesomeIcons.mobile, title: 'Theo hệ thống', subtitle: 'Tự động theo cài đặt thiết bị', isSelected: settings.themeMode == ThemeMode.system, onTap: () { ref.read(themeSettingsProvider.notifier).setThemeMode(ThemeMode.system); }, ), Divider(height: 1, color: colorScheme.outlineVariant), _ThemeModeOption( icon: FontAwesomeIcons.sun, title: 'Sáng', subtitle: 'Luôn sử dụng giao diện sáng', isSelected: settings.themeMode == ThemeMode.light, onTap: () { ref.read(themeSettingsProvider.notifier).setThemeMode(ThemeMode.light); }, ), Divider(height: 1, color: colorScheme.outlineVariant), _ThemeModeOption( icon: FontAwesomeIcons.moon, title: 'Tối', subtitle: 'Luôn sử dụng giao diện tối', isSelected: settings.themeMode == ThemeMode.dark, onTap: () { ref.read(themeSettingsProvider.notifier).setThemeMode(ThemeMode.dark); }, ), ], ), ); } } /// Color option widget class _ColorOption extends StatelessWidget { const _ColorOption({ required this.option, required this.isSelected, required this.onTap, }); final SeedColorOption option; final bool isSelected; final VoidCallback onTap; @override Widget build(BuildContext context) { return GestureDetector( onTap: onTap, child: AnimatedContainer( duration: const Duration(milliseconds: 200), decoration: BoxDecoration( color: option.color, shape: BoxShape.circle, border: isSelected ? Border.all( color: Theme.of(context).colorScheme.onSurface, width: 3, ) : null, boxShadow: isSelected ? [ BoxShadow( color: option.color.withValues(alpha: 0.4), blurRadius: 8, spreadRadius: 2, ), ] : null, ), child: isSelected ? const Center( child: Icon( Icons.check, color: Colors.white, size: 24, ), ) : null, ), ); } } /// Theme mode option widget class _ThemeModeOption extends StatelessWidget { const _ThemeModeOption({ required this.icon, required this.title, required this.subtitle, required this.isSelected, required this.onTap, }); final IconData icon; final String title; final String subtitle; final bool isSelected; final VoidCallback onTap; @override Widget build(BuildContext context) { final colorScheme = Theme.of(context).colorScheme; return InkWell( onTap: onTap, child: Padding( padding: const EdgeInsets.all(AppSpacing.md), child: Row( children: [ FaIcon( icon, size: 20, color: isSelected ? colorScheme.primary : colorScheme.onSurfaceVariant, ), const SizedBox(width: AppSpacing.md), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, style: TextStyle( fontSize: 15, fontWeight: isSelected ? FontWeight.w600 : FontWeight.normal, color: colorScheme.onSurface, ), ), Text( subtitle, style: TextStyle( fontSize: 13, color: colorScheme.onSurfaceVariant, ), ), ], ), ), if (isSelected) Icon( Icons.check_circle, color: colorScheme.primary, size: 24, ), ], ), ), ); } }