feat: auth done

This commit is contained in:
jahongireshonqulov
2025-10-30 14:41:55 +05:00
parent f47e78a9a2
commit ab1ac6e6fa
26 changed files with 1702 additions and 195 deletions

View File

@@ -30,6 +30,10 @@ import '../../feature/auth/domain/usecases/verify_phone_register_usecase.dart'
as _i664;
import '../../feature/auth/presentation/blocs/login_bloc/login_bloc.dart'
as _i1065;
import '../../feature/auth/presentation/blocs/register_bloc/register_bloc.dart'
as _i1050;
import '../../feature/auth/presentation/blocs/reset_password_bloc/reset_password_bloc.dart'
as _i97;
import '../../feature/auth/presentation/blocs/verify_otp_bloc/verify_otp_bloc.dart'
as _i323;
import '../../feature/auth/presentation/blocs/verify_phone_bloc/verify_phone_bloc.dart'
@@ -119,6 +123,12 @@ extension GetItInjectableX on _i174.GetIt {
gh<_i664.VerifyPhoneRegisterUseCase>(),
),
);
gh.factory<_i1050.RegisterBloc>(
() => _i1050.RegisterBloc(gh<_i607.RegisterUseCase>()),
);
gh.factory<_i97.ResetPasswordBloc>(
() => _i97.ResetPasswordBloc(gh<_i694.ResetPasswordUseCase>()),
);
gh.factory<_i1065.LoginBloc>(
() => _i1065.LoginBloc(
gh<_i241.LoginUseCase>(),

View File

@@ -19,10 +19,31 @@ abstract class Validators {
return null;
}
static String? validateRepeatPassword(
String repeatPassword,
String password,
) {
if (repeatPassword.isEmpty) {
return navigatorKey.currentContext?.loc.field_cannot_be_empty;
} else if (repeatPassword != password) {
return navigatorKey.currentContext?.loc.passwords_do_not_match;
}
return null;
}
static String? validateFields(String value) {
if (value.isEmpty) {
return navigatorKey.currentContext?.loc.field_cannot_be_empty;
}
return null;
}
static String? validateOtpFields(String value) {
if (value.isEmpty) {
return navigatorKey.currentContext?.loc.field_cannot_be_empty;
} else if (value.length < 5) {
return navigatorKey.currentContext?.loc.otp_code_incomplete;
}
return null;
}
}

View File

@@ -867,6 +867,42 @@ abstract class AppLocalizations {
/// In en, this message translates to:
/// **'By proceeding, you consent to get calls or SMS messages, including by automated means, from {appName} and its affiliates to the number provided.'**
String consent_message(String appName);
/// No description provided for @otp_code_incomplete.
///
/// In en, this message translates to:
/// **'Code is incomplete. Please enter the full code.'**
String get otp_code_incomplete;
/// No description provided for @passwords_do_not_match.
///
/// In en, this message translates to:
/// **'Passwords do not match.'**
String get passwords_do_not_match;
/// No description provided for @reset_password.
///
/// In en, this message translates to:
/// **'Reset password'**
String get reset_password;
/// No description provided for @new_password.
///
/// In en, this message translates to:
/// **'New password'**
String get new_password;
/// No description provided for @enter_otp_code.
///
/// In en, this message translates to:
/// **'Enter the 5-digit code sent to you at {phoneNumber}'**
String enter_otp_code(String phoneNumber);
/// No description provided for @resend_otp_after.
///
/// In en, this message translates to:
/// **'You can resend OTP after'**
String get resend_otp_after;
}
class _AppLocalizationsDelegate

View File

@@ -406,4 +406,25 @@ class AppLocalizationsEn extends AppLocalizations {
String consent_message(String appName) {
return 'By proceeding, you consent to get calls or SMS messages, including by automated means, from $appName and its affiliates to the number provided.';
}
@override
String get otp_code_incomplete =>
'Code is incomplete. Please enter the full code.';
@override
String get passwords_do_not_match => 'Passwords do not match.';
@override
String get reset_password => 'Reset password';
@override
String get new_password => 'New password';
@override
String enter_otp_code(String phoneNumber) {
return 'Enter the 5-digit code sent to you at $phoneNumber';
}
@override
String get resend_otp_after => 'You can resend OTP after';
}

View File

@@ -406,4 +406,25 @@ class AppLocalizationsRu extends AppLocalizations {
String consent_message(String appName) {
return 'Продолжая, вы соглашаетесь получать звонки или SMS-сообщения, включая автоматические, от $appName и его партнёров на указанный номер.';
}
@override
String get otp_code_incomplete =>
'Код неполный. Пожалуйста, введите полный код.';
@override
String get passwords_do_not_match => 'Пароли не совпадают.';
@override
String get reset_password => 'Восстановить пароль';
@override
String get new_password => 'Новый пароль';
@override
String enter_otp_code(String phoneNumber) {
return 'Введите 5-значный код, отправленный на номер $phoneNumber';
}
@override
String get resend_otp_after => 'Вы можете повторно отправить код через';
}

View File

@@ -407,4 +407,25 @@ class AppLocalizationsUz extends AppLocalizations {
String consent_message(String appName) {
return 'Davom etish orqali siz $appName va uning hamkorlaridan siz kiritgan raqamga, shu jumladan avtomatik vositalar orqali, qongiroqlar yoki SMS xabarlar olishingizga rozilik bildirasiz.';
}
@override
String get otp_code_incomplete =>
'Kod yetarli emas. Iltimos, toliq kodni kiriting.';
@override
String get passwords_do_not_match => 'Parollar mos kelmadi.';
@override
String get reset_password => 'Parolni qayta tiklash';
@override
String get new_password => 'Yangi parol';
@override
String enter_otp_code(String phoneNumber) {
return '$phoneNumber raqamiga yuborilgan 5 xonali kodni kiriting';
}
@override
String get resend_otp_after => 'OTP kodni qayta yuborish mumkin boladi';
}

View File

@@ -19,7 +19,7 @@ class VerifyOtpCodeForgotPasswordUseCase
}
class VerifyOtpCodeParams {
final String otpCode;
final dynamic otpCode;
final String phoneNumber;
VerifyOtpCodeParams({required this.otpCode, required this.phoneNumber});

View File

@@ -0,0 +1,35 @@
import 'package:food_delivery_client/feature/auth/domain/usecases/register_usecase.dart';
import 'package:food_delivery_client/feature/common/presentation/widgets/w_toastification.dart';
import 'package:food_delivery_client/food_delivery_client.dart';
part 'register_event.dart';
part 'register_state.dart';
part 'register_bloc.freezed.dart';
@injectable
class RegisterBloc extends Bloc<RegisterEvent, RegisterState> {
final RegisterUseCase _registerUseCase;
RegisterBloc(this._registerUseCase) : super(const RegisterState()) {
on<_Loaded>(_onLoaded);
}
Future<void> _onLoaded(_Loaded event, Emitter<RegisterState> emit) async {
emit(state.copyWith(status: RequestStatus.loading));
final response = await _registerUseCase.call(event.params);
response.fold(
(l) {
showErrorToast(l.errorMessage);
emit(state.copyWith(status: RequestStatus.error));
},
(r) {
showSuccessToast(r.message);
emit(state.copyWith(status: RequestStatus.loaded));
},
);
}
}

View File

@@ -0,0 +1,535 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// coverage:ignore-file
// ignore_for_file: type=lint
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
part of 'register_bloc.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$RegisterEvent {
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is RegisterEvent);
}
@override
int get hashCode => runtimeType.hashCode;
@override
String toString() {
return 'RegisterEvent()';
}
}
/// @nodoc
class $RegisterEventCopyWith<$Res> {
$RegisterEventCopyWith(RegisterEvent _, $Res Function(RegisterEvent) __);
}
/// Adds pattern-matching-related methods to [RegisterEvent].
extension RegisterEventPatterns on RegisterEvent {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>({TResult Function( _Started value)? started,TResult Function( _Loaded value)? loaded,required TResult orElse(),}){
final _that = this;
switch (_that) {
case _Started() when started != null:
return started(_that);case _Loaded() when loaded != null:
return loaded(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>({required TResult Function( _Started value) started,required TResult Function( _Loaded value) loaded,}){
final _that = this;
switch (_that) {
case _Started():
return started(_that);case _Loaded():
return loaded(_that);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>({TResult? Function( _Started value)? started,TResult? Function( _Loaded value)? loaded,}){
final _that = this;
switch (_that) {
case _Started() when started != null:
return started(_that);case _Loaded() when loaded != null:
return loaded(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>({TResult Function()? started,TResult Function( RegisterParams params)? loaded,required TResult orElse(),}) {final _that = this;
switch (_that) {
case _Started() when started != null:
return started();case _Loaded() when loaded != null:
return loaded(_that.params);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>({required TResult Function() started,required TResult Function( RegisterParams params) loaded,}) {final _that = this;
switch (_that) {
case _Started():
return started();case _Loaded():
return loaded(_that.params);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>({TResult? Function()? started,TResult? Function( RegisterParams params)? loaded,}) {final _that = this;
switch (_that) {
case _Started() when started != null:
return started();case _Loaded() when loaded != null:
return loaded(_that.params);case _:
return null;
}
}
}
/// @nodoc
class _Started implements RegisterEvent {
const _Started();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _Started);
}
@override
int get hashCode => runtimeType.hashCode;
@override
String toString() {
return 'RegisterEvent.started()';
}
}
/// @nodoc
class _Loaded implements RegisterEvent {
const _Loaded(this.params);
final RegisterParams params;
/// Create a copy of RegisterEvent
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$LoadedCopyWith<_Loaded> get copyWith => __$LoadedCopyWithImpl<_Loaded>(this, _$identity);
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _Loaded&&(identical(other.params, params) || other.params == params));
}
@override
int get hashCode => Object.hash(runtimeType,params);
@override
String toString() {
return 'RegisterEvent.loaded(params: $params)';
}
}
/// @nodoc
abstract mixin class _$LoadedCopyWith<$Res> implements $RegisterEventCopyWith<$Res> {
factory _$LoadedCopyWith(_Loaded value, $Res Function(_Loaded) _then) = __$LoadedCopyWithImpl;
@useResult
$Res call({
RegisterParams params
});
}
/// @nodoc
class __$LoadedCopyWithImpl<$Res>
implements _$LoadedCopyWith<$Res> {
__$LoadedCopyWithImpl(this._self, this._then);
final _Loaded _self;
final $Res Function(_Loaded) _then;
/// Create a copy of RegisterEvent
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') $Res call({Object? params = null,}) {
return _then(_Loaded(
null == params ? _self.params : params // ignore: cast_nullable_to_non_nullable
as RegisterParams,
));
}
}
/// @nodoc
mixin _$RegisterState {
RequestStatus get status;
/// Create a copy of RegisterState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$RegisterStateCopyWith<RegisterState> get copyWith => _$RegisterStateCopyWithImpl<RegisterState>(this as RegisterState, _$identity);
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is RegisterState&&(identical(other.status, status) || other.status == status));
}
@override
int get hashCode => Object.hash(runtimeType,status);
@override
String toString() {
return 'RegisterState(status: $status)';
}
}
/// @nodoc
abstract mixin class $RegisterStateCopyWith<$Res> {
factory $RegisterStateCopyWith(RegisterState value, $Res Function(RegisterState) _then) = _$RegisterStateCopyWithImpl;
@useResult
$Res call({
RequestStatus status
});
}
/// @nodoc
class _$RegisterStateCopyWithImpl<$Res>
implements $RegisterStateCopyWith<$Res> {
_$RegisterStateCopyWithImpl(this._self, this._then);
final RegisterState _self;
final $Res Function(RegisterState) _then;
/// Create a copy of RegisterState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? status = null,}) {
return _then(_self.copyWith(
status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable
as RequestStatus,
));
}
}
/// Adds pattern-matching-related methods to [RegisterState].
extension RegisterStatePatterns on RegisterState {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _RegisterState value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _RegisterState() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _RegisterState value) $default,){
final _that = this;
switch (_that) {
case _RegisterState():
return $default(_that);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _RegisterState value)? $default,){
final _that = this;
switch (_that) {
case _RegisterState() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( RequestStatus status)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _RegisterState() when $default != null:
return $default(_that.status);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( RequestStatus status) $default,) {final _that = this;
switch (_that) {
case _RegisterState():
return $default(_that.status);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( RequestStatus status)? $default,) {final _that = this;
switch (_that) {
case _RegisterState() when $default != null:
return $default(_that.status);case _:
return null;
}
}
}
/// @nodoc
class _RegisterState implements RegisterState {
const _RegisterState({this.status = RequestStatus.initial});
@override@JsonKey() final RequestStatus status;
/// Create a copy of RegisterState
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$RegisterStateCopyWith<_RegisterState> get copyWith => __$RegisterStateCopyWithImpl<_RegisterState>(this, _$identity);
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _RegisterState&&(identical(other.status, status) || other.status == status));
}
@override
int get hashCode => Object.hash(runtimeType,status);
@override
String toString() {
return 'RegisterState(status: $status)';
}
}
/// @nodoc
abstract mixin class _$RegisterStateCopyWith<$Res> implements $RegisterStateCopyWith<$Res> {
factory _$RegisterStateCopyWith(_RegisterState value, $Res Function(_RegisterState) _then) = __$RegisterStateCopyWithImpl;
@override @useResult
$Res call({
RequestStatus status
});
}
/// @nodoc
class __$RegisterStateCopyWithImpl<$Res>
implements _$RegisterStateCopyWith<$Res> {
__$RegisterStateCopyWithImpl(this._self, this._then);
final _RegisterState _self;
final $Res Function(_RegisterState) _then;
/// Create a copy of RegisterState
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? status = null,}) {
return _then(_RegisterState(
status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable
as RequestStatus,
));
}
}
// dart format on

