first app design
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import '../constants/app_constants.dart';
|
||||
import '../models/auth_models.dart';
|
||||
import '../services/auth_service.dart';
|
||||
import '../storage/token_storage.dart';
|
||||
|
||||
enum AuthStatus { unknown, authenticated, unauthenticated }
|
||||
|
||||
class AuthState {
|
||||
final AuthStatus status;
|
||||
final String? userType;
|
||||
final Employee? employee;
|
||||
final Renter? renter;
|
||||
|
||||
const AuthState({
|
||||
required this.status,
|
||||
this.userType,
|
||||
this.employee,
|
||||
this.renter,
|
||||
});
|
||||
|
||||
AuthState copyWith({
|
||||
AuthStatus? status,
|
||||
String? userType,
|
||||
Employee? employee,
|
||||
Renter? renter,
|
||||
}) =>
|
||||
AuthState(
|
||||
status: status ?? this.status,
|
||||
userType: userType ?? this.userType,
|
||||
employee: employee ?? this.employee,
|
||||
renter: renter ?? this.renter,
|
||||
);
|
||||
}
|
||||
|
||||
class AuthNotifier extends StateNotifier<AuthState> {
|
||||
final AuthService _service;
|
||||
|
||||
AuthNotifier(this._service)
|
||||
: super(const AuthState(status: AuthStatus.unknown));
|
||||
|
||||
Future<void> init() async {
|
||||
final token = await TokenStorage.getToken();
|
||||
final userType = await TokenStorage.getUserType();
|
||||
if (token == null || userType == null) {
|
||||
state = const AuthState(status: AuthStatus.unauthenticated);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (userType == AppConstants.userTypeEmployee) {
|
||||
final employee = await _service.getMe();
|
||||
state = AuthState(
|
||||
status: AuthStatus.authenticated,
|
||||
userType: userType,
|
||||
employee: employee,
|
||||
);
|
||||
} else {
|
||||
final renter = await _service.getRenterMe();
|
||||
state = AuthState(
|
||||
status: AuthStatus.authenticated,
|
||||
userType: userType,
|
||||
renter: renter,
|
||||
);
|
||||
}
|
||||
} catch (_) {
|
||||
await TokenStorage.clear();
|
||||
state = const AuthState(status: AuthStatus.unauthenticated);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> loginEmployee(String email, String password) async {
|
||||
final result = await _service.loginEmployee(email: email, password: password);
|
||||
await TokenStorage.saveToken(result.token);
|
||||
await TokenStorage.saveUserType(AppConstants.userTypeEmployee);
|
||||
state = AuthState(
|
||||
status: AuthStatus.authenticated,
|
||||
userType: AppConstants.userTypeEmployee,
|
||||
employee: result.employee,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> logout() async {
|
||||
await _service.logout();
|
||||
state = const AuthState(status: AuthStatus.unauthenticated);
|
||||
}
|
||||
}
|
||||
|
||||
final authServiceProvider = Provider((_) => AuthService());
|
||||
|
||||
final authProvider = StateNotifierProvider<AuthNotifier, AuthState>((ref) {
|
||||
return AuthNotifier(ref.read(authServiceProvider));
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
|
||||
const _localeKey = 'app_locale';
|
||||
|
||||
const _storage = FlutterSecureStorage(
|
||||
aOptions: AndroidOptions(encryptedSharedPreferences: true),
|
||||
);
|
||||
|
||||
class LocaleNotifier extends StateNotifier<Locale> {
|
||||
LocaleNotifier() : super(const Locale('en')) {
|
||||
_load();
|
||||
}
|
||||
|
||||
Future<void> _load() async {
|
||||
final code = await _storage.read(key: _localeKey);
|
||||
if (code != null) state = Locale(code);
|
||||
}
|
||||
|
||||
Future<void> setLocale(Locale locale) async {
|
||||
await _storage.write(key: _localeKey, value: locale.languageCode);
|
||||
state = locale;
|
||||
}
|
||||
}
|
||||
|
||||
final localeProvider = StateNotifierProvider<LocaleNotifier, Locale>(
|
||||
(_) => LocaleNotifier(),
|
||||
);
|
||||
@@ -0,0 +1,34 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
|
||||
const _themeKey = 'app_theme';
|
||||
|
||||
const _storage = FlutterSecureStorage(
|
||||
aOptions: AndroidOptions(encryptedSharedPreferences: true),
|
||||
);
|
||||
|
||||
class ThemeNotifier extends StateNotifier<ThemeMode> {
|
||||
ThemeNotifier() : super(ThemeMode.dark) {
|
||||
_load();
|
||||
}
|
||||
|
||||
Future<void> _load() async {
|
||||
final val = await _storage.read(key: _themeKey);
|
||||
if (val == 'light') state = ThemeMode.light;
|
||||
if (val == 'dark') state = ThemeMode.dark;
|
||||
}
|
||||
|
||||
Future<void> setMode(ThemeMode mode) async {
|
||||
await _storage.write(
|
||||
key: _themeKey, value: mode == ThemeMode.light ? 'light' : 'dark');
|
||||
state = mode;
|
||||
}
|
||||
|
||||
void toggle() =>
|
||||
setMode(state == ThemeMode.dark ? ThemeMode.light : ThemeMode.dark);
|
||||
}
|
||||
|
||||
final themeProvider = StateNotifierProvider<ThemeNotifier, ThemeMode>(
|
||||
(_) => ThemeNotifier(),
|
||||
);
|
||||
Reference in New Issue
Block a user