feat:verify your account page ui done

This commit is contained in:
jahongireshonqulov
2025-11-01 18:33:03 +05:00
parent 0b562d1dcc
commit c5a6c2dbed
21 changed files with 765 additions and 23 deletions

View File

@@ -35,6 +35,25 @@
"discover": "Discover", "discover": "Discover",
"cart": "Cart", "cart": "Cart",
"transactions": "Transactions", "transactions": "Transactions",
"profile": "Profile" "profile": "Profile",
"forgotPassword": "Forgot Password",
"forgotPasswordSubtitle": "Please enter your phone number to reset your password.",
"phoneNumber": "Phone Number",
"sendCode": "Send Code",
"verifyYourAccount": "Verify Your Account",
"verifyAccountSubtitle": "Weve sent a verification code to",
"verifyAccount": "Verify Account",
"didNotReceiveCode": "Didnt receive the code?",
"resend": "Resend",
"createNewPassword": "Create New Password",
"createNewPasswordSubtitle": "Please create your new password.",
"oldPassword": "Old Password",
"newPassword": "New Password",
"confirmNewPassword": "Confirm New Password",
"passwordHint": "*Password must have at least 8 characters, including number and symbol.",
"resetPassword": "Reset Password",
"changePasswordSuccess": "Change Password Success",
"changePasswordMessage": "We have updated your password. Please remember your password, thank you!",
"login": "Login"
} }

View File

@@ -35,6 +35,25 @@
"discover": "Обзор", "discover": "Обзор",
"cart": "Корзина", "cart": "Корзина",
"transactions": "Транзакции", "transactions": "Транзакции",
"profile": "Профиль" "profile": "Профиль",
"forgotPassword": "Забыли пароль",
"forgotPasswordSubtitle": "Пожалуйста, введите свой номер телефона, чтобы сбросить пароль.",
"phoneNumber": "Номер телефона",
"sendCode": "Отправить код",
"verifyYourAccount": "Подтвердите аккаунт",
"verifyAccountSubtitle": "Мы отправили код подтверждения на",
"verifyAccount": "Подтвердить",
"didNotReceiveCode": "Не получили код?",
"resend": "Отправить повторно",
"createNewPassword": "Создайте новый пароль",
"createNewPasswordSubtitle": "Пожалуйста, создайте новый пароль.",
"oldPassword": "Старый пароль",
"newPassword": "Новый пароль",
"confirmNewPassword": "Подтвердите пароль",
"passwordHint": "*Пароль должен содержать не менее 8 символов, включая цифры и символы.",
"resetPassword": "Сбросить пароль",
"changePasswordSuccess": "Пароль успешно изменён",
"changePasswordMessage": "Ваш пароль был обновлён. Пожалуйста, запомните его. Спасибо!",
"login": "Войти"
} }

View File

@@ -35,6 +35,25 @@
"discover": "Kashf etish", "discover": "Kashf etish",
"cart": "Savat", "cart": "Savat",
"transactions": "Tranzaksiyalar", "transactions": "Tranzaksiyalar",
"profile": "Profil" "profile": "Profil",
"forgotPassword": "Parolni unutdingizmi",
"forgotPasswordSubtitle": "Parolingizni tiklash uchun telefon raqamingizni kiriting.",
"phoneNumber": "Telefon raqami",
"sendCode": "Kod yuborish",
"verifyYourAccount": "Hisobni tasdiqlang",
"verifyAccountSubtitle": "Tasdiqlash kodi quyidagi raqamga yuborildi",
"verifyAccount": "Hisobni tasdiqlash",
"didNotReceiveCode": "Kod kelmadimi?",
"resend": "Qayta yuborish",
"createNewPassword": "Yangi parol yarating",
"createNewPasswordSubtitle": "Iltimos, yangi parolingizni yarating.",
"oldPassword": "Eski parol",
"newPassword": "Yangi parol",
"confirmNewPassword": "Parolni tasdiqlang",
"passwordHint": "*Parol kamida 8 ta belgi, raqam va belgidan iborat bolishi kerak.",
"resetPassword": "Parolni tiklash",
"changePasswordSuccess": "Parol muvaffaqiyatli ozgartirildi",
"changePasswordMessage": "Parolingiz yangilandi. Iltimos, uni eslab qoling. Rahmat!",
"login": "Kirish"
} }

View File