View File

@@ -0,0 +1,8 @@
part of 'register_bloc.dart';
@freezed
class RegisterEvent with _$RegisterEvent {
const factory RegisterEvent.started() = _Started;
const factory RegisterEvent.loaded(RegisterParams params) = _Loaded;
}

View File

@@ -0,0 +1,8 @@
part of 'register_bloc.dart';
@freezed
abstract class RegisterState with _$RegisterState {
const factory RegisterState({
@Default(RequestStatus.initial) RequestStatus status,
}) = _RegisterState;
}

View File

@@ -0,0 +1,36 @@
import 'package:food_delivery_client/feature/auth/domain/usecases/reset_password_usecase.dart';
import 'package:food_delivery_client/feature/common/presentation/widgets/w_toastification.dart';
import 'package:food_delivery_client/food_delivery_client.dart';
part 'reset_password_event.dart';
part 'reset_password_state.dart';
part 'reset_password_bloc.freezed.dart';
@injectable
class ResetPasswordBloc extends Bloc<ResetPasswordEvent, ResetPasswordState> {
final ResetPasswordUseCase _passwordUseCase;
ResetPasswordBloc(this._passwordUseCase) : super(const ResetPasswordState()) {
on<_Loaded>(_onLoaded);
}
Future<void> _onLoaded(
_Loaded event,
Emitter<ResetPasswordState> emit,
) async {
emit(state.copyWith(status: RequestStatus.loading));
final response = await _passwordUseCase.call(event.params);
response.fold(
(l) {
showErrorToast(l.errorMessage);
emit(state.copyWith(status: RequestStatus.error));
},
(r) {
showSuccessToast(r.message);
emit(state.copyWith(status: RequestStatus.loaded));
},
);
}
}

