feat: Implement email verification flow for user registration, update API base URL, and refine agent search screen UI.
This commit is contained in:
2
.env.dev
2
.env.dev
@@ -1,3 +1,3 @@
|
|||||||
# Dev Environment Configuration
|
# Dev Environment Configuration
|
||||||
API_BASE_URL=http://144.91.78.96:3001/api/v1
|
API_BASE_URL=https://dev.re-quest.com/api/v1
|
||||||
STORAGE_BASE_URL=https://sin1.contabostorage.com/request
|
STORAGE_BASE_URL=https://sin1.contabostorage.com/request
|
||||||
|
|||||||
@@ -442,7 +442,6 @@ class _AgentCardState extends State<_AgentCard> {
|
|||||||
color: Color(0xFF638559),
|
color: Color(0xFF638559),
|
||||||
borderRadius: BorderRadius.only(
|
borderRadius: BorderRadius.only(
|
||||||
bottomLeft: Radius.circular(20),
|
bottomLeft: Radius.circular(20),
|
||||||
topRight: Radius.circular(20),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
|
|||||||
@@ -130,7 +130,9 @@ class AuthRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<UserModel> register(RegisterRequest request) async {
|
/// Register returns { message, user } — no tokens.
|
||||||
|
/// The user must verify their email before logging in.
|
||||||
|
Future<Map<String, dynamic>> register(RegisterRequest request) async {
|
||||||
try {
|
try {
|
||||||
final response = await _dio.post(
|
final response = await _dio.post(
|
||||||
ApiConstants.authRegister,
|
ApiConstants.authRegister,
|
||||||
@@ -138,14 +140,7 @@ class AuthRepository {
|
|||||||
);
|
);
|
||||||
|
|
||||||
final data = response.data['data'] as Map<String, dynamic>;
|
final data = response.data['data'] as Map<String, dynamic>;
|
||||||
final authResponse = AuthResponse.fromJson(data);
|
return data;
|
||||||
|
|
||||||
await SecureStorage.saveTokens(
|
|
||||||
accessToken: authResponse.accessToken,
|
|
||||||
refreshToken: authResponse.refreshToken,
|
|
||||||
);
|
|
||||||
|
|
||||||
return authResponse.user;
|
|
||||||
} on DioException catch (e) {
|
} on DioException catch (e) {
|
||||||
if (e.error is ApiException) {
|
if (e.error is ApiException) {
|
||||||
throw e.error as ApiException;
|
throw e.error as ApiException;
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ class AuthState {
|
|||||||
final bool requiresTwoFactor;
|
final bool requiresTwoFactor;
|
||||||
final String? tempToken;
|
final String? tempToken;
|
||||||
final String? twoFactorEmail;
|
final String? twoFactorEmail;
|
||||||
|
final bool registrationSuccess;
|
||||||
|
|
||||||
const AuthState({
|
const AuthState({
|
||||||
this.status = AuthStatus.initial,
|
this.status = AuthStatus.initial,
|
||||||
@@ -30,6 +31,7 @@ class AuthState {
|
|||||||
this.requiresTwoFactor = false,
|
this.requiresTwoFactor = false,
|
||||||
this.tempToken,
|
this.tempToken,
|
||||||
this.twoFactorEmail,
|
this.twoFactorEmail,
|
||||||
|
this.registrationSuccess = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
AuthState copyWith({
|
AuthState copyWith({
|
||||||
@@ -41,6 +43,7 @@ class AuthState {
|
|||||||
bool? requiresTwoFactor,
|
bool? requiresTwoFactor,
|
||||||
String? tempToken,
|
String? tempToken,
|
||||||
String? twoFactorEmail,
|
String? twoFactorEmail,
|
||||||
|
bool? registrationSuccess,
|
||||||
}) {
|
}) {
|
||||||
return AuthState(
|
return AuthState(
|
||||||
status: status ?? this.status,
|
status: status ?? this.status,
|
||||||
@@ -51,6 +54,7 @@ class AuthState {
|
|||||||
requiresTwoFactor: requiresTwoFactor ?? this.requiresTwoFactor,
|
requiresTwoFactor: requiresTwoFactor ?? this.requiresTwoFactor,
|
||||||
tempToken: tempToken ?? this.tempToken,
|
tempToken: tempToken ?? this.tempToken,
|
||||||
twoFactorEmail: twoFactorEmail ?? this.twoFactorEmail,
|
twoFactorEmail: twoFactorEmail ?? this.twoFactorEmail,
|
||||||
|
registrationSuccess: registrationSuccess ?? this.registrationSuccess,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,7 +186,7 @@ class AuthNotifier extends StateNotifier<AuthState> {
|
|||||||
final lastName = nameParts.length > 1 ? nameParts.sublist(1).join(' ') : null;
|
final lastName = nameParts.length > 1 ? nameParts.sublist(1).join(' ') : null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final user = await _repository.register(
|
await _repository.register(
|
||||||
RegisterRequest(
|
RegisterRequest(
|
||||||
email: email,
|
email: email,
|
||||||
password: password,
|
password: password,
|
||||||
@@ -193,13 +197,12 @@ class AuthNotifier extends StateNotifier<AuthState> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Registration successful — user must verify email before logging in
|
||||||
state = state.copyWith(
|
state = state.copyWith(
|
||||||
status: AuthStatus.authenticated,
|
status: AuthStatus.initial,
|
||||||
user: user,
|
|
||||||
registeredEmail: email,
|
registeredEmail: email,
|
||||||
|
registrationSuccess: true,
|
||||||
);
|
);
|
||||||
_connectSocket();
|
|
||||||
_initPushNotifications();
|
|
||||||
} on ApiException catch (e) {
|
} on ApiException catch (e) {
|
||||||
state = state.copyWith(
|
state = state.copyWith(
|
||||||
status: AuthStatus.error,
|
status: AuthStatus.error,
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ class _SignupScreenState extends ConsumerState<SignupScreen> {
|
|||||||
child: SafeArea(
|
child: SafeArea(
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||||
child: authState.status == AuthStatus.authenticated
|
child: authState.registrationSuccess
|
||||||
? _buildSuccessContent(authState)
|
? _buildSuccessContent(authState)
|
||||||
: _buildFormContent(authState),
|
: _buildFormContent(authState),
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user