Initial Flutter scaffold: Riverpod + GoRouter + Dio

This commit is contained in:
2026-01-27 13:20:01 +00:00
commit c8ac4ec8bc
18 changed files with 2728 additions and 0 deletions

View File

@@ -0,0 +1,115 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../services/api_client.dart';
class AuthState {
final bool isAuthenticated;
final Map<String, dynamic>? user;
final bool isLoading;
final String? error;
const AuthState({
this.isAuthenticated = false,
this.user,
this.isLoading = false,
this.error,
});
AuthState copyWith({
bool? isAuthenticated,
Map<String, dynamic>? user,
bool? isLoading,
String? error,
}) {
return AuthState(
isAuthenticated: isAuthenticated ?? this.isAuthenticated,
user: user ?? this.user,
isLoading: isLoading ?? this.isLoading,
error: error,
);
}
}
class AuthNotifier extends StateNotifier<AsyncValue<AuthState>> {
final ApiClient _apiClient;
AuthNotifier(this._apiClient) : super(const AsyncValue.loading()) {
_checkSession();
}
Future<void> _checkSession() async {
try {
final session = await _apiClient.getSession();
if (session != null && session['user'] != null) {
state = AsyncValue.data(AuthState(
isAuthenticated: true,
user: session['user'],
));
} else {
state = const AsyncValue.data(AuthState(isAuthenticated: false));
}
} catch (e) {
state = const AsyncValue.data(AuthState(isAuthenticated: false));
}
}
Future<void> signUp({
required String email,
required String password,
required String name,
}) async {
state = const AsyncValue.loading();
try {
final result = await _apiClient.signUp(
email: email,
password: password,
name: name,
);
state = AsyncValue.data(AuthState(
isAuthenticated: true,
user: result['user'],
));
} catch (e) {
state = AsyncValue.data(AuthState(
isAuthenticated: false,
error: e.toString(),
));
rethrow;
}
}
Future<void> signIn({
required String email,
required String password,
}) async {
state = const AsyncValue.loading();
try {
final result = await _apiClient.signIn(
email: email,
password: password,
);
state = AsyncValue.data(AuthState(
isAuthenticated: true,
user: result['user'],
));
} catch (e) {
state = AsyncValue.data(AuthState(
isAuthenticated: false,
error: e.toString(),
));
rethrow;
}
}
Future<void> signOut() async {
try {
await _apiClient.signOut();
} finally {
state = const AsyncValue.data(AuthState(isAuthenticated: false));
}
}
}
final authStateProvider = StateNotifierProvider<AuthNotifier, AsyncValue<AuthState>>((ref) {
final apiClient = ref.watch(apiClientProvider);
return AuthNotifier(apiClient);
});