View File

@@ -0,0 +1,535 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// coverage:ignore-file
// ignore_for_file: type=lint
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
part of 'reset_password_bloc.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$ResetPasswordEvent {
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is ResetPasswordEvent);
}
@override
int get hashCode => runtimeType.hashCode;
@override
String toString() {
return 'ResetPasswordEvent()';
}
}
/// @nodoc
class $ResetPasswordEventCopyWith<$Res> {
$ResetPasswordEventCopyWith(ResetPasswordEvent _, $Res Function(ResetPasswordEvent) __);
}
/// Adds pattern-matching-related methods to [ResetPasswordEvent].
extension ResetPasswordEventPatterns on ResetPasswordEvent {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>({TResult Function( _Started value)? started,TResult Function( _Loaded value)? loaded,required TResult orElse(),}){
final _that = this;
switch (_that) {
case _Started() when started != null:
return started(_that);case _Loaded() when loaded != null:
return loaded(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>({required TResult Function( _Started value) started,required TResult Function( _Loaded value) loaded,}){
final _that = this;
switch (_that) {
case _Started():
return started(_that);case _Loaded():
return loaded(_that);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>({TResult? Function( _Started value)? started,TResult? Function( _Loaded value)? loaded,}){
final _that = this;
switch (_that) {
case _Started() when started != null:
return started(_that);case _Loaded() when loaded != null:
return loaded(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>({TResult Function()? started,TResult Function( ResetPasswordParams params)? loaded,required TResult orElse(),}) {final _that = this;
switch (_that) {
case _Started() when started != null:
return started();case _Loaded() when loaded != null:
return loaded(_that.params);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>({required TResult Function() started,required TResult Function( ResetPasswordParams params) loaded,}) {final _that = this;
switch (_that) {
case _Started():
return started();case _Loaded():
return loaded(_that.params);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>({TResult? Function()? started,TResult? Function( ResetPasswordParams params)? loaded,}) {final _that = this;
switch (_that) {
case _Started() when started != null:
return started();case _Loaded() when loaded != null:
return loaded(_that.params);case _:
return null;
}
}
}
/// @nodoc
class _Started implements ResetPasswordEvent {
const _Started();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _Started);
}
@override
int get hashCode => runtimeType.hashCode;
@override
String toString() {
return 'ResetPasswordEvent.started()';
}
}
/// @nodoc
class _Loaded implements ResetPasswordEvent {
const _Loaded(this.params);
final ResetPasswordParams params;
/// Create a copy of ResetPasswordEvent
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$LoadedCopyWith<_Loaded> get copyWith => __$LoadedCopyWithImpl<_Loaded>(this, _$identity);
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _Loaded&&(identical(other.params, params) || other.params == params));
}
@override
int get hashCode => Object.hash(runtimeType,params);
@override
String toString() {
return 'ResetPasswordEvent.loaded(params: $params)';
}
}
/// @nodoc
abstract mixin class _$LoadedCopyWith<$Res> implements $ResetPasswordEventCopyWith<$Res> {
factory _$LoadedCopyWith(_Loaded value, $Res Function(_Loaded) _then) = __$LoadedCopyWithImpl;
@useResult
$Res call({
ResetPasswordParams params
});
}
/// @nodoc
class __$LoadedCopyWithImpl<$Res>
implements _$LoadedCopyWith<$Res> {
__$LoadedCopyWithImpl(this._self, this._then);
final _Loaded _self;
final $Res Function(_Loaded) _then;
/// Create a copy of ResetPasswordEvent
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') $Res call({Object? params = null,}) {
return _then(_Loaded(
null == params ? _self.params : params // ignore: cast_nullable_to_non_nullable
as ResetPasswordParams,
));
}
}
/// @nodoc
mixin _$ResetPasswordState {
RequestStatus get status;
/// Create a copy of ResetPasswordState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$ResetPasswordStateCopyWith<ResetPasswordState> get copyWith => _$ResetPasswordStateCopyWithImpl<ResetPasswordState>(this as ResetPasswordState, _$identity);
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is ResetPasswordState&&(identical(other.status, status) || other.status == status));
}
@override
int get hashCode => Object.hash(runtimeType,status);
@override
String toString() {
return 'ResetPasswordState(status: $status)';
}
}
/// @nodoc
abstract mixin class $ResetPasswordStateCopyWith<$Res> {
factory $ResetPasswordStateCopyWith(ResetPasswordState value, $Res Function(ResetPasswordState) _then) = _$ResetPasswordStateCopyWithImpl;
@useResult
$Res call({
RequestStatus status
});
}
/// @nodoc
class _$ResetPasswordStateCopyWithImpl<$Res>
implements $ResetPasswordStateCopyWith<$Res> {
_$ResetPasswordStateCopyWithImpl(this._self, this._then);
final ResetPasswordState _self;
final $Res Function(ResetPasswordState) _then;
/// Create a copy of ResetPasswordState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? status = null,}) {
return _then(_self.copyWith(
status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable
as RequestStatus,
));
}
}
/// Adds pattern-matching-related methods to [ResetPasswordState].
extension ResetPasswordStatePatterns on ResetPasswordState {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _ResetPasswordState value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _ResetPasswordState() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _ResetPasswordState value) $default,){
final _that = this;
switch (_that) {
case _ResetPasswordState():
return $default(_that);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _ResetPasswordState value)? $default,){
final _that = this;
switch (_that) {
case _ResetPasswordState() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( RequestStatus status)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _ResetPasswordState() when $default != null:
return $default(_that.status);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( RequestStatus status) $default,) {final _that = this;
switch (_that) {
case _ResetPasswordState():
return $default(_that.status);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( RequestStatus status)? $default,) {final _that = this;
switch (_that) {
case _ResetPasswordState() when $default != null:
return $default(_that.status);case _:
return null;
}
}
}
/// @nodoc
class _ResetPasswordState implements ResetPasswordState {
const _ResetPasswordState({this.status = RequestStatus.initial});
@override@JsonKey() final RequestStatus status;
/// Create a copy of ResetPasswordState
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$ResetPasswordStateCopyWith<_ResetPasswordState> get copyWith => __$ResetPasswordStateCopyWithImpl<_ResetPasswordState>(this, _$identity);
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _ResetPasswordState&&(identical(other.status, status) || other.status == status));
}
@override
int get hashCode => Object.hash(runtimeType,status);
@override
String toString() {
return 'ResetPasswordState(status: $status)';
}
}
/// @nodoc
abstract mixin class _$ResetPasswordStateCopyWith<$Res> implements $ResetPasswordStateCopyWith<$Res> {
factory _$ResetPasswordStateCopyWith(_ResetPasswordState value, $Res Function(_ResetPasswordState) _then) = __$ResetPasswordStateCopyWithImpl;
@override @useResult
$Res call({
RequestStatus status
});
}
/// @nodoc
class __$ResetPasswordStateCopyWithImpl<$Res>
implements _$ResetPasswordStateCopyWith<$Res> {
__$ResetPasswordStateCopyWithImpl(this._self, this._then);
final _ResetPasswordState _self;
final $Res Function(_ResetPasswordState) _then;
/// Create a copy of ResetPasswordState
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? status = null,}) {
return _then(_ResetPasswordState(
status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable
as RequestStatus,
));
}
}
// dart format on

