Add mode switching and fix logout flow in settings

- Display current app mode in settings
- Add dialog to switch between local and online modes
- Fix logout to reset setup state and return to setup screen
This commit is contained in:
m3mo 2026-02-03 14:22:48 +01:00
parent 95ffc4d51d
commit 28c5380d31

View File

@ -4,6 +4,7 @@ import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import '../../../auth/presentation/viewmodels/auth_viewmodel.dart'; import '../../../auth/presentation/viewmodels/auth_viewmodel.dart';
import '../../domain/enums/app_mode.dart';
import '../viewmodels/settings_viewmodel.dart'; import '../viewmodels/settings_viewmodel.dart';
class SettingsPage extends StatelessWidget { class SettingsPage extends StatelessWidget {
@ -24,6 +25,21 @@ class SettingsPage extends StatelessWidget {
), ),
body: ListView( body: ListView(
children: [ children: [
_SectionHeader(title: l10n.appMode),
ListTile(
leading: Icon(
settingsVm.isLocalMode ? Icons.smartphone : Icons.cloud_sync,
),
title: Text(settingsVm.isLocalMode ? l10n.localMode : l10n.onlineMode),
subtitle: Text(
settingsVm.isLocalMode
? l10n.useLocallyDesc
: l10n.syncOnlineDesc,
),
trailing: const Icon(Icons.chevron_right),
onTap: () => _showModeSwitchDialog(context, settingsVm, l10n),
),
const Divider(),
_SectionHeader(title: l10n.general), _SectionHeader(title: l10n.general),
ListTile( ListTile(
leading: const Icon(Icons.language), leading: const Icon(Icons.language),
@ -48,6 +64,8 @@ class SettingsPage extends StatelessWidget {
title: Text(l10n.version), title: Text(l10n.version),
subtitle: const Text('1.0.0'), subtitle: const Text('1.0.0'),
), ),
// Only show logout button in online mode when authenticated
if (settingsVm.isOnlineMode) ...[
const Divider(), const Divider(),
const SizedBox(height: 16), const SizedBox(height: 16),
Padding( Padding(
@ -65,6 +83,7 @@ class SettingsPage extends StatelessWidget {
), ),
), ),
), ),
],
const SizedBox(height: 32), const SizedBox(height: 32),
], ],
), ),
@ -110,6 +129,79 @@ class SettingsPage extends StatelessWidget {
); );
} }
void _showModeSwitchDialog(
BuildContext context,
SettingsViewModel settingsVm,
AppLocalizations l10n,
) {
final isLocalMode = settingsVm.isLocalMode;
showDialog(
context: context,
builder: (dialogContext) => AlertDialog(
title: Text(isLocalMode ? l10n.switchToOnline : l10n.switchToLocal),
content: Text(l10n.switchModeWarning),
actions: [
TextButton(
onPressed: () => Navigator.pop(dialogContext),
child: Text(l10n.cancel),
),
FilledButton(
onPressed: () async {
Navigator.pop(dialogContext);
if (isLocalMode) {
// Switching from local to online
// First, ask if user wants to upload local tasks
final uploadTasks = await _showUploadTasksDialog(context, l10n);
if (uploadTasks == true) {
// TODO: Implement task upload to server after login
// For now, just switch mode and go to login
}
await settingsVm.setAppMode(AppMode.online);
if (context.mounted) {
context.go('/login');
}
} else {
// Switching from online to local
await context.read<AuthViewModel>().logout();
await settingsVm.setAppMode(AppMode.local);
if (context.mounted) {
context.go('/');
}
}
},
child: Text(isLocalMode ? l10n.switchToOnline : l10n.switchToLocal),
),
],
),
);
}
Future<bool?> _showUploadTasksDialog(
BuildContext context,
AppLocalizations l10n,
) async {
return showDialog<bool>(
context: context,
builder: (dialogContext) => AlertDialog(
title: Text(l10n.uploadTasksQuestion),
actions: [
TextButton(
onPressed: () => Navigator.pop(dialogContext, false),
child: Text(l10n.no),
),
FilledButton(
onPressed: () => Navigator.pop(dialogContext, true),
child: Text(l10n.yes),
),
],
),
);
}
void _showLogoutConfirmation(BuildContext context, AppLocalizations l10n) { void _showLogoutConfirmation(BuildContext context, AppLocalizations l10n) {
showDialog( showDialog(
context: context, context: context,
@ -122,9 +214,17 @@ class SettingsPage extends StatelessWidget {
child: Text(l10n.cancel), child: Text(l10n.cancel),
), ),
FilledButton( FilledButton(
onPressed: () { onPressed: () async {
final authVm = context.read<AuthViewModel>();
final settingsVm = context.read<SettingsViewModel>();
Navigator.pop(dialogContext); Navigator.pop(dialogContext);
context.read<AuthViewModel>().logout(); await authVm.logout();
// Reset setup so user returns to setup screen on next launch
await settingsVm.setSetupCompleted(false);
await settingsVm.setOnboardingShown(false);
if (context.mounted) {
context.go('/setup');
}
}, },
style: FilledButton.styleFrom( style: FilledButton.styleFrom(
backgroundColor: Theme.of(context).colorScheme.error, backgroundColor: Theme.of(context).colorScheme.error,