@@ -0,0 +1,22 @@
class StringHelpers {
static String formatUzbekPhoneNumber(String input) {
final digits = input.replaceAll(RegExp(r'\D'), '');
String formatted = digits;
if (formatted.startsWith('998')) {
formatted = formatted.substring(3);
} else if (formatted.startsWith('8')) {
formatted = formatted.substring(1);
}
final buffer = StringBuffer('+998 ');
for (int i = 0; i < formatted.length && i < 9; i++) {
buffer.write(formatted[i]);
if (i == 1 || i == 4 || i == 6) {
buffer.write(' ');
}
}
return buffer.toString().trim();
}
}

View File

@@ -279,6 +279,114 @@ abstract class AppLocalizations {
/// In en, this message translates to: /// In en, this message translates to:
/// **'Profile'** /// **'Profile'**
String get profile; String get profile;
/// No description provided for @forgotPassword.
///
/// In en, this message translates to:
/// **'Forgot Password'**
String get forgotPassword;
/// No description provided for @forgotPasswordSubtitle.
///
/// In en, this message translates to:
/// **'Please enter your phone number to reset your password.'**
String get forgotPasswordSubtitle;
/// No description provided for @phoneNumber.
///
/// In en, this message translates to:
/// **'Phone Number'**
String get phoneNumber;
/// No description provided for @sendCode.
///
/// In en, this message translates to:
/// **'Send Code'**
String get sendCode;
/// No description provided for @verifyYourAccount.
///
/// In en, this message translates to:
/// **'Verify Your Account'**
String get verifyYourAccount;
/// No description provided for @verifyAccountSubtitle.
///
/// In en, this message translates to:
/// **'Weve sent a verification code to'**
String get verifyAccountSubtitle;
/// No description provided for @verifyAccount.
///
/// In en, this message translates to:
/// **'Verify Account'**
String get verifyAccount;
/// No description provided for @didNotReceiveCode.
///
/// In en, this message translates to:
/// **'Didnt receive the code?'**
String get didNotReceiveCode;
/// No description provided for @resend.
///
/// In en, this message translates to:
/// **'Resend'**
String get resend;
/// No description provided for @createNewPassword.
///
/// In en, this message translates to:
/// **'Create New Password'**
String get createNewPassword;
/// No description provided for @createNewPasswordSubtitle.
///
/// In en, this message translates to:
/// **'Please create your new password.'**
String get createNewPasswordSubtitle;
/// No description provided for @oldPassword.
///
/// In en, this message translates to:
/// **'Old Password'**
String get oldPassword;
/// No description provided for @newPassword.
///
/// In en, this message translates to:
/// **'New Password'**
String get newPassword;
/// No description provided for @confirmNewPassword.
///
/// In en, this message translates to:
/// **'Confirm New Password'**
String get confirmNewPassword;
/// No description provided for @passwordHint.
///
/// In en, this message translates to:
/// **'*Password must have at least 8 characters, including number and symbol.'**
String get passwordHint;
/// No description provided for @resetPassword.
///
/// In en, this message translates to:
/// **'Reset Password'**
String get resetPassword;
/// No description provided for @changePasswordSuccess.
///
/// In en, this message translates to:
/// **'Change Password Success'**
String get changePasswordSuccess;
/// No description provided for @changePasswordMessage.
///
/// In en, this message translates to:
/// **'We have updated your password. Please remember your password, thank you!'**
String get changePasswordMessage;
} }
class _AppLocalizationsDelegate class _AppLocalizationsDelegate

View File

@@ -105,4 +105,61 @@ class AppLocalizationsEn extends AppLocalizations {
@override @override
String get profile => 'Profile'; String get profile => 'Profile';
@override
String get forgotPassword => 'Forgot Password';
@override
String get forgotPasswordSubtitle =>
'Please enter your phone number to reset your password.';
@override
String get phoneNumber => 'Phone Number';
@override
String get sendCode => 'Send Code';
@override
String get verifyYourAccount => 'Verify Your Account';
@override
String get verifyAccountSubtitle => 'Weve sent a verification code to';
@override
String get verifyAccount => 'Verify Account';
@override
String get didNotReceiveCode => 'Didnt receive the code?';
@override
String get resend => 'Resend';
@override
String get createNewPassword => 'Create New Password';
@override
String get createNewPasswordSubtitle => 'Please create your new password.';
@override
String get oldPassword => 'Old Password';
@override
String get newPassword => 'New Password';
@override
String get confirmNewPassword => 'Confirm New Password';
@override
String get passwordHint =>
'*Password must have at least 8 characters, including number and symbol.';
@override
String get resetPassword => 'Reset Password';
@override
String get changePasswordSuccess => 'Change Password Success';
@override
String get changePasswordMessage =>
'We have updated your password. Please remember your password, thank you!';
} }

