diff --git a/lib/core/storage/local_storage_service.dart b/lib/core/storage/local_storage_service.dart new file mode 100644 index 0000000..c14fce1 --- /dev/null +++ b/lib/core/storage/local_storage_service.dart @@ -0,0 +1,13 @@ +import 'package:shared_preferences/shared_preferences.dart'; + +class LocalStorageService { + Future setBool(String key, bool value) async{ + final prefs = await SharedPreferences.getInstance(); + await prefs.setBool(key, value); + } + + Future getBool(String key) async { + final prefs = await SharedPreferences.getInstance(); + return prefs.getBool(key); + } +} \ No newline at end of file diff --git a/lib/features/auth/data/fingerprint_repository.dart b/lib/features/auth/data/fingerprint_repository.dart new file mode 100644 index 0000000..4b37e39 --- /dev/null +++ b/lib/features/auth/data/fingerprint_repository.dart @@ -0,0 +1,16 @@ +import 'package:cb_prestige_qr/core/storage/local_storage_service.dart'; + +class FingerprintRepository { + final LocalStorageService storage; + FingerprintRepository(this.storage); + + static const key = "fingerprint_enabled"; + + Future load() async { + return await storage.getBool(key) ?? false; + } + + Future save(bool value) async { + await storage.setBool(key, value); + } +} \ No newline at end of file diff --git a/lib/features/auth/domain/fingerprint_state.dart b/lib/features/auth/domain/fingerprint_state.dart new file mode 100644 index 0000000..573f548 --- /dev/null +++ b/lib/features/auth/domain/fingerprint_state.dart @@ -0,0 +1,9 @@ +class FingerprintState { + final bool enabled; + + FingerprintState(this.enabled); + + FingerprintState copyWith({bool? enabled}){ + return FingerprintState(enabled ?? this.enabled); + } +} \ No newline at end of file diff --git a/lib/features/auth/presentation/providers/fingerprint_provider.dart b/lib/features/auth/presentation/providers/fingerprint_provider.dart new file mode 100644 index 0000000..f386518 --- /dev/null +++ b/lib/features/auth/presentation/providers/fingerprint_provider.dart @@ -0,0 +1,33 @@ +import 'package:cb_prestige_qr/core/storage/local_storage_service.dart'; +import 'package:cb_prestige_qr/features/auth/data/fingerprint_repository.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:hooks_riverpod/legacy.dart'; + + +final storageProvider = Provider((ref) => LocalStorageService()); + +final fingerprintRepoProvider = Provider((ref) { + return FingerprintRepository(ref.read(storageProvider)); +}); + +final fingerprintProvider = +StateNotifierProvider((ref) { + return FingerprintNotifier(ref.read(fingerprintRepoProvider)); +}); + +class FingerprintNotifier extends StateNotifier { + final FingerprintRepository repo; + + FingerprintNotifier(this.repo) : super(false) { + _init(); + } + + Future _init() async { + state = await repo.load(); + } + + Future toggle(bool value) async { + state = value; + await repo.save(value); + } +} \ No newline at end of file diff --git a/lib/features/settings/presentation/pages/settings_page.dart b/lib/features/settings/presentation/pages/settings_page.dart index 8001a51..f19a727 100644 --- a/lib/features/settings/presentation/pages/settings_page.dart +++ b/lib/features/settings/presentation/pages/settings_page.dart @@ -1,3 +1,5 @@ +import 'package:cb_prestige_qr/core/utils/MainShell.dart'; +import 'package:cb_prestige_qr/features/auth/presentation/pages/login_page.dart'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; @@ -28,6 +30,13 @@ class SettingsPage extends ConsumerWidget { onNotificationsChanged: viewModel.toggleNotifications, onHapticsChanged: viewModel.toggleHaptics, onFingerChanged: viewModel.toggleFinger, + onLogout: () { + ref.read(navIndexNotifierProvider.notifier).setIndex(0); + Navigator.of(context).pushAndRemoveUntil( + MaterialPageRoute(builder: (_) => const LoginPage()), + (route) => false, + ); + }, ), loading: () => const Center(child: CircularProgressIndicator()), error: (error, stackTrace) => Center( @@ -47,12 +56,14 @@ class _SettingsBody extends StatelessWidget { required this.onNotificationsChanged, required this.onHapticsChanged, required this.onFingerChanged, + required this.onLogout, }); final SettingsUiState state; final ValueChanged onNotificationsChanged; final ValueChanged onHapticsChanged; final ValueChanged onFingerChanged; + final VoidCallback onLogout; @override Widget build(BuildContext context) { @@ -94,6 +105,17 @@ class _SettingsBody extends StatelessWidget { ), ], ), + const SizedBox(height: 12), + FilledButton.icon( + onPressed: onLogout, + icon: const Icon(Icons.logout_rounded), + label: const Text('Logout'), + style: FilledButton.styleFrom( + backgroundColor: Theme.of(context).colorScheme.error, + foregroundColor: Theme.of(context).colorScheme.onError, + padding: const EdgeInsets.symmetric(vertical: 16), + ), + ), ], ); } diff --git a/pubspec.lock b/pubspec.lock index 2e0de45..03ac6bf 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -576,6 +576,30 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 + url: "https://pub.dev" + source: hosted + version: "2.2.1" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 + url: "https://pub.dev" + source: hosted + version: "2.3.0" petitparser: dependency: transitive description: @@ -584,6 +608,14 @@ packages: url: "https://pub.dev" source: hosted version: "7.0.2" + platform: + dependency: transitive + description: + name: platform + sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" + url: "https://pub.dev" + source: hosted + version: "3.1.6" plugin_platform_interface: dependency: transitive description: @@ -656,6 +688,62 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.3" + shared_preferences: + dependency: "direct main" + description: + name: shared_preferences + sha256: c3025c5534b01739267eb7d76959bbc25a6d10f6988e1c2a3036940133dd10bf + url: "https://pub.dev" + source: hosted + version: "2.5.5" + shared_preferences_android: + dependency: transitive + description: + name: shared_preferences_android + sha256: e8d4762b1e2e8578fc4d0fd548cebf24afd24f49719c08974df92834565e2c53 + url: "https://pub.dev" + source: hosted + version: "2.4.23" + shared_preferences_foundation: + dependency: transitive + description: + name: shared_preferences_foundation + sha256: "4e7eaffc2b17ba398759f1151415869a34771ba11ebbccd1b0145472a619a64f" + url: "https://pub.dev" + source: hosted + version: "2.5.6" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + sha256: "649dc798a33931919ea356c4305c2d1f81619ea6e92244070b520187b5140ef9" + url: "https://pub.dev" + source: hosted + version: "2.4.2" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019 + url: "https://pub.dev" + source: hosted + version: "2.4.3" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1" + url: "https://pub.dev" + source: hosted + version: "2.4.1" shelf: dependency: transitive description: @@ -893,6 +981,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.1" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" + url: "https://pub.dev" + source: hosted + version: "1.1.0" xml: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 446dce9..a6c4450 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -41,6 +41,7 @@ dependencies: carousel_slider: ^5.1.2 mobile_scanner: ^7.2.0 local_auth: ^3.0.1 + shared_preferences: ^2.5.5 dev_dependencies: flutter_test: