change password screen ui
This commit is contained in:
@@ -121,7 +121,6 @@ class AppText {
|
||||
static const String declineText = "Decline";
|
||||
|
||||
//Forgot Password
|
||||
|
||||
static const String restorePasswordText = "Restore password";
|
||||
static const String toRestorePasswordPleaseEnterPhoneNumber =
|
||||
"To restore password please enter phone number";
|
||||
@@ -158,6 +157,10 @@ class AppText {
|
||||
static const String noText = "No";
|
||||
static const String yesText = "Yes";
|
||||
static const String pinUpdatedSucess = "Pin updated Sucessfully !";
|
||||
static const String passwordUpdatedSucess = "Password updated Sucessfully !";
|
||||
static const String changePasswordText = "Change Password";
|
||||
static const String newPasswordText = "New Password";
|
||||
static const String currentPsswordText = "Current Password";
|
||||
|
||||
//Contact Admin
|
||||
static const String byPhoneText = "By phone";
|
||||
|
||||
@@ -40,7 +40,11 @@ class PrivacySettingsSection extends StatelessWidget {
|
||||
),
|
||||
const Gap(12),
|
||||
SettingsListItem(
|
||||
onTapFunc: () {},
|
||||
onTapFunc: () {
|
||||
goRouter.pushNamed(
|
||||
RouteName.changePasswordScreen,
|
||||
);
|
||||
},
|
||||
icon: AppImages.resetPasswordIcon,
|
||||
title: AppText.resetPasswordText,
|
||||
trailing: "",
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'restore_password_event.dart';
|
||||
import 'restore_password_state.dart';
|
||||
import 'change_password_event.dart';
|
||||
import 'change_password_state.dart';
|
||||
|
||||
class RestorePasswordBloc
|
||||
extends Bloc<RestorePasswordEvent, RestorePasswordState> {
|
||||
class ChangePasswordBloc
|
||||
extends Bloc<ChangePasswordEvent, ChangePasswordState> {
|
||||
final GlobalKey<FormState> formKey = GlobalKey<FormState>();
|
||||
|
||||
final TextEditingController currentPasswordTextField =
|
||||
TextEditingController();
|
||||
final TextEditingController passwordTextField = TextEditingController();
|
||||
final TextEditingController repeatPasswordTextField = TextEditingController();
|
||||
|
||||
@@ -14,47 +17,51 @@ class RestorePasswordBloc
|
||||
return formKey;
|
||||
}
|
||||
|
||||
RestorePasswordBloc() : super(RestorePasswordInitial()) {
|
||||
ChangePasswordBloc() : super(ChangePasswordInitial()) {
|
||||
currentPasswordTextField.addListener(_onFormFieldChanged);
|
||||
passwordTextField.addListener(_onFormFieldChanged);
|
||||
repeatPasswordTextField.addListener(_onFormFieldChanged);
|
||||
on<RestorePasswordFormChanged>(_onLoginFormChanged);
|
||||
on<RestorePasswordSubmitted>((event, emit) async {
|
||||
on<ChangePasswordFormChanged>(_onLoginFormChanged);
|
||||
on<ChangePasswordSubmitted>((event, emit) async {
|
||||
if (!formKey.currentState!.validate()) {
|
||||
return;
|
||||
}
|
||||
emit(RestorePasswordLoading());
|
||||
emit(ChangePasswordLoading());
|
||||
try {
|
||||
// Simulate API call
|
||||
await Future.delayed(const Duration(seconds: 2));
|
||||
// Replace the next line with actual API call
|
||||
final isSuccess = await _mockLoginApi(event.password);
|
||||
if (isSuccess) {
|
||||
emit(RestorePasswordSuccess());
|
||||
emit(ChangePasswordSuccess());
|
||||
} else {
|
||||
emit(const RestorePasswordFailure(
|
||||
emit(const ChangePasswordFailure(
|
||||
"Failed. Please check your credentials."));
|
||||
}
|
||||
} catch (e) {
|
||||
emit(RestorePasswordFailure(e.toString()));
|
||||
emit(ChangePasswordFailure(e.toString()));
|
||||
}
|
||||
});
|
||||
}
|
||||
void _onFormFieldChanged() {
|
||||
add(RestorePasswordFormChanged(
|
||||
add(ChangePasswordFormChanged(
|
||||
currentPasswordTextField.text,
|
||||
passwordTextField.text,
|
||||
repeatPasswordTextField.text,
|
||||
));
|
||||
}
|
||||
|
||||
void _onLoginFormChanged(
|
||||
RestorePasswordFormChanged event, Emitter<RestorePasswordState> emit) {
|
||||
final areFieldsFilled =
|
||||
event.password.isNotEmpty && event.repeatPassword.isNotEmpty;
|
||||
emit(RestorePasswordFieldsState(areFieldsFilled));
|
||||
ChangePasswordFormChanged event, Emitter<ChangePasswordState> emit) {
|
||||
final areFieldsFilled = event.currentPassword.isNotEmpty &&
|
||||
event.password.isNotEmpty &&
|
||||
event.repeatPassword.isNotEmpty;
|
||||
emit(ChangePasswordFieldsState(areFieldsFilled));
|
||||
}
|
||||
|
||||
// Method to reset text fields
|
||||
void resetFields() {
|
||||
currentPasswordTextField.clear();
|
||||
passwordTextField.clear();
|
||||
repeatPasswordTextField.clear();
|
||||
}
|
||||
@@ -69,6 +76,7 @@ class RestorePasswordBloc
|
||||
@override
|
||||
Future<void> close() {
|
||||
passwordTextField.dispose();
|
||||
currentPasswordTextField.dispose();
|
||||
repeatPasswordTextField.dispose();
|
||||
|
||||
return super.close();
|
||||
@@ -0,0 +1,35 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
abstract class ChangePasswordEvent extends Equatable {
|
||||
const ChangePasswordEvent();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class ChangePasswordSubmitted extends ChangePasswordEvent {
|
||||
final String currentPassword;
|
||||
final String password;
|
||||
final String repeatPassword;
|
||||
|
||||
const ChangePasswordSubmitted(
|
||||
this.password,
|
||||
this.currentPassword,
|
||||
this.repeatPassword,
|
||||
);
|
||||
|
||||
@override
|
||||
List<Object> get props => [currentPassword, password, repeatPassword];
|
||||
}
|
||||
|
||||
class ChangePasswordFormChanged extends ChangePasswordEvent {
|
||||
final String currentPassword;
|
||||
final String password;
|
||||
final String repeatPassword;
|
||||
|
||||
const ChangePasswordFormChanged(
|
||||
this.currentPassword, this.password, this.repeatPassword);
|
||||
|
||||
@override
|
||||
List<Object> get props => [currentPassword, password, repeatPassword];
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
abstract class ChangePasswordState extends Equatable {
|
||||
const ChangePasswordState();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class ChangePasswordInitial extends ChangePasswordState {}
|
||||
|
||||
class ChangePasswordLoading extends ChangePasswordState {}
|
||||
|
||||
class ChangePasswordSuccess extends ChangePasswordState {}
|
||||
|
||||
class ChangePasswordFailure extends ChangePasswordState {
|
||||
final String error;
|
||||
|
||||
const ChangePasswordFailure(this.error);
|
||||
|
||||
@override
|
||||
List<Object> get props => [error];
|
||||
}
|
||||
|
||||
class ChangePasswordFieldsState extends ChangePasswordState {
|
||||
final bool areFieldsFilled;
|
||||
|
||||
const ChangePasswordFieldsState(this.areFieldsFilled);
|
||||
|
||||
@override
|
||||
List<Object> get props => [areFieldsFilled];
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
abstract class RestorePasswordEvent extends Equatable {
|
||||
const RestorePasswordEvent();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class RestorePasswordSubmitted extends RestorePasswordEvent {
|
||||
final String password;
|
||||
final String repeatPassword;
|
||||
|
||||
const RestorePasswordSubmitted(
|
||||
this.password,
|
||||
this.repeatPassword,
|
||||
);
|
||||
|
||||
@override
|
||||
List<Object> get props => [password, repeatPassword];
|
||||
}
|
||||
|
||||
class RestorePasswordFormChanged extends RestorePasswordEvent {
|
||||
final String password;
|
||||
final String repeatPassword;
|
||||
|
||||
const RestorePasswordFormChanged(this.password, this.repeatPassword);
|
||||
|
||||
@override
|
||||
List<Object> get props => [password, repeatPassword];
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
abstract class RestorePasswordState extends Equatable {
|
||||
const RestorePasswordState();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class RestorePasswordInitial extends RestorePasswordState {}
|
||||
|
||||
class RestorePasswordLoading extends RestorePasswordState {}
|
||||
|
||||
class RestorePasswordSuccess extends RestorePasswordState {}
|
||||
|
||||
class RestorePasswordFailure extends RestorePasswordState {
|
||||
final String error;
|
||||
|
||||
const RestorePasswordFailure(this.error);
|
||||
|
||||
@override
|
||||
List<Object> get props => [error];
|
||||
}
|
||||
|
||||
class RestorePasswordFieldsState extends RestorePasswordState {
|
||||
final bool areFieldsFilled;
|
||||
|
||||
const RestorePasswordFieldsState(this.areFieldsFilled);
|
||||
|
||||
@override
|
||||
List<Object> get props => [areFieldsFilled];
|
||||
}
|
||||
@@ -1,23 +1,15 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
|
||||
import '../widgets/restore_password_bottom_section.dart';
|
||||
import '../widgets/restore_password_form.dart';
|
||||
import '../widgets/restore_password_top_section.dart';
|
||||
import '../widgets/change_password_bottom_section.dart';
|
||||
import '../widgets/change_password_form.dart';
|
||||
|
||||
class ChangePasswordLayout extends StatelessWidget {
|
||||
const ChangePasswordLayout({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: ListView(
|
||||
children: const [
|
||||
RestorePasswordTopSection(),
|
||||
RestorePasswordForm(),
|
||||
Gap(150),
|
||||
RestorePasswordBottomSection(),
|
||||
],
|
||||
));
|
||||
return const Scaffold(
|
||||
bottomNavigationBar: RestorePasswordBottomSection(),
|
||||
body: RestorePasswordForm());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import '../bloc/restore_password_bloc.dart';
|
||||
import '../../../../core/styles/app_text.dart';
|
||||
import '../../../../shared/components/appbar_widget.dart';
|
||||
import '../bloc/change_password_bloc.dart';
|
||||
import 'change_password_layout.dart';
|
||||
|
||||
class ChangePasswordScreen extends StatelessWidget {
|
||||
@@ -10,13 +12,17 @@ class ChangePasswordScreen extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: true,
|
||||
appBar: const AppBarWidget(
|
||||
height: 75,
|
||||
titleTxt: AppText.changePasswordText,
|
||||
),
|
||||
resizeToAvoidBottomInset: false,
|
||||
body: MultiBlocProvider(
|
||||
// Define the providers for the OnboardingBloc and other blocs
|
||||
providers: [
|
||||
BlocProvider(
|
||||
// Create an instance of the OnboardingBloc
|
||||
create: (context) => RestorePasswordBloc(),
|
||||
create: (context) => ChangePasswordBloc(),
|
||||
),
|
||||
],
|
||||
child: const ChangePasswordLayout(),
|
||||
|
||||
@@ -5,16 +5,14 @@ import 'package:gap/gap.dart';
|
||||
import 'package:tanami_app/shared/components/loader.dart';
|
||||
import 'package:tanami_app/shared/components/toast_message.dart';
|
||||
|
||||
import '../../../../core/routes/route_name.dart';
|
||||
import '../../../../core/routes/routes.dart';
|
||||
import '../../../../core/styles/app_color.dart';
|
||||
import '../../../../core/styles/app_text.dart';
|
||||
import '../../../../shared/components/button_widget.dart';
|
||||
import '../../../../shared/components/text_widget.dart';
|
||||
import '../../../countrySelection/presentation/bloc/choose_country_bloc.dart';
|
||||
import '../bloc/restore_password_bloc.dart';
|
||||
import '../bloc/restore_password_event.dart';
|
||||
import '../bloc/restore_password_state.dart';
|
||||
import '../bloc/change_password_bloc.dart';
|
||||
import '../bloc/change_password_event.dart';
|
||||
import '../bloc/change_password_state.dart';
|
||||
|
||||
class RestorePasswordBottomSection extends StatelessWidget {
|
||||
const RestorePasswordBottomSection({
|
||||
@@ -23,21 +21,18 @@ class RestorePasswordBottomSection extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final radioBloc = context.read<RadioBloc>();
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
BlocConsumer<RestorePasswordBloc, RestorePasswordState>(
|
||||
BlocConsumer<ChangePasswordBloc, ChangePasswordState>(
|
||||
listener: (context, state) {
|
||||
if (state is RestorePasswordLoading) {
|
||||
if (state is ChangePasswordLoading) {
|
||||
Loader.loader(context);
|
||||
} else if (state is RestorePasswordSuccess) {
|
||||
successToastMessage(context, "Password resetted successful !");
|
||||
} else if (state is ChangePasswordSuccess) {
|
||||
successToastMessage(context, "Password changed successful !");
|
||||
goRouter.pop();
|
||||
radioBloc.resetSelection();
|
||||
goRouter.goNamed(RouteName.loginScreen, pathParameters: {
|
||||
"fromScreen": "registerStep",
|
||||
});
|
||||
} else if (state is RestorePasswordFailure) {
|
||||
goRouter.pop();
|
||||
} else if (state is ChangePasswordFailure) {
|
||||
goRouter.pop();
|
||||
errorToastMessage(
|
||||
context,
|
||||
@@ -47,10 +42,10 @@ class RestorePasswordBottomSection extends StatelessWidget {
|
||||
},
|
||||
builder: (context, state) {
|
||||
bool isButtonEnabled = false;
|
||||
if (state is RestorePasswordFieldsState) {
|
||||
if (state is ChangePasswordFieldsState) {
|
||||
isButtonEnabled = state.areFieldsFilled;
|
||||
} else if (state is RestorePasswordSuccess ||
|
||||
state is RestorePasswordFailure) {
|
||||
} else if (state is ChangePasswordSuccess ||
|
||||
state is ChangePasswordFailure) {
|
||||
isButtonEnabled = true;
|
||||
}
|
||||
return Container(
|
||||
@@ -65,13 +60,21 @@ class RestorePasswordBottomSection extends StatelessWidget {
|
||||
: AppColor.inactiveBtnTxtColor,
|
||||
function: () {
|
||||
isButtonEnabled
|
||||
? context.read<RestorePasswordBloc>().add(
|
||||
RestorePasswordSubmitted(
|
||||
context
|
||||
.read<RestorePasswordBloc>()
|
||||
.passwordTextField
|
||||
.text,
|
||||
""),
|
||||
? context.read<ChangePasswordBloc>().add(
|
||||
ChangePasswordSubmitted(
|
||||
context
|
||||
.read<ChangePasswordBloc>()
|
||||
.currentPasswordTextField
|
||||
.text,
|
||||
context
|
||||
.read<ChangePasswordBloc>()
|
||||
.passwordTextField
|
||||
.text,
|
||||
context
|
||||
.read<ChangePasswordBloc>()
|
||||
.repeatPasswordTextField
|
||||
.text,
|
||||
),
|
||||
)
|
||||
: null;
|
||||
},
|
||||
@@ -2,17 +2,22 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:tanami_app/core/styles/app_text.dart';
|
||||
import 'package:tanami_app/features/forgotPassword/presentation/bloc/restore_password_bloc.dart';
|
||||
|
||||
import '../../../../core/routes/route_name.dart';
|
||||
import '../../../../core/routes/routes.dart';
|
||||
import '../../../../core/styles/app_color.dart';
|
||||
import '../../../../shared/components/bloc/password_field/password_visibility_bloc.dart';
|
||||
import '../../../../shared/components/button_widget.dart';
|
||||
import '../../../../shared/components/form_label_textfield.dart';
|
||||
import '../../../../shared/components/text_widget.dart';
|
||||
import '../bloc/change_password_bloc.dart';
|
||||
|
||||
class RestorePasswordForm extends StatelessWidget {
|
||||
const RestorePasswordForm({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final restorePasswordBloc = context.read<RestorePasswordBloc>();
|
||||
final restorePasswordBloc = context.read<ChangePasswordBloc>();
|
||||
|
||||
// Reset fields when the screen is built
|
||||
restorePasswordBloc.resetFields();
|
||||
@@ -33,7 +38,18 @@ class RestorePasswordForm extends StatelessWidget {
|
||||
create: (_) => PasswordVisibilityBloc(),
|
||||
child: FormLabelTextField(
|
||||
hintText: AppText.enterPassword,
|
||||
title: AppText.password,
|
||||
title: AppText.currentPsswordText,
|
||||
type: AppText.password.toLowerCase(),
|
||||
textEditingController:
|
||||
restorePasswordBloc.currentPasswordTextField,
|
||||
),
|
||||
),
|
||||
const Gap(12),
|
||||
BlocProvider(
|
||||
create: (_) => PasswordVisibilityBloc(),
|
||||
child: FormLabelTextField(
|
||||
hintText: AppText.enterPassword,
|
||||
title: AppText.newPasswordText,
|
||||
type: AppText.password.toLowerCase(),
|
||||
textEditingController: restorePasswordBloc.passwordTextField,
|
||||
),
|
||||
@@ -42,13 +58,26 @@ class RestorePasswordForm extends StatelessWidget {
|
||||
BlocProvider(
|
||||
create: (_) => PasswordVisibilityBloc(),
|
||||
child: FormLabelTextField(
|
||||
hintText: AppText.repeatPasswordText,
|
||||
hintText: AppText.enterPassword,
|
||||
title: AppText.repeatPasswordText,
|
||||
type: AppText.password.toLowerCase(),
|
||||
textEditingController:
|
||||
restorePasswordBloc.repeatPasswordTextField,
|
||||
),
|
||||
),
|
||||
const Gap(12),
|
||||
Align(
|
||||
alignment: Alignment.topRight,
|
||||
child: ButtonWidget().textBtn(
|
||||
function: () {
|
||||
goRouter.pushNamed(
|
||||
RouteName.forgotPasswordPhoneVerificationScreen);
|
||||
},
|
||||
text: TextWidget().text15W400(AppText.forgorPassword,
|
||||
clr: AppColor.forgotPassButtonColor,
|
||||
textDecoration: TextDecoration.underline)),
|
||||
),
|
||||
const Gap(20),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -1,41 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:tanami_app/core/styles/app_color.dart';
|
||||
import 'package:tanami_app/core/styles/app_images.dart';
|
||||
import 'package:tanami_app/core/styles/app_text.dart';
|
||||
import 'package:tanami_app/shared/components/text_widget.dart';
|
||||
|
||||
class RestorePasswordTopSection extends StatelessWidget {
|
||||
const RestorePasswordTopSection({
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
const Gap(85),
|
||||
Center(
|
||||
child: SvgPicture.asset(
|
||||
AppImages.weclomeLogo,
|
||||
),
|
||||
),
|
||||
const Gap(60),
|
||||
TextWidget().text20W700(
|
||||
AppText.restorePasswordText,
|
||||
clr: AppColor.charcoalColor,
|
||||
),
|
||||
const Gap(10),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 75),
|
||||
child: TextWidget().text14W500(
|
||||
AppText.createNewPasswordText,
|
||||
clr: AppColor.smokeGrayColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:tanami_app/core/styles/app_text.dart';
|
||||
|
||||
import '../../../../core/utils/secure/secure_storage_service.dart';
|
||||
|
||||
part 'pin_event.dart';
|
||||
@@ -12,13 +11,20 @@ class PinBloc extends Bloc<PinEvent, PinState> {
|
||||
|
||||
PinBloc({required this.secureStorageService})
|
||||
: super(const PinState(
|
||||
pin: '', pinComplete: false, isVerified: false, error: '')) {
|
||||
pin: '',
|
||||
pinComplete: false,
|
||||
isVerified: false,
|
||||
error: '',
|
||||
verifiedOnce: false)) {
|
||||
on<NumberPressed>((event, emit) {
|
||||
final newPin = state.pin + event.number;
|
||||
|
||||
if (newPin.length <= 6) {
|
||||
emit(state.copyWith(
|
||||
pin: newPin, pinComplete: newPin.length == 6, error: ''));
|
||||
pin: newPin,
|
||||
pinComplete: newPin.length == 6,
|
||||
error: '',
|
||||
verifiedOnce: false));
|
||||
|
||||
if (newPin.length == 6) {
|
||||
add(VerifyPinPressed(newPin));
|
||||
@@ -30,7 +36,10 @@ class PinBloc extends Bloc<PinEvent, PinState> {
|
||||
if (state.pin.isNotEmpty) {
|
||||
final newPin = state.pin.substring(0, state.pin.length - 1);
|
||||
emit(state.copyWith(
|
||||
pin: newPin, pinComplete: newPin.length == 6, error: ''));
|
||||
pin: newPin,
|
||||
pinComplete: newPin.length == 6,
|
||||
error: '',
|
||||
verifiedOnce: false));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -42,11 +51,12 @@ class PinBloc extends Bloc<PinEvent, PinState> {
|
||||
final storedPin = await secureStorageService.read('pin_code');
|
||||
|
||||
if (storedPin == event.pin) {
|
||||
emit(state.copyWith(isVerified: true, error: ''));
|
||||
emit(state.copyWith(isVerified: true, error: '', verifiedOnce: true));
|
||||
} else {
|
||||
emit(state.copyWith(
|
||||
isVerified: false,
|
||||
error: AppText.incorrectPinCode,
|
||||
verifiedOnce: true,
|
||||
));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -5,12 +5,14 @@ class PinState extends Equatable {
|
||||
final bool pinComplete;
|
||||
final bool isVerified;
|
||||
final String error;
|
||||
final bool verifiedOnce; // New variable to prevent double listener calls
|
||||
|
||||
const PinState({
|
||||
required this.pin,
|
||||
required this.pinComplete,
|
||||
required this.isVerified,
|
||||
required this.error,
|
||||
required this.verifiedOnce,
|
||||
});
|
||||
|
||||
PinState copyWith({
|
||||
@@ -18,15 +20,17 @@ class PinState extends Equatable {
|
||||
bool? pinComplete,
|
||||
bool? isVerified,
|
||||
String? error,
|
||||
bool? verifiedOnce,
|
||||
}) {
|
||||
return PinState(
|
||||
pin: pin ?? this.pin,
|
||||
pinComplete: pinComplete ?? this.pinComplete,
|
||||
isVerified: isVerified ?? this.isVerified,
|
||||
error: error ?? this.error,
|
||||
verifiedOnce: verifiedOnce ?? this.verifiedOnce,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object> get props => [pin, pinComplete, isVerified, error];
|
||||
List<Object> get props => [pin, pinComplete, isVerified, error, verifiedOnce];
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
@@ -26,10 +28,13 @@ class PinKey extends StatelessWidget {
|
||||
const Gap(20),
|
||||
BlocConsumer<PinBloc, PinState>(
|
||||
listener: (context, state) {
|
||||
if (state.pinComplete) {
|
||||
if (state.pinComplete &&
|
||||
state.error.isEmpty &&
|
||||
!state.verifiedOnce) {
|
||||
if (fromScreen == "login") {
|
||||
goRouter.pushNamed(RouteName.mainScreen);
|
||||
} else if (fromScreen == "reset-pin") {
|
||||
log("Running this");
|
||||
successToastMessage(context, AppText.pinUpdatedSucess);
|
||||
goRouter.pop();
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user