import 'package:cb_prestige_qr/app/navigation/main_shell.dart'; import 'package:cb_prestige_qr/features/auth/domain/entities/user_profile.dart'; import 'package:cb_prestige_qr/features/auth/presentation/views/login_view.dart'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import '../viewmodels/settings_ui_state.dart'; import '../viewmodels/settings_view_model.dart'; class SettingsView extends ConsumerWidget { const SettingsView({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final theme = Theme.of(context); final viewModel = ref.read(settingsViewModelProvider.notifier); final stateAsync = ref.watch(settingsViewModelProvider); return Scaffold( backgroundColor: theme.scaffoldBackgroundColor, appBar: AppBar( title: const Text('Settings'), backgroundColor: theme.scaffoldBackgroundColor, surfaceTintColor: theme.scaffoldBackgroundColor, elevation: 0, scrolledUnderElevation: 0, ), body: stateAsync.when( data: (state) => _SettingsBody( state: state, onNotificationsChanged: viewModel.toggleNotifications, onHapticsChanged: viewModel.toggleHaptics, onLogout: () { viewModel.logout().then((_) { if (!context.mounted) return; ref.read(navIndexProvider.notifier).setIndex(0); Navigator.of(context).pushAndRemoveUntil( MaterialPageRoute(builder: (_) => const LoginView()), (route) => false, ); }); }, ), loading: () => const Center(child: CircularProgressIndicator()), error: (error, stackTrace) => Center( child: TextButton( onPressed: () => ref.invalidate(settingsViewModelProvider), child: const Text('Retry'), ), ), ), ); } } class _SettingsBody extends StatelessWidget { const _SettingsBody({ required this.state, required this.onNotificationsChanged, required this.onHapticsChanged, required this.onLogout, }); final SettingsUiState state; final ValueChanged onNotificationsChanged; final ValueChanged onHapticsChanged; final VoidCallback onLogout; @override Widget build(BuildContext context) { return ListView( padding: const EdgeInsets.fromLTRB(16, 12, 16, 24), children: [ _ProfileCard(profile: state.userProfile), const SizedBox(height: 12), _SectionCard( title: 'Preferences', children: [ SwitchListTile.adaptive( value: state.notificationsEnabled, onChanged: onNotificationsChanged, title: const Text('Notifications'), subtitle: const Text('Get updates about scans'), ), const Divider(height: 1), SwitchListTile.adaptive( value: state.hapticsEnabled, onChanged: onHapticsChanged, title: const Text('Haptics'), subtitle: const Text('Vibration feedback'), ), ], ), const SizedBox(height: 12), _SectionCard( title: 'About', children: [ ListTile( title: const Text('Version'), subtitle: Text(state.appVersionLabel), ), ], ), const SizedBox(height: 12), _LogoutButton(onPressed: onLogout), ], ); } } class _ProfileCard extends StatelessWidget { const _ProfileCard({required this.profile}); final UserProfile profile; @override Widget build(BuildContext context) { final colorScheme = Theme.of(context).colorScheme; final textTheme = Theme.of(context).textTheme; return Container( decoration: BoxDecoration( color: colorScheme.surface, borderRadius: BorderRadius.circular(16), border: Border.all( color: colorScheme.outlineVariant.withValues(alpha: 0.5), ), boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: 0.06), blurRadius: 14, offset: const Offset(0, 6), ), ], ), child: Padding( padding: const EdgeInsets.all(16), child: Row( children: [ Container( width: 54, height: 54, decoration: BoxDecoration( color: colorScheme.primaryContainer, borderRadius: BorderRadius.circular(18), ), alignment: Alignment.center, child: Text( profile.initials, style: textTheme.titleLarge?.copyWith( color: colorScheme.onPrimaryContainer, fontWeight: FontWeight.w900, ), ), ), const SizedBox(width: 14), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( profile.displayName, maxLines: 1, overflow: TextOverflow.ellipsis, style: textTheme.titleMedium?.copyWith( fontWeight: FontWeight.w800, ), ), const SizedBox(height: 3), Text( '@${profile.username}', maxLines: 1, overflow: TextOverflow.ellipsis, style: textTheme.bodySmall?.copyWith( color: colorScheme.onSurfaceVariant, fontWeight: FontWeight.w600, ), ), const SizedBox(height: 10), Wrap( spacing: 8, runSpacing: 8, children: [ _ProfileChip( icon: Icons.badge_rounded, label: profile.roleLabel, ), _ProfileChip( icon: Icons.store_rounded, label: profile.branchLabel, ), ], ), ], ), ), ], ), ), ); } } class _ProfileChip extends StatelessWidget { const _ProfileChip({required this.icon, required this.label}); final IconData icon; final String label; @override Widget build(BuildContext context) { final colorScheme = Theme.of(context).colorScheme; final textTheme = Theme.of(context).textTheme; return Container( padding: const EdgeInsets.symmetric(horizontal: 9, vertical: 6), decoration: BoxDecoration( color: colorScheme.surfaceContainerHighest.withValues(alpha: 0.55), borderRadius: BorderRadius.circular(8), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon(icon, size: 15, color: colorScheme.onSurfaceVariant), const SizedBox(width: 5), Text( label, style: textTheme.labelMedium?.copyWith( color: colorScheme.onSurfaceVariant, fontWeight: FontWeight.w700, ), ), ], ), ); } } class _LogoutButton extends StatelessWidget { const _LogoutButton({required this.onPressed}); final VoidCallback onPressed; @override Widget build(BuildContext context) { final colorScheme = Theme.of(context).colorScheme; return SizedBox( width: double.infinity, child: FilledButton.icon( onPressed: onPressed, icon: const Icon(Icons.logout_rounded), label: const Text( 'Logout', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600), ), style: FilledButton.styleFrom( backgroundColor: colorScheme.primary, foregroundColor: colorScheme.onPrimary, padding: const EdgeInsets.symmetric(vertical: 16), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(18), ), ), ), ); } } class _SectionCard extends StatelessWidget { const _SectionCard({required this.title, required this.children}); final String title; final List children; @override Widget build(BuildContext context) { final colorScheme = Theme.of(context).colorScheme; return Container( decoration: BoxDecoration( color: colorScheme.surface, borderRadius: BorderRadius.circular(16), border: Border.all( color: colorScheme.outlineVariant.withValues(alpha: 0.5), ), boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: 0.06), blurRadius: 14, offset: const Offset(0, 6), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.fromLTRB(16, 14, 16, 8), child: Text( title, style: Theme.of( context, ).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.w700), ), ), ...children, ], ), ); } }