View File

@@ -0,0 +1,8 @@
part of 'reset_password_bloc.dart';
@freezed
class ResetPasswordEvent with _$ResetPasswordEvent {
const factory ResetPasswordEvent.started() = _Started;
const factory ResetPasswordEvent.loaded(ResetPasswordParams params) = _Loaded;
}

View File

@@ -0,0 +1,8 @@
part of 'reset_password_bloc.dart';
@freezed
abstract class ResetPasswordState with _$ResetPasswordState {
const factory ResetPasswordState({
@Default(RequestStatus.initial) RequestStatus status,
}) = _ResetPasswordState;
}

View File

@@ -67,6 +67,7 @@ class VerifyOtpBloc extends Bloc<VerifyOtpEvent, VerifyOtpState> {
emit(state.copyWith(status: RequestStatus.error));
},
(r) {
showSuccessToast(r.message);
emit(state.copyWith(status: RequestStatus.loaded));
add(VerifyOtpEvent.cancelTimer());
},
@@ -86,6 +87,7 @@ class VerifyOtpBloc extends Bloc<VerifyOtpEvent, VerifyOtpState> {
emit(state.copyWith(status: RequestStatus.error));
},
(r) {
showSuccessToast(r.message);
emit(state.copyWith(status: RequestStatus.loaded));
add(VerifyOtpEvent.cancelTimer());
},

