import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../network/api_client.dart'; import '../storage/token_storage.dart'; class AuthState { final bool authenticated; final int? userId; final String? name; const AuthState({ this.authenticated = false, this.userId, this.name, }); } final tokenStorageProvider = Provider((ref) => TokenStorage()); final apiClientProvider = Provider((ref) { final client = ApiClient(tokenStorage: ref.watch(tokenStorageProvider)); client.onUnauthorized = () { ref.read(authProvider.notifier).logout(); }; return client; }); class AuthNotifier extends AsyncNotifier { @override Future build() async { final storage = ref.watch(tokenStorageProvider); await storage.load(); return AuthState(authenticated: storage.hasToken); } Future login(String account, String password) async { state = const AsyncLoading(); try { final client = ref.read(apiClientProvider); final data = await client.post>('/user/login', { 'account': account, 'password': password, }); final token = data['token'] as String? ?? ''; final user = data['user'] as Map? ?? {}; await ref.read(tokenStorageProvider).save(token); state = AsyncData(AuthState( authenticated: true, userId: (user['id'] as num?)?.toInt(), name: user['name'] as String?, )); } catch (e) { state = AsyncError(e, StackTrace.current); } } Future logout() async { await ref.read(tokenStorageProvider).clear(); state = const AsyncData(AuthState()); } } final authProvider = AsyncNotifierProvider(AuthNotifier.new);