View File

@@ -103,4 +103,61 @@ class AppLocalizationsRu extends AppLocalizations {
@override @override
String get profile => 'Профиль'; String get profile => 'Профиль';
@override
String get forgotPassword => 'Забыли пароль';
@override
String get forgotPasswordSubtitle =>
'Пожалуйста, введите свой номер телефона, чтобы сбросить пароль.';
@override
String get phoneNumber => 'Номер телефона';
@override
String get sendCode => 'Отправить код';
@override
String get verifyYourAccount => 'Подтвердите аккаунт';
@override
String get verifyAccountSubtitle => 'Мы отправили код подтверждения на';
@override
String get verifyAccount => 'Подтвердить';
@override
String get didNotReceiveCode => 'Не получили код?';
@override
String get resend => 'Отправить повторно';
@override
String get createNewPassword => 'Создайте новый пароль';
@override
String get createNewPasswordSubtitle => 'Пожалуйста, создайте новый пароль.';
@override
String get oldPassword => 'Старый пароль';
@override
String get newPassword => 'Новый пароль';
@override
String get confirmNewPassword => 'Подтвердите пароль';
@override
String get passwordHint =>
'*Пароль должен содержать не менее 8 символов, включая цифры и символы.';
@override
String get resetPassword => 'Сбросить пароль';
@override
String get changePasswordSuccess => 'Пароль успешно изменён';
@override
String get changePasswordMessage =>
'Ваш пароль был обновлён. Пожалуйста, запомните его. Спасибо!';
} }

View File

@@ -103,4 +103,63 @@ class AppLocalizationsUz extends AppLocalizations {
@override @override
String get profile => 'Profil'; String get profile => 'Profil';
@override
String get forgotPassword => 'Parolni unutdingizmi';
@override
String get forgotPasswordSubtitle =>
'Parolingizni tiklash uchun telefon raqamingizni kiriting.';
@override
String get phoneNumber => 'Telefon raqami';
@override
String get sendCode => 'Kod yuborish';
@override
String get verifyYourAccount => 'Hisobni tasdiqlang';
@override
String get verifyAccountSubtitle =>
'Tasdiqlash kodi quyidagi raqamga yuborildi';
@override
String get verifyAccount => 'Hisobni tasdiqlash';
@override
String get didNotReceiveCode => 'Kod kelmadimi?';
@override
String get resend => 'Qayta yuborish';
@override
String get createNewPassword => 'Yangi parol yarating';
@override
String get createNewPasswordSubtitle =>
'Iltimos, yangi parolingizni yarating.';
@override
String get oldPassword => 'Eski parol';
@override
String get newPassword => 'Yangi parol';
@override
String get confirmNewPassword => 'Parolni tasdiqlang';
@override
String get passwordHint =>
'*Parol kamida 8 ta belgi, raqam va belgidan iborat bolishi kerak.';
@override
String get resetPassword => 'Parolni tiklash';
@override
String get changePasswordSuccess => 'Parol muvaffaqiyatli ozgartirildi';
@override
String get changePasswordMessage =>
'Parolingiz yangilandi. Iltimos, uni eslab qoling. Rahmat!';
} }

View File

@@ -1,5 +1,8 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:food_delivery_client/feature/auth/presentation/pages/create_new_password_page/create_new_password_page.dart';
import 'package:food_delivery_client/feature/auth/presentation/pages/forgot_password_page/forgot_password_page.dart';
import 'package:food_delivery_client/feature/auth/presentation/pages/login_page/login_page.dart'; import 'package:food_delivery_client/feature/auth/presentation/pages/login_page/login_page.dart';
import 'package:food_delivery_client/feature/auth/presentation/pages/verify_account_page/verify_account_page.dart';
import 'package:food_delivery_client/feature/onboarding/presentation/pages/onboarding_page/onboarding_page.dart'; import 'package:food_delivery_client/feature/onboarding/presentation/pages/onboarding_page/onboarding_page.dart';
import 'package:food_delivery_client/feature/onboarding/presentation/pages/splash_page/splash_page.dart'; import 'package:food_delivery_client/feature/onboarding/presentation/pages/splash_page/splash_page.dart';
@@ -30,6 +33,23 @@ class AppRoutes {
path: Routes.main, path: Routes.main,
pageBuilder: (context, state) => CupertinoPage(child: MainPage()), pageBuilder: (context, state) => CupertinoPage(child: MainPage()),
), ),
GoRoute(
path: Routes.forgotPassword,
pageBuilder: (context, state) =>
CupertinoPage(child: ForgotPasswordPage()),
),
GoRoute(
path: Routes.verifyAccount,
pageBuilder: (context, state) => CupertinoPage(
child: VerifyAccountPage(phoneNumber: state.extra as String),
),
),
GoRoute(
path: Routes.createNewPassword,
pageBuilder: (context, state) => CupertinoPage(
child: CreateNewPasswordPage(phoneNumber: state.extra as String),
),
),
], ],
); );
} }