View File

@@ -2,6 +2,7 @@ import 'package:food_delivery_client/core/helpers/formatters.dart';
import 'package:food_delivery_client/core/helpers/validator_helpers.dart';
import 'package:food_delivery_client/feature/auth/presentation/widgets/w_auth_background.dart';
import '../../../../../../food_delivery_client.dart';
import '../../../../domain/usecases/login_usecase.dart';
import '../../../blocs/login_bloc/login_bloc.dart';
class WLoginBody extends StatefulWidget {
@@ -128,16 +129,15 @@ class _WLoginBodyState extends State<WLoginBody> {
).paddingOnly(left: 10),
onPressed: () {
if (_formKey.currentState?.validate() ?? false) {
context.go(Routes.main);
// context.read<LoginBloc>().add(
// LoginEvent.login(
// LoginParams(
// phoneNumber:
// "+998${_phoneController.text.trim().replaceAll(" ", "")}",
// password: _passwordController.text.trim(),
// ),
// ),
// );
context.read<LoginBloc>().add(
LoginEvent.login(
LoginParams(
phoneNumber:
"+998${_phoneController.text.trim().replaceAll(" ", "")}",
password: _passwordController.text.trim(),
),
),
);
}
},
borderRadius: 15,

View File

@@ -1,6 +1,7 @@
import 'package:food_delivery_client/feature/auth/presentation/pages/register_page/widgets/w_register_body.dart';
import '../../../../../food_delivery_client.dart';
import '../../blocs/register_bloc/register_bloc.dart';
class RegisterPage extends StatelessWidget {
const RegisterPage({super.key, required this.phoneNumber});
@@ -9,6 +10,16 @@ class RegisterPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return WLayout(top: false, child: Scaffold(body: WRegisterBody()));
return BlocProvider(
create: (context) => sl<RegisterBloc>(),
child: BlocBuilder<RegisterBloc, RegisterState>(
builder: (context, state) {
return WLayout(
top: false,
child: Scaffold(body: WRegisterBody(phoneNumber: phoneNumber)),
);
},
),
);
}
}

