added pinput package for better ux of enter otp and added back button in otp,set password and set otp screen
This commit is contained in:
@@ -62,6 +62,29 @@ class _ForgotPasswordPageState extends State<ForgotPasswordPage> {
|
||||
behavior: HitTestBehavior.translucent,
|
||||
child: Scaffold(
|
||||
backgroundColor: AppColors.backgroundWhite,
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.transparent,
|
||||
elevation: 0,
|
||||
leadingWidth: 70.w,
|
||||
leading: Padding(
|
||||
padding: EdgeInsets.only(left: 24.w, top: 8.h, bottom: 8.h),
|
||||
child: InkWell(
|
||||
onTap: () => Navigator.pop(context),
|
||||
borderRadius: BorderRadius.circular(50),
|
||||
child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
color: AppColors.primaryRed,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Icon(
|
||||
Icons.arrow_back_ios_new,
|
||||
color: Colors.white,
|
||||
size: 18.sp,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
body: BlocConsumer<ForgotPasswordBloc, ForgotPasswordState>(
|
||||
listener: (context, state) {
|
||||
if (state.status == ForgotPasswordStatus.success) {
|
||||
@@ -97,7 +120,7 @@ class _ForgotPasswordPageState extends State<ForgotPasswordPage> {
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(height: 40.h),
|
||||
SizedBox(height: 10.h),
|
||||
// ===== LOGO SECTION =====
|
||||
Center(
|
||||
child: Column(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_otp_text_field/flutter_otp_text_field.dart';
|
||||
import 'package:pinput/pinput.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import '../../constants/app_assets.dart';
|
||||
@@ -21,7 +21,30 @@ class OtpVerificationPage extends StatelessWidget {
|
||||
behavior: HitTestBehavior.translucent,
|
||||
child: Scaffold(
|
||||
backgroundColor: AppColors.backgroundWhite,
|
||||
body: BlocConsumer<VerifyOtpBloc, VerifyOtpState>(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.transparent,
|
||||
elevation: 0,
|
||||
leadingWidth: 70.w,
|
||||
leading: Padding(
|
||||
padding: EdgeInsets.only(left: 24.w, top: 8.h, bottom: 8.h),
|
||||
child: InkWell(
|
||||
onTap: () => Navigator.pop(context),
|
||||
borderRadius: BorderRadius.circular(50),
|
||||
child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
color: AppColors.primaryRed,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Icon(
|
||||
Icons.arrow_back_ios_new,
|
||||
color: Colors.white,
|
||||
size: 18.sp,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
body: BlocListener<VerifyOtpBloc, VerifyOtpState>(
|
||||
listener: (context, state) {
|
||||
if (state.status == VerifyOtpStatus.success) {
|
||||
Navigator.pushReplacementNamed(
|
||||
@@ -39,122 +62,149 @@ class OtpVerificationPage extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
final isLoading = state.status == VerifyOtpStatus.loading;
|
||||
|
||||
return SafeArea(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 24.w),
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(height: 40.h),
|
||||
// ===== LOGO SECTION =====
|
||||
Center(
|
||||
child: Column(
|
||||
children: [
|
||||
Image.asset(
|
||||
AppAssets.appIcon,
|
||||
height: 60.h,
|
||||
child: SafeArea(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 24.w),
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(height: 10.h),
|
||||
// ===== LOGO SECTION =====
|
||||
Center(
|
||||
child: Column(
|
||||
children: [
|
||||
Image.asset(
|
||||
AppAssets.appIcon,
|
||||
height: 60.h,
|
||||
),
|
||||
SizedBox(height: 8.h),
|
||||
Text(
|
||||
"Partner's App",
|
||||
style: GoogleFonts.poppins(
|
||||
color: AppColors.primaryRed,
|
||||
fontSize: 20.sp,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
SizedBox(height: 8.h),
|
||||
Text(
|
||||
"Partner's App",
|
||||
style: GoogleFonts.poppins(
|
||||
color: AppColors.primaryRed,
|
||||
fontSize: 20.sp,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 60.h),
|
||||
),
|
||||
SizedBox(height: 60.h),
|
||||
|
||||
// ===== HEADER TEXT =====
|
||||
Text(
|
||||
"Verify OTP",
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.poppins(
|
||||
color: AppColors.black,
|
||||
fontSize: 24.sp,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
// ===== HEADER TEXT =====
|
||||
Text(
|
||||
"Verify OTP",
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.poppins(
|
||||
color: AppColors.black,
|
||||
fontSize: 24.sp,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
SizedBox(height: 12.h),
|
||||
Text(
|
||||
"We've sent an OTP to your registered email. Please enter it below.",
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.poppins(
|
||||
color: AppColors.textGrey,
|
||||
fontSize: 16.sp,
|
||||
height: 1.4,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 12.h),
|
||||
Text(
|
||||
"We've sent an OTP to your registered email. Please enter it below.",
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.poppins(
|
||||
color: AppColors.textGrey,
|
||||
fontSize: 16.sp,
|
||||
height: 1.4,
|
||||
),
|
||||
SizedBox(height: 48.h),
|
||||
),
|
||||
SizedBox(height: 48.h),
|
||||
|
||||
// ===== OTP INPUT FIELDS =====
|
||||
OtpTextField(
|
||||
numberOfFields: 6,
|
||||
borderColor: AppColors.borderGrey,
|
||||
focusedBorderColor: AppColors.primaryRed,
|
||||
showFieldAsBox: true,
|
||||
fieldWidth: 45.w,
|
||||
borderRadius: BorderRadius.circular(12.r),
|
||||
enabledBorderColor: AppColors.borderGrey,
|
||||
cursorColor: AppColors.primaryRed,
|
||||
// ===== OTP INPUT FIELDS =====
|
||||
Pinput(
|
||||
length: 6,
|
||||
defaultPinTheme: PinTheme(
|
||||
width: 48.w,
|
||||
height: 52.h,
|
||||
textStyle: GoogleFonts.poppins(
|
||||
fontSize: 18.sp,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColors.black,
|
||||
),
|
||||
onCodeChanged: (String code) {
|
||||
context.read<VerifyOtpBloc>().add(
|
||||
OtpChanged(otp: code),
|
||||
);
|
||||
},
|
||||
onSubmit: (String verificationCode) {
|
||||
if (isLoading) return;
|
||||
context.read<VerifyOtpBloc>().add(
|
||||
OtpChanged(otp: verificationCode),
|
||||
);
|
||||
context.read<VerifyOtpBloc>().add(
|
||||
VerifyOtpSubmitted(
|
||||
emailAddress: email,
|
||||
otp: verificationCode,
|
||||
),
|
||||
);
|
||||
},
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12.r),
|
||||
border: Border.all(color: AppColors.borderGrey),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// ===== VERIFY BUTTON =====
|
||||
CustomButton(
|
||||
text: "Verify",
|
||||
isLoading: isLoading,
|
||||
onPressed: state.otp.length == 6 && !isLoading
|
||||
? () {
|
||||
focusedPinTheme: PinTheme(
|
||||
width: 48.w,
|
||||
height: 52.h,
|
||||
textStyle: GoogleFonts.poppins(
|
||||
fontSize: 18.sp,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColors.black,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12.r),
|
||||
border: Border.all(color: AppColors.primaryRed),
|
||||
),
|
||||
),
|
||||
submittedPinTheme: PinTheme(
|
||||
width: 48.w,
|
||||
height: 52.h,
|
||||
textStyle: GoogleFonts.poppins(
|
||||
fontSize: 18.sp,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColors.black,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12.r),
|
||||
border: Border.all(color: AppColors.borderGrey),
|
||||
),
|
||||
),
|
||||
onChanged: (String code) {
|
||||
context.read<VerifyOtpBloc>().add(
|
||||
OtpChanged(otp: code),
|
||||
);
|
||||
},
|
||||
onCompleted: (String verificationCode) {
|
||||
context.read<VerifyOtpBloc>().add(
|
||||
VerifyOtpSubmitted(
|
||||
emailAddress: email,
|
||||
otp: state.otp,
|
||||
otp: verificationCode,
|
||||
),
|
||||
);
|
||||
}
|
||||
: null,
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 24.h),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
// ===== VERIFY BUTTON =====
|
||||
BlocBuilder<VerifyOtpBloc, VerifyOtpState>(
|
||||
buildWhen: (previous, current) =>
|
||||
previous.otp.length != current.otp.length ||
|
||||
previous.status != current.status,
|
||||
builder: (context, state) {
|
||||
final isLoading = state.status == VerifyOtpStatus.loading;
|
||||
return CustomButton(
|
||||
text: "Verify",
|
||||
isLoading: isLoading,
|
||||
onPressed: state.otp.length == 6 && !isLoading
|
||||
? () {
|
||||
context.read<VerifyOtpBloc>().add(
|
||||
VerifyOtpSubmitted(
|
||||
emailAddress: email,
|
||||
otp: state.otp,
|
||||
),
|
||||
);
|
||||
}
|
||||
: null,
|
||||
);
|
||||
},
|
||||
),
|
||||
SizedBox(height: 24.h),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -70,6 +70,29 @@ class _ResetPasswordPageState extends State<ResetPasswordPage> {
|
||||
behavior: HitTestBehavior.translucent,
|
||||
child: Scaffold(
|
||||
backgroundColor: AppColors.backgroundWhite,
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.transparent,
|
||||
elevation: 0,
|
||||
leadingWidth: 70.w,
|
||||
leading: Padding(
|
||||
padding: EdgeInsets.only(left: 24.w, top: 8.h, bottom: 8.h),
|
||||
child: InkWell(
|
||||
onTap: () => Navigator.pop(context),
|
||||
borderRadius: BorderRadius.circular(50),
|
||||
child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
color: AppColors.primaryRed,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Icon(
|
||||
Icons.arrow_back_ios_new,
|
||||
color: Colors.white,
|
||||
size: 18.sp,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
body: BlocConsumer<ResetPasswordBloc, ResetPasswordState>(
|
||||
listener: (context, state) {
|
||||
if (state.status == ResetPasswordStatus.success) {
|
||||
@@ -105,7 +128,7 @@ class _ResetPasswordPageState extends State<ResetPasswordPage> {
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(height: 40.h),
|
||||
SizedBox(height: 10.h),
|
||||
// ===== LOGO SECTION =====
|
||||
Center(
|
||||
child: Column(
|
||||
|
||||
Reference in New Issue
Block a user