feat: Implement email verification flow for user registration, update API base URL, and refine agent search screen UI.

This commit is contained in:
pradeepkumar
2026-03-16 15:32:17 +05:30
parent 9512f5ef8d
commit e195696733
5 changed files with 14 additions and 17 deletions

View File

@@ -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

View File

@@ -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(

View File

@@ -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;

View File

@@ -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,

View File

@@ -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),
), ),