View File

@@ -1,9 +1,13 @@
import 'package:food_delivery_client/core/helpers/validator_helpers.dart';
import 'package:food_delivery_client/feature/auth/domain/usecases/register_usecase.dart';
import 'package:food_delivery_client/feature/auth/presentation/widgets/w_auth_background.dart';
import '../../../../../../food_delivery_client.dart';
import '../../../blocs/register_bloc/register_bloc.dart';
class WRegisterBody extends StatefulWidget {
const WRegisterBody({super.key});
const WRegisterBody({super.key, required this.phoneNumber});
final String phoneNumber;
@override
State<WRegisterBody> createState() => _WRegisterBodyState();
@@ -40,62 +44,69 @@ class _WRegisterBodyState extends State<WRegisterBody> {
@override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: WAuthBackground(
child: SizedBox(
width: context.w,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
20.verticalSpace,
Align(
alignment: AlignmentGeometry.center,
child: Text(
context.loc.sign_up,
style: AppTextStyles.size24Bold,
),
),
20.verticalSpace,
Text(
context.loc.first_name,
style: AppTextStyles.size14Regular.copyWith(
color: AppColors.c6A6E7F,
),
),
5.verticalSpace,
AppTextFormField(
hintText: context.loc.enter_first_name,
controller: _firstNameController,
borderRadius: AppUtils.kBorderRadius8,
keyBoardType: TextInputType.name,
validator: (value) {
return Validators.validateFields(
_firstNameController.text.trim(),
);
},
),
10.verticalSpace,
Text(
'Last name',
style: AppTextStyles.size14Regular.copyWith(
color: AppColors.c6A6E7F,
),
),
5.verticalSpace,
AppTextFormField(
hintText: "Enter LastName",
controller: _lastNameController,
borderRadius: AppUtils.kBorderRadius8,
keyBoardType: TextInputType.text,
validator: (value) {
return Validators.validateFields(
_lastNameController.text.trim(),
);
},
),
10.verticalSpace,
/* Text(
return BlocConsumer<RegisterBloc, RegisterState>(
listener: (context, state) {
if (state.status.isLoaded()) {
context.go(Routes.login);
}
},
builder: (context, state) {
return Form(
key: _formKey,
child: WAuthBackground(
child: SizedBox(
width: context.w,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
20.verticalSpace,
Align(
alignment: AlignmentGeometry.center,
child: Text(
context.loc.sign_up,
style: AppTextStyles.size24Bold,
),
),
20.verticalSpace,
Text(
context.loc.first_name,
style: AppTextStyles.size14Regular.copyWith(
color: AppColors.c6A6E7F,
),
),
5.verticalSpace,
AppTextFormField(
hintText: context.loc.enter_first_name,
controller: _firstNameController,
borderRadius: AppUtils.kBorderRadius8,
keyBoardType: TextInputType.name,
validator: (value) {
return Validators.validateFields(
_firstNameController.text.trim(),
);
},
),
10.verticalSpace,
Text(
'Last name',
style: AppTextStyles.size14Regular.copyWith(
color: AppColors.c6A6E7F,
),
),
5.verticalSpace,
AppTextFormField(
hintText: "Enter LastName",
controller: _lastNameController,
borderRadius: AppUtils.kBorderRadius8,
keyBoardType: TextInputType.text,
validator: (value) {
return Validators.validateFields(
_lastNameController.text.trim(),
);
},
),
10.verticalSpace,
/* Text(
context.loc.phone_number,
style: AppTextStyles.size14Regular.copyWith(
color: AppColors.c6A6E7F,
@@ -121,88 +132,99 @@ class _WRegisterBodyState extends State<WRegisterBody> {
),
*/
10.verticalSpace,
Text(
context.loc.enter_password,
style: AppTextStyles.size14Regular.copyWith(
color: AppColors.c6A6E7F,
),
),
5.verticalSpace,
AppTextFormField(
obscureText: true,
hintText: context.loc.password,
controller: _passwordController,
borderRadius: AppUtils.kBorderRadius8,
keyBoardType: TextInputType.visiblePassword,
validator: (value) {
return Validators.validatePassword(
_passwordController.text.trim(),
);
},
),
10.verticalSpace,
Text(
context.loc.repeat_password,
style: AppTextStyles.size14Regular.copyWith(
color: AppColors.c6A6E7F,
),
),
5.verticalSpace,
AppTextFormField(
obscureText: true,
hintText: context.loc.enter_repeat_password,
controller: _repeatPasswordController,
borderRadius: AppUtils.kBorderRadius8,
keyBoardType: TextInputType.visiblePassword,
validator: (value) {
return Validators.validatePassword(
_repeatPasswordController.text.trim(),
);
},
),
20.verticalSpace,
AppButton(
name: context.loc.continue_str,
borderRadius: 15,
backgroundColor: AppColors.c34A853,
trailing: SvgPicture.asset(
AppIcons.icArrowRightLight,
).paddingOnly(left: 8),
onPressed: () {
if (_formKey.currentState?.validate() ?? false) {
}
},
),
20.verticalSpace,
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
10.verticalSpace,
Text(
context.loc.already_has_account,
style: AppTextStyles.size14Medium,
),
TextButton(
onPressed: () {
context.pushReplacement(Routes.login);
},
child: Text(
context.loc.login,
style: AppTextStyles.size15Bold.copyWith(
color: AppColors.c34A853,
),
context.loc.enter_password,
style: AppTextStyles.size14Regular.copyWith(
color: AppColors.c6A6E7F,
),
),
5.verticalSpace,
AppTextFormField(
obscureText: true,
hintText: context.loc.password,
controller: _passwordController,
borderRadius: AppUtils.kBorderRadius8,
keyBoardType: TextInputType.visiblePassword,
validator: (value) {
return Validators.validatePassword(
_passwordController.text.trim(),
);
},
),
10.verticalSpace,
Text(
context.loc.repeat_password,
style: AppTextStyles.size14Regular.copyWith(
color: AppColors.c6A6E7F,
),
),
5.verticalSpace,
AppTextFormField(
obscureText: true,
hintText: context.loc.enter_repeat_password,
controller: _repeatPasswordController,
borderRadius: AppUtils.kBorderRadius8,
keyBoardType: TextInputType.visiblePassword,
validator: (value) {
return Validators.validateRepeatPassword(
_repeatPasswordController.text.trim(),
_passwordController.text.trim(),
);
},
),
20.verticalSpace,
AppButton(
isLoading: state.status.isLoading(),
name: context.loc.continue_str,
borderRadius: 15,
backgroundColor: AppColors.c34A853,
trailing: SvgPicture.asset(
AppIcons.icArrowRightLight,
).paddingOnly(left: 8),
onPressed: () {
if (_formKey.currentState?.validate() ?? false) {
context.read<RegisterBloc>().add(
RegisterEvent.loaded(
RegisterParams(
phoneNumber: widget.phoneNumber,
password: _passwordController.text.trim(),
firstName: _firstNameController.text.trim(),
lastName: _lastNameController.text.trim(),
),
),
);
}
},
),
20.verticalSpace,
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
context.loc.already_has_account,
style: AppTextStyles.size14Medium,
),
TextButton(
onPressed: () {
context.pushReplacement(Routes.login);
},
child: Text(
context.loc.login,
style: AppTextStyles.size15Bold.copyWith(
color: AppColors.c34A853,
),
),
),
],
),
],
),
],
).paddingSymmetric(horizontal: 16),
),
),
).paddingSymmetric(horizontal: 16),
),
),
);
},
);
}
}

