feat: Implement the home screen with new UI components and assets, and refine authentication screens and routing.
This commit is contained in:
@@ -1,11 +1,12 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:real_estate_mobile/core/network/api_exceptions.dart';
|
||||
import 'package:real_estate_mobile/core/storage/secure_storage.dart';
|
||||
import 'package:real_estate_mobile/features/auth/data/auth_repository.dart';
|
||||
import 'package:real_estate_mobile/features/auth/data/models/register_request.dart';
|
||||
import 'package:real_estate_mobile/features/auth/data/models/user_model.dart';
|
||||
|
||||
// Auth state
|
||||
enum AuthStatus { initial, loading, success, error }
|
||||
enum AuthStatus { initial, loading, authenticated, error }
|
||||
|
||||
class AuthState {
|
||||
final AuthStatus status;
|
||||
@@ -49,7 +50,37 @@ class AuthState {
|
||||
class AuthNotifier extends StateNotifier<AuthState> {
|
||||
final AuthRepository _repository;
|
||||
|
||||
AuthNotifier(this._repository) : super(const AuthState());
|
||||
AuthNotifier(this._repository) : super(const AuthState()) {
|
||||
checkAuthStatus();
|
||||
}
|
||||
|
||||
Future<void> checkAuthStatus() async {
|
||||
final token = await SecureStorage.getAccessToken();
|
||||
if (token == null) {
|
||||
state = state.copyWith(status: AuthStatus.initial);
|
||||
return;
|
||||
}
|
||||
|
||||
state = state.copyWith(status: AuthStatus.loading);
|
||||
|
||||
try {
|
||||
final user = await _repository.getMe();
|
||||
state = state.copyWith(
|
||||
status: AuthStatus.authenticated,
|
||||
user: user,
|
||||
);
|
||||
} catch (_) {
|
||||
// Token is invalid/expired — clear and show login
|
||||
await SecureStorage.clearTokens();
|
||||
state = state.copyWith(status: AuthStatus.initial);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> logout() async {
|
||||
state = state.copyWith(status: AuthStatus.loading);
|
||||
await _repository.logout();
|
||||
state = const AuthState();
|
||||
}
|
||||
|
||||
Future<void> login({
|
||||
required String email,
|
||||
@@ -76,7 +107,7 @@ class AuthNotifier extends StateNotifier<AuthState> {
|
||||
}
|
||||
|
||||
state = state.copyWith(
|
||||
status: AuthStatus.success,
|
||||
status: AuthStatus.authenticated,
|
||||
user: result['user'] as UserModel,
|
||||
);
|
||||
} on ApiException catch (e) {
|
||||
@@ -124,7 +155,7 @@ class AuthNotifier extends StateNotifier<AuthState> {
|
||||
);
|
||||
|
||||
state = state.copyWith(
|
||||
status: AuthStatus.success,
|
||||
status: AuthStatus.authenticated,
|
||||
user: user,
|
||||
registeredEmail: email,
|
||||
);
|
||||
|
||||
@@ -16,7 +16,6 @@ class LoginScreen extends ConsumerStatefulWidget {
|
||||
}
|
||||
|
||||
class _LoginScreenState extends ConsumerState<LoginScreen> {
|
||||
final _nameController = TextEditingController();
|
||||
final _emailController = TextEditingController();
|
||||
final _passwordController = TextEditingController();
|
||||
String _selectedRole = 'USER';
|
||||
@@ -24,7 +23,6 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_nameController.dispose();
|
||||
_emailController.dispose();
|
||||
_passwordController.dispose();
|
||||
super.dispose();
|
||||
@@ -63,6 +61,8 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
|
||||
final authState = ref.watch(authProvider);
|
||||
final isLoading = authState.status == AuthStatus.loading;
|
||||
|
||||
// Router redirect handles navigation on auth state change
|
||||
|
||||
return Scaffold(
|
||||
body: Container(
|
||||
width: double.infinity,
|
||||
@@ -149,14 +149,6 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
|
||||
const SizedBox(height: 16),
|
||||
],
|
||||
|
||||
// Name field
|
||||
AuthTextField(
|
||||
hintText: 'Name',
|
||||
controller: _nameController,
|
||||
keyboardType: TextInputType.name,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// Email field
|
||||
AuthTextField(
|
||||
hintText: 'Email',
|
||||
|
||||
@@ -81,7 +81,7 @@ class _SignupScreenState extends ConsumerState<SignupScreen> {
|
||||
child: SafeArea(
|
||||
child: SingleChildScrollView(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
child: authState.status == AuthStatus.success
|
||||
child: authState.status == AuthStatus.authenticated
|
||||
? _buildSuccessContent(authState)
|
||||
: _buildFormContent(authState),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user