View File

@@ -4,12 +4,7 @@ abstract class Routes {
static const String login = '/login'; static const String login = '/login';
static const String register = '/register'; static const String register = '/register';
static const String main = '/main'; static const String main = '/main';
static const String categories = '/categories'; static const String createNewPassword = '/create-new-password';
static const String filters = '/filters'; static const String forgotPassword = '/forgot-password';
static const String browse = '/browse'; static const String verifyAccount = '/verify-account';
static const String forgotPassword = "/forgot-password";
static const String restaurantsByCategory = '/restaurants-by-category';
static const String verifyPhoneNumber = "/verify-phone-number";
static const String verifyOtpCode = "/verify-otp-code";
static const String resetPassword = "/reset-password";
} }

View File

@@ -55,6 +55,5 @@ abstract class AppColors {
static const Color cA7AEC1 = Color(0xFFA7AEC1); static const Color cA7AEC1 = Color(0xFFA7AEC1);
static const Color c151B33 = Color(0xFF151B33); static const Color c151B33 = Color(0xFF151B33);
static const Color cE5E7EB = Color(0xFFE5E7EB); static const Color cE5E7EB = Color(0xFFE5E7EB);
static const Color cE2E8F0 = Color(0xFFE2E8F0);
} }

View File

@@ -11,8 +11,6 @@ class AppThemeColors extends ThemeExtension<AppThemeColors> {
final Color inActiveColor1; final Color inActiveColor1;
final Color inActiveColor2; final Color inActiveColor2;
AppThemeColors({ AppThemeColors({
required this.onBoardingColor, required this.onBoardingColor,
required this.boxShadow, required this.boxShadow,
@@ -22,7 +20,6 @@ class AppThemeColors extends ThemeExtension<AppThemeColors> {
required this.inActiveColor, required this.inActiveColor,
required this.inActiveColor1, required this.inActiveColor1,
required this.inActiveColor2, required this.inActiveColor2,
}); });
static AppThemeColors light = AppThemeColors( static AppThemeColors light = AppThemeColors(
@@ -33,7 +30,7 @@ class AppThemeColors extends ThemeExtension<AppThemeColors> {
borderColor: AppColors.cE2E4EA, borderColor: AppColors.cE2E4EA,
inActiveColor: AppColors.cE2E4EA, inActiveColor: AppColors.cE2E4EA,
inActiveColor1: AppColors.cA9A9A9, inActiveColor1: AppColors.cA9A9A9,
inActiveColor2: AppColors.cE5E7EB inActiveColor2: AppColors.cE5E7EB,
); );
static AppThemeColors dark = AppThemeColors( static AppThemeColors dark = AppThemeColors(
@@ -44,7 +41,7 @@ class AppThemeColors extends ThemeExtension<AppThemeColors> {
borderColor: AppColors.c292F3D, borderColor: AppColors.c292F3D,
inActiveColor: AppColors.c292F3D, inActiveColor: AppColors.c292F3D,
inActiveColor1: AppColors.c626262, inActiveColor1: AppColors.c626262,
inActiveColor2: AppColors.c292F3D inActiveColor2: AppColors.c292F3D,
); );
@override @override
@@ -57,7 +54,6 @@ class AppThemeColors extends ThemeExtension<AppThemeColors> {
Color? inActiveColor, Color? inActiveColor,
Color? inActiveColor1, Color? inActiveColor1,
Color? inActiveColor2, Color? inActiveColor2,
}) { }) {
return AppThemeColors( return AppThemeColors(
onBoardingColor: onBoardingColor ?? this.onBoardingColor, onBoardingColor: onBoardingColor ?? this.onBoardingColor,
@@ -67,7 +63,7 @@ class AppThemeColors extends ThemeExtension<AppThemeColors> {
borderColor: borderColor ?? this.borderColor, borderColor: borderColor ?? this.borderColor,
inActiveColor: inActiveColor ?? this.inActiveColor, inActiveColor: inActiveColor ?? this.inActiveColor,
inActiveColor1: inActiveColor1 ?? this.inActiveColor1, inActiveColor1: inActiveColor1 ?? this.inActiveColor1,
inActiveColor2: inActiveColor2??this.inActiveColor2 inActiveColor2: inActiveColor2 ?? this.inActiveColor2,
); );
} }

View File

@@ -5,6 +5,8 @@ import 'package:food_delivery_client/core/core.dart';
class AppThemeTextStyles extends ThemeExtension<AppThemeTextStyles> { class AppThemeTextStyles extends ThemeExtension<AppThemeTextStyles> {
//Regular fonts //Regular fonts
final TextStyle size14Regular; final TextStyle size14Regular;
final TextStyle size14Regular1;
//Medium //Medium
@@ -14,6 +16,8 @@ class AppThemeTextStyles extends ThemeExtension<AppThemeTextStyles> {
final TextStyle size16SemiBold; final TextStyle size16SemiBold;
final TextStyle size24SemiBold; final TextStyle size24SemiBold;
final TextStyle size24SemiBold1;
//Bold //Bold
@@ -25,9 +29,11 @@ class AppThemeTextStyles extends ThemeExtension<AppThemeTextStyles> {
AppThemeTextStyles({ AppThemeTextStyles({
required this.size14Regular, required this.size14Regular,
required this.size14Regular1,
required this.size16Medium, required this.size16Medium,
required this.size16SemiBold, required this.size16SemiBold,
required this.size24SemiBold, required this.size24SemiBold,
required this.size24SemiBold1,
required this.size14Bold, required this.size14Bold,
required this.size24Bold, required this.size24Bold,
required this.size64Black, required this.size64Black,
@@ -47,6 +53,13 @@ class AppThemeTextStyles extends ThemeExtension<AppThemeTextStyles> {
fontFamily: _fontRegular, fontFamily: _fontRegular,
color: AppColors.c151B33, color: AppColors.c151B33,
), ),
size14Regular1: TextStyle(
fontSize: 14,
height: 1.6,
fontWeight: FontWeight.w400,
fontFamily: _fontRegular,
color: AppColors.c151B33,
),
size16Medium: TextStyle( size16Medium: TextStyle(
fontSize: 16, fontSize: 16,
height: 1.3, height: 1.3,
@@ -67,6 +80,14 @@ class AppThemeTextStyles extends ThemeExtension<AppThemeTextStyles> {
fontFamily: _fontSemiBold, fontFamily: _fontSemiBold,
color: AppColors.c1A202C, color: AppColors.c1A202C,
), ),
size24SemiBold1: TextStyle(
fontSize: 24,
height: 1.25,
letterSpacing: -.48,
fontWeight: FontWeight.w600,
fontFamily: _fontSemiBold,
color: AppColors.c000000,
),
size14Bold: TextStyle( size14Bold: TextStyle(
fontSize: 14, fontSize: 14,
fontWeight: FontWeight.w700, fontWeight: FontWeight.w700,
@@ -95,6 +116,13 @@ class AppThemeTextStyles extends ThemeExtension<AppThemeTextStyles> {
fontFamily: _fontRegular, fontFamily: _fontRegular,
color: AppColors.cFFFFFF, color: AppColors.cFFFFFF,
), ),
size14Regular1: TextStyle(
fontSize: 14,
height: 1.6,
fontWeight: FontWeight.w400,
fontFamily: _fontRegular,
color: AppColors.cA9A9A9,
),
size16Medium: TextStyle( size16Medium: TextStyle(
fontSize: 16, fontSize: 16,
height: 1.3, height: 1.3,
@@ -115,6 +143,14 @@ class AppThemeTextStyles extends ThemeExtension<AppThemeTextStyles> {
fontFamily: _fontSemiBold, fontFamily: _fontSemiBold,
color: AppColors.cFFFFFF, color: AppColors.cFFFFFF,
), ),
size24SemiBold1: TextStyle(
fontSize: 24,
height: 1.25,
letterSpacing: -.48,
fontWeight: FontWeight.w600,
fontFamily: _fontSemiBold,
color: AppColors.cFFFFFF,
),
size14Bold: TextStyle( size14Bold: TextStyle(
fontSize: 14, fontSize: 14,
fontWeight: FontWeight.w700, fontWeight: FontWeight.w700,
@@ -138,18 +174,22 @@ class AppThemeTextStyles extends ThemeExtension<AppThemeTextStyles> {
@override @override
ThemeExtension<AppThemeTextStyles> copyWith({ ThemeExtension<AppThemeTextStyles> copyWith({
TextStyle? size14Regular, TextStyle? size14Regular,
TextStyle? size14Regular1,
TextStyle? size16Medium, TextStyle? size16Medium,
TextStyle? size16SemiBold, TextStyle? size16SemiBold,
TextStyle? size24SemiBold, TextStyle? size24SemiBold,
TextStyle? size24SemiBold1,
TextStyle? size14Bold, TextStyle? size14Bold,
TextStyle? size24Bold, TextStyle? size24Bold,
TextStyle? size64Black, TextStyle? size64Black,
}) { }) {
return AppThemeTextStyles( return AppThemeTextStyles(
size14Regular: size14Regular ?? this.size14Regular, size14Regular: size14Regular ?? this.size14Regular,
size14Regular1: size14Regular1 ?? this.size14Regular1,
size16Medium: size16Medium ?? this.size16Medium, size16Medium: size16Medium ?? this.size16Medium,
size16SemiBold: size16SemiBold ?? this.size16SemiBold, size16SemiBold: size16SemiBold ?? this.size16SemiBold,
size24SemiBold: size24SemiBold ?? this.size24SemiBold, size24SemiBold: size24SemiBold ?? this.size24SemiBold,
size24SemiBold1: size24SemiBold1 ?? this.size24SemiBold1,
size14Bold: size14Bold ?? this.size14Bold, size14Bold: size14Bold ?? this.size14Bold,
size24Bold: size24Bold ?? this.size24Bold, size24Bold: size24Bold ?? this.size24Bold,
size64Black: size64Black ?? this.size64Black, size64Black: size64Black ?? this.size64Black,
@@ -164,9 +204,11 @@ class AppThemeTextStyles extends ThemeExtension<AppThemeTextStyles> {
if (other is! AppThemeTextStyles) return this; if (other is! AppThemeTextStyles) return this;
return AppThemeTextStyles( return AppThemeTextStyles(
size14Regular: TextStyle.lerp(size14Regular, other.size14Regular, t)!, size14Regular: TextStyle.lerp(size14Regular, other.size14Regular, t)!,
size14Regular1: TextStyle.lerp(size14Regular1, other.size14Regular1, t)!,
size16Medium: TextStyle.lerp(size16Medium, other.size16Medium, t)!, size16Medium: TextStyle.lerp(size16Medium, other.size16Medium, t)!,
size16SemiBold: TextStyle.lerp(size16SemiBold, other.size16SemiBold, t)!, size16SemiBold: TextStyle.lerp(size16SemiBold, other.size16SemiBold, t)!,
size24SemiBold: TextStyle.lerp(size24SemiBold, other.size24SemiBold, t)!, size24SemiBold: TextStyle.lerp(size24SemiBold, other.size24SemiBold, t)!,
size24SemiBold1: TextStyle.lerp(size24SemiBold1, other.size24SemiBold1, t)!,
size14Bold: TextStyle.lerp(size14Bold, other.size14Bold, t)!, size14Bold: TextStyle.lerp(size14Bold, other.size14Bold, t)!,
size24Bold: TextStyle.lerp(size24Bold, other.size24Bold, t)!, size24Bold: TextStyle.lerp(size24Bold, other.size24Bold, t)!,
size64Black: TextStyle.lerp(size64Black, other.size64Black, t)!, size64Black: TextStyle.lerp(size64Black, other.size64Black, t)!,

View File

@@ -0,0 +1,12 @@
import '../../../../../food_delivery_client.dart';
class CreateNewPasswordPage extends StatelessWidget {
const CreateNewPasswordPage({super.key, required this.phoneNumber});
final String phoneNumber;
@override
Widget build(BuildContext context) {
return WLayout(child: Scaffold());
}
}

View File

@@ -0,0 +1,10 @@
import '../../../../../../food_delivery_client.dart';
class CreateNewPasswordBody extends StatelessWidget {
const CreateNewPasswordBody({super.key});
@override
Widget build(BuildContext context) {
return WLayout(child: Scaffold());
}
}

View File

@@ -0,0 +1,12 @@
import 'package:food_delivery_client/feature/auth/presentation/pages/forgot_password_page/widgets/forgot_password_body.dart';
import '../../../../../food_delivery_client.dart';
class ForgotPasswordPage extends StatelessWidget {
const ForgotPasswordPage({super.key});
@override
Widget build(BuildContext context) {
return ForgotPasswordBody();
}
}

View File

@@ -0,0 +1,115 @@
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/common/presentation/widgets/app_text_form_field.dart';
import '../../../../../../food_delivery_client.dart';
class ForgotPasswordBody extends StatefulWidget {
const ForgotPasswordBody({super.key});
@override
State<ForgotPasswordBody> createState() => _ForgotPasswordBodyState();
}
class _ForgotPasswordBodyState extends State<ForgotPasswordBody> {
late final TextEditingController _phoneNumberController;
final _formKey = GlobalKey<FormState>();
bool _isValid = false;
void _validateForm() {
final isValid = _formKey.currentState?.validate() ?? false;
if (isValid != _isValid) {
setState(() {
_isValid = isValid;
});
}
}
@override
void initState() {
_phoneNumberController = TextEditingController();
_phoneNumberController.addListener(_validateForm);
super.initState();
}
@override
void dispose() {
_phoneNumberController.removeListener(_validateForm);
_phoneNumberController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Form(
key: _formKey,
autovalidateMode: AutovalidateMode.onUserInteraction,
child: WLayout(
child: Scaffold(
resizeToAvoidBottomInset: true,
body: SingleChildScrollView(
keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
30.verticalSpace,
WBackButton(),
20.verticalSpace,
Text(
context.loc.forgotPassword,
style: context.appThemeTextStyles.size24Bold,
),
8.verticalSpace,
Text(
context.loc.forgotPasswordSubtitle,
style: AppTextStyles.size14Regular.copyWith(
color: AppColors.cA7AEC1,
height: 1.6,
),
).paddingOnly(right: 50),
30.verticalSpace,
Text(
context.loc.phoneNumber,
style: context.appThemeTextStyles.size16Medium,
),
10.verticalSpace,
AppTextFormField(
controller: _phoneNumberController,
keyBoardType: TextInputType.number,
prefixIcon: Text(
"+ 998",
style: context.appThemeTextStyles.size14Regular,
),
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
Formatters.phoneFormatter,
LengthLimitingTextInputFormatter(12),
],
validator: (value) {
return Validators.validatePhoneNumber(
_phoneNumberController.text.trim(),
);
},
),
100.verticalSpace,
AppButton(
name: context.loc.sendCode,
isActive: _isValid,
onPressed: () {
context.push(
Routes.verifyAccount,
extra:
"+998${_phoneNumberController.text.trim().replaceAll(" ", "")}",
);
if (_formKey.currentState?.validate() ?? false) {}
},
),
],
).paddingSymmetric(horizontal: 24),
),
),
),
);
}
}

View File

@@ -108,7 +108,12 @@ class _WLoginBodyState extends State<WLoginBody> {
), ),
10.verticalSpace, 10.verticalSpace,
AppTextFormField( AppTextFormField(
prefixIcon: Text("+ 998"), prefixIcon: Text(
"+ 998",
style: context
.appThemeTextStyles
.size14Regular,
),
controller: _phoneNumberController, controller: _phoneNumberController,
hintText: context.loc.enter_email_or_phone, hintText: context.loc.enter_email_or_phone,
inputFormatters: [ inputFormatters: [
@@ -143,7 +148,9 @@ class _WLoginBodyState extends State<WLoginBody> {
Align( Align(
alignment: AlignmentGeometry.centerRight, alignment: AlignmentGeometry.centerRight,
child: TextButton( child: TextButton(
onPressed: () {}, onPressed: () {
context.push(Routes.forgotPassword);
},
child: Text( child: Text(
context.loc.forgot_password, context.loc.forgot_password,
style: AppTextStyles.size14Regular style: AppTextStyles.size14Regular

View File

@@ -0,0 +1,13 @@
import 'package:food_delivery_client/feature/auth/presentation/pages/verify_account_page/widgets/verify_account_body.dart';
import '../../../../../food_delivery_client.dart';
class VerifyAccountPage extends StatelessWidget {
const VerifyAccountPage({super.key, required this.phoneNumber});
final String phoneNumber;
@override
Widget build(BuildContext context) {
return VerifyAccountBody(phoneNumber: phoneNumber);
}
}

View File

@@ -0,0 +1,160 @@
import 'package:food_delivery_client/core/helpers/string_helpers.dart';
import 'package:food_delivery_client/core/helpers/validator_helpers.dart';
import 'package:pinput/pinput.dart';
import '../../../../../../food_delivery_client.dart';
class VerifyAccountBody extends StatefulWidget {
const VerifyAccountBody({super.key, required this.phoneNumber});
final String phoneNumber;
@override
State<VerifyAccountBody> createState() => _VerifyAccountBodyState();
}
class _VerifyAccountBodyState extends State<VerifyAccountBody> {
late TextEditingController _otpController;
final _formKey = GlobalKey<FormState>();
bool _isValid = false;
void _formValidator() {
final isValid = _formKey.currentState?.validate() ?? false;
if (_isValid != isValid) {
setState(() {
_isValid = isValid;
});
}
}
@override
void initState() {
_otpController = TextEditingController();
_otpController.addListener(_formValidator);
super.initState();
}
@override
void dispose() {
_otpController.removeListener(_formValidator);
_otpController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final defaultPinTheme = PinTheme(
height: 56,
width: 56,
textStyle: context.appThemeTextStyles.size24SemiBold1,
decoration: BoxDecoration(
border: Border.all(
color: context.appThemeColors.borderColor,
style: BorderStyle.solid,
width: 1,
),
color: context.theme.scaffoldBackgroundColor,
borderRadius: AppUtils.kBorderRadius12,
),
);
return Form(
key: _formKey,
autovalidateMode: AutovalidateMode.onUserInteraction,
child: WLayout(
child: Scaffold(
resizeToAvoidBottomInset: true,
body: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
30.verticalSpace,
WBackButton(),
20.verticalSpace,
Text(
context.loc.verifyYourAccount,
style: context.appThemeTextStyles.size24Bold,
),
8.verticalSpace,
RichText(
text: TextSpan(
text: context.loc.verifyAccountSubtitle,
style: AppTextStyles.size14Regular.copyWith(
color: AppColors.cA7AEC1,
height: 1.6,
),
children: [
TextSpan(text: " "),
TextSpan(
text: StringHelpers.formatUzbekPhoneNumber(
widget.phoneNumber,
),
style: AppTextStyles.size14Regular.copyWith(
color: AppColors.cFF6F00,
),
),
],
),
),
50.verticalSpace,
Pinput(
autofocus: true,
enabled: true,
length: 5,
controller: _otpController,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
keyboardType: TextInputType.number,
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
LengthLimitingTextInputFormatter(5),
],
defaultPinTheme: defaultPinTheme,
focusedPinTheme: defaultPinTheme.copyWith(
decoration: defaultPinTheme.decoration?.copyWith(
border: Border.all(color: AppColors.cFF6F00),
),
),
validator: (value) {
return Validators.validateOtpFields(
_otpController.text.trim(),
);
},
),
90.verticalSpace,
AppButton(
isActive: _isValid,
name: context.loc.verifyAccount,
onPressed: () {},
),
20.verticalSpace,
Align(
alignment: AlignmentGeometry.center,
child: RichText(
text: TextSpan(
text: context.loc.didNotReceiveCode,
style: context.appThemeTextStyles.size14Regular1,
children: [
WidgetSpan(
baseline: TextBaseline.alphabetic,
alignment: PlaceholderAlignment.baseline,
child: TextButton(
onPressed: () {},
child: Text(
context.loc.resend,
style: AppTextStyles.size14Regular.copyWith(
color: AppColors.cFF6F00,
),
),
),
),
],
),
),
),
],
).paddingSymmetric(horizontal: 24),
),
),
),
);
}
}

View File

@@ -62,7 +62,8 @@ class _MyAppState extends State<MyApp> {
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
theme: AppTheme.lightTheme, theme: AppTheme.lightTheme,
darkTheme: AppTheme.darkTheme, darkTheme: AppTheme.darkTheme,
themeMode: themeState.themeMode, themeMode: ThemeMode.dark,
// themeMode: themeState.themeMode,
routerConfig: sl<AppRoutes>().router, routerConfig: sl<AppRoutes>().router,
locale: state.currentLocale, locale: state.currentLocale,
supportedLocales: L10n.locales, supportedLocales: L10n.locales,