View File

@@ -1,21 +1,137 @@
import 'package:food_delivery_client/core/helpers/validator_helpers.dart';
import 'package:food_delivery_client/feature/auth/domain/usecases/reset_password_usecase.dart';
import 'package:food_delivery_client/feature/auth/presentation/blocs/reset_password_bloc/reset_password_bloc.dart';
import 'package:food_delivery_client/feature/auth/presentation/widgets/w_auth_background.dart';
import '../../../../../food_delivery_client.dart';
class ResetPasswordPage extends StatelessWidget {
class ResetPasswordPage extends StatefulWidget {
const ResetPasswordPage({super.key, required this.phoneNumber});
final String phoneNumber;
final String phoneNumber;
@override
State<ResetPasswordPage> createState() => _ResetPasswordPageState();
}
class _ResetPasswordPageState extends State<ResetPasswordPage> {
late TextEditingController _passwordController;
late TextEditingController _repeatPasswordController;
final _formKey = GlobalKey<FormState>();
@override
void initState() {
_passwordController = TextEditingController();
_repeatPasswordController = TextEditingController();
super.initState();
}
@override
void dispose() {
_passwordController.dispose();
_repeatPasswordController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return WLayout(
top: false,
child: Scaffold(
body: WAuthBackground(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [],
),
),
return BlocProvider(
create: (context) => sl<ResetPasswordBloc>(),
child: BlocConsumer<ResetPasswordBloc, ResetPasswordState>(
listener: (context, state) {
if (state.status.isLoaded()) {
context.go(Routes.login);
}
},
builder: (context, state) {
return Form(
key: _formKey,
child: WLayout(
top: false,
child: Scaffold(
body: WAuthBackground(
child: SizedBox(
width: context.w,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
25.verticalSpace,
Text(
context.loc.reset_password,
style: AppTextStyles.size20Medium,
),
20.verticalSpace,
Text(
context.loc.new_password,
style: AppTextStyles.size14Regular.copyWith(
color: AppColors.c6A6E7F,
),
),
5.verticalSpace,
AppTextFormField(
obscureText: true,
controller: _passwordController,
borderRadius: AppUtils.kBorderRadius8,
hintText: context.loc.enter_password,
keyBoardType: TextInputType.visiblePassword,
validator: (value) {
return Validators.validatePassword(
_passwordController.text.trim(),
);
},
),
20.verticalSpace,
Text(
context.loc.password,
style: AppTextStyles.size14Regular.copyWith(
color: AppColors.c6A6E7F,
),
),
5.verticalSpace,
AppTextFormField(
obscureText: true,
controller: _repeatPasswordController,
borderRadius: AppUtils.kBorderRadius8,
hintText: context.loc.enter_password,
keyBoardType: TextInputType.visiblePassword,
validator: (value) {
return Validators.validateRepeatPassword(
_repeatPasswordController.text.trim(),
_passwordController.text.trim(),
);
},
),
25.verticalSpace,
AppButton(
name: context.loc.continue_str,
trailing: SvgPicture.asset(
AppIcons.icArrowRightLight,
).paddingOnly(left: 8),
isLoading: state.status.isLoading(),
onPressed: () {
if (_formKey.currentState?.validate() ?? false) {
context.read<ResetPasswordBloc>().add(
ResetPasswordEvent.loaded(
ResetPasswordParams(
phoneNumber: widget.phoneNumber,
newPassword: _passwordController.text
.trim(),
),
),
);
}
},
backgroundColor: AppColors.c34A853,
borderRadius: 15,
),
],
).paddingSymmetric(horizontal: 16),
),
),
),
),
);
},
),
);
}

View File

@@ -1,3 +1,4 @@
import 'package:flutter/cupertino.dart';
import 'package:food_delivery_client/core/helpers/time_formatters.dart';
import 'package:food_delivery_client/feature/auth/domain/usecases/verify_otp_code_login_usecase.dart';
import 'package:food_delivery_client/feature/auth/presentation/blocs/verify_otp_bloc/verify_otp_bloc.dart';
@@ -68,7 +69,7 @@ class _VerifyOtpCodePageState extends State<VerifyOtpCodePage> {
children: [
40.verticalSpace,
Text(
"Enter the 5-digit code sent to you at ${widget.params.phoneNumber}",
context.loc.enter_otp_code(widget.params.phoneNumber),
style: AppTextStyles.size20Medium,
),
20.verticalSpace,
@@ -98,36 +99,47 @@ class _VerifyOtpCodePageState extends State<VerifyOtpCodePage> {
},
),
10.verticalSpace,
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("You can resend otp after"),
SizedBox(
height: 40,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
context.loc.resend_otp_after,
style: AppTextStyles.size14Regular,
),
if (state.time != 0)
Text(TimeFormatters.formatMinutesToTime(state.time)),
if (state.time != 0)
Text(
TimeFormatters.formatMinutesToTime(state.time),
),
if (state.time == 0)
state.resendStatus.isLoading()
? CircularProgressIndicator.adaptive()
: TextButton(
onPressed: () {
if (widget.params.isRegister) {
context.read<VerifyOtpBloc>().add(
VerifyOtpEvent.resendRegister(
widget.params.phoneNumber,
),
);
} else {
context.read<VerifyOtpBloc>().add(
VerifyOtpEvent.resendForgot(
widget.params.phoneNumber,
),
);
}
},
child: Text("Resend"),
),
],
if (state.time == 0)
state.resendStatus.isLoading()
? CircularProgressIndicator.adaptive()
: IconButton(
onPressed: () {
if (widget.params.isRegister) {
context.read<VerifyOtpBloc>().add(
VerifyOtpEvent.resendRegister(
widget.params.phoneNumber,
),
);
} else {
context.read<VerifyOtpBloc>().add(
VerifyOtpEvent.resendForgot(
widget.params.phoneNumber,
),
);
}
},
icon: Icon(
CupertinoIcons.restart,
color: AppColors.c000000,
),
),
],
),
),
20.verticalSpace,
@@ -153,9 +165,8 @@ class _VerifyOtpCodePageState extends State<VerifyOtpCodePage> {
VerifyOtpEvent.verifyOtpReset(
VerifyOtpCodeParams(
phoneNumber: widget.params.phoneNumber,
otpCode: _controller.text.trim().substring(
0,
4,
otpCode: int.tryParse(
_controller.text.trim().substring(0, 4),
),
),
),
@@ -163,6 +174,7 @@ class _VerifyOtpCodePageState extends State<VerifyOtpCodePage> {
}
}
},
isLoading: state.status.isLoading(),
backgroundColor: AppColors.c34A853,
borderRadius: 15,
trailing: SvgPicture.asset(

View File

@@ -115,6 +115,7 @@ class _VerifyPhoneNumberPageState extends State<VerifyPhoneNumberPage> {
}
}
},
isLoading: state.status.isLoading(),
name: context.loc.continue_str,
borderRadius: 15,
backgroundColor: AppColors.c34A853,

View File

@@ -14,8 +14,8 @@ class WAuthBackground extends StatelessWidget {
child: Image.asset(AppImages.imgBurger2, fit: BoxFit.cover),
),
SingleChildScrollView(
// keyboardDismissBehavior:
// ScrollViewKeyboardDismissBehavior.onDrag,
keyboardDismissBehavior:
ScrollViewKeyboardDismissBehavior.onDrag,
child: Column(
children: [
SizedBox(height: context.h * .2),