feat:verify your account page ui done
This commit is contained in:
22
lib/core/helpers/string_helpers.dart
Normal file
22
lib/core/helpers/string_helpers.dart
Normal 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();
|
||||
}
|
||||
}
|
||||
@@ -279,6 +279,114 @@ abstract class AppLocalizations {
|
||||
/// In en, this message translates to:
|
||||
/// **'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:
|
||||
/// **'We’ve 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:
|
||||
/// **'Didn’t 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
|
||||
|
||||
@@ -105,4 +105,61 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
|
||||
@override
|
||||
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 => 'We’ve sent a verification code to';
|
||||
|
||||
@override
|
||||
String get verifyAccount => 'Verify Account';
|
||||
|
||||
@override
|
||||
String get didNotReceiveCode => 'Didn’t 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!';
|
||||
}
|
||||
|
||||
@@ -103,4 +103,61 @@ class AppLocalizationsRu extends AppLocalizations {
|
||||
|
||||
@override
|
||||
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 =>
|
||||
'Ваш пароль был обновлён. Пожалуйста, запомните его. Спасибо!';
|
||||
}
|
||||
|
||||
@@ -103,4 +103,63 @@ class AppLocalizationsUz extends AppLocalizations {
|
||||
|
||||
@override
|
||||
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 bo‘lishi kerak.';
|
||||
|
||||
@override
|
||||
String get resetPassword => 'Parolni tiklash';
|
||||
|
||||
@override
|
||||
String get changePasswordSuccess => 'Parol muvaffaqiyatli o‘zgartirildi';
|
||||
|
||||
@override
|
||||
String get changePasswordMessage =>
|
||||
'Parolingiz yangilandi. Iltimos, uni eslab qoling. Rahmat!';
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
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/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/splash_page/splash_page.dart';
|
||||
|
||||
@@ -30,6 +33,23 @@ class AppRoutes {
|
||||
path: Routes.main,
|
||||
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),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,12 +4,7 @@ abstract class Routes {
|
||||
static const String login = '/login';
|
||||
static const String register = '/register';
|
||||
static const String main = '/main';
|
||||
static const String categories = '/categories';
|
||||
static const String filters = '/filters';
|
||||
static const String browse = '/browse';
|
||||
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";
|
||||
static const String createNewPassword = '/create-new-password';
|
||||
static const String forgotPassword = '/forgot-password';
|
||||
static const String verifyAccount = '/verify-account';
|
||||
}
|
||||
|
||||
@@ -55,6 +55,5 @@ abstract class AppColors {
|
||||
static const Color cA7AEC1 = Color(0xFFA7AEC1);
|
||||
static const Color c151B33 = Color(0xFF151B33);
|
||||
static const Color cE5E7EB = Color(0xFFE5E7EB);
|
||||
|
||||
|
||||
static const Color cE2E8F0 = Color(0xFFE2E8F0);
|
||||
}
|
||||
|
||||
@@ -11,8 +11,6 @@ class AppThemeColors extends ThemeExtension<AppThemeColors> {
|
||||
final Color inActiveColor1;
|
||||
final Color inActiveColor2;
|
||||
|
||||
|
||||
|
||||
AppThemeColors({
|
||||
required this.onBoardingColor,
|
||||
required this.boxShadow,
|
||||
@@ -22,7 +20,6 @@ class AppThemeColors extends ThemeExtension<AppThemeColors> {
|
||||
required this.inActiveColor,
|
||||
required this.inActiveColor1,
|
||||
required this.inActiveColor2,
|
||||
|
||||
});
|
||||
|
||||
static AppThemeColors light = AppThemeColors(
|
||||
@@ -33,7 +30,7 @@ class AppThemeColors extends ThemeExtension<AppThemeColors> {
|
||||
borderColor: AppColors.cE2E4EA,
|
||||
inActiveColor: AppColors.cE2E4EA,
|
||||
inActiveColor1: AppColors.cA9A9A9,
|
||||
inActiveColor2: AppColors.cE5E7EB
|
||||
inActiveColor2: AppColors.cE5E7EB,
|
||||
);
|
||||
|
||||
static AppThemeColors dark = AppThemeColors(
|
||||
@@ -44,7 +41,7 @@ class AppThemeColors extends ThemeExtension<AppThemeColors> {
|
||||
borderColor: AppColors.c292F3D,
|
||||
inActiveColor: AppColors.c292F3D,
|
||||
inActiveColor1: AppColors.c626262,
|
||||
inActiveColor2: AppColors.c292F3D
|
||||
inActiveColor2: AppColors.c292F3D,
|
||||
);
|
||||
|
||||
@override
|
||||
@@ -57,7 +54,6 @@ class AppThemeColors extends ThemeExtension<AppThemeColors> {
|
||||
Color? inActiveColor,
|
||||
Color? inActiveColor1,
|
||||
Color? inActiveColor2,
|
||||
|
||||
}) {
|
||||
return AppThemeColors(
|
||||
onBoardingColor: onBoardingColor ?? this.onBoardingColor,
|
||||
@@ -67,7 +63,7 @@ class AppThemeColors extends ThemeExtension<AppThemeColors> {
|
||||
borderColor: borderColor ?? this.borderColor,
|
||||
inActiveColor: inActiveColor ?? this.inActiveColor,
|
||||
inActiveColor1: inActiveColor1 ?? this.inActiveColor1,
|
||||
inActiveColor2: inActiveColor2??this.inActiveColor2
|
||||
inActiveColor2: inActiveColor2 ?? this.inActiveColor2,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@ import 'package:food_delivery_client/core/core.dart';
|
||||
class AppThemeTextStyles extends ThemeExtension<AppThemeTextStyles> {
|
||||
//Regular fonts
|
||||
final TextStyle size14Regular;
|
||||
final TextStyle size14Regular1;
|
||||
|
||||
|
||||
//Medium
|
||||
|
||||
@@ -14,6 +16,8 @@ class AppThemeTextStyles extends ThemeExtension<AppThemeTextStyles> {
|
||||
|
||||
final TextStyle size16SemiBold;
|
||||
final TextStyle size24SemiBold;
|
||||
final TextStyle size24SemiBold1;
|
||||
|
||||
|
||||
//Bold
|
||||
|
||||
@@ -25,9 +29,11 @@ class AppThemeTextStyles extends ThemeExtension<AppThemeTextStyles> {
|
||||
|
||||
AppThemeTextStyles({
|
||||
required this.size14Regular,
|
||||
required this.size14Regular1,
|
||||
required this.size16Medium,
|
||||
required this.size16SemiBold,
|
||||
required this.size24SemiBold,
|
||||
required this.size24SemiBold1,
|
||||
required this.size14Bold,
|
||||
required this.size24Bold,
|
||||
required this.size64Black,
|
||||
@@ -47,6 +53,13 @@ class AppThemeTextStyles extends ThemeExtension<AppThemeTextStyles> {
|
||||
fontFamily: _fontRegular,
|
||||
color: AppColors.c151B33,
|
||||
),
|
||||
size14Regular1: TextStyle(
|
||||
fontSize: 14,
|
||||
height: 1.6,
|
||||
fontWeight: FontWeight.w400,
|
||||
fontFamily: _fontRegular,
|
||||
color: AppColors.c151B33,
|
||||
),
|
||||
size16Medium: TextStyle(
|
||||
fontSize: 16,
|
||||
height: 1.3,
|
||||
@@ -67,6 +80,14 @@ class AppThemeTextStyles extends ThemeExtension<AppThemeTextStyles> {
|
||||
fontFamily: _fontSemiBold,
|
||||
color: AppColors.c1A202C,
|
||||
),
|
||||
size24SemiBold1: TextStyle(
|
||||
fontSize: 24,
|
||||
height: 1.25,
|
||||
letterSpacing: -.48,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: _fontSemiBold,
|
||||
color: AppColors.c000000,
|
||||
),
|
||||
size14Bold: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w700,
|
||||
@@ -95,6 +116,13 @@ class AppThemeTextStyles extends ThemeExtension<AppThemeTextStyles> {
|
||||
fontFamily: _fontRegular,
|
||||
color: AppColors.cFFFFFF,
|
||||
),
|
||||
size14Regular1: TextStyle(
|
||||
fontSize: 14,
|
||||
height: 1.6,
|
||||
fontWeight: FontWeight.w400,
|
||||
fontFamily: _fontRegular,
|
||||
color: AppColors.cA9A9A9,
|
||||
),
|
||||
size16Medium: TextStyle(
|
||||
fontSize: 16,
|
||||
height: 1.3,
|
||||
@@ -115,6 +143,14 @@ class AppThemeTextStyles extends ThemeExtension<AppThemeTextStyles> {
|
||||
fontFamily: _fontSemiBold,
|
||||
color: AppColors.cFFFFFF,
|
||||
),
|
||||
size24SemiBold1: TextStyle(
|
||||
fontSize: 24,
|
||||
height: 1.25,
|
||||
letterSpacing: -.48,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: _fontSemiBold,
|
||||
color: AppColors.cFFFFFF,
|
||||
),
|
||||
size14Bold: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w700,
|
||||
@@ -138,18 +174,22 @@ class AppThemeTextStyles extends ThemeExtension<AppThemeTextStyles> {
|
||||
@override
|
||||
ThemeExtension<AppThemeTextStyles> copyWith({
|
||||
TextStyle? size14Regular,
|
||||
TextStyle? size14Regular1,
|
||||
TextStyle? size16Medium,
|
||||
TextStyle? size16SemiBold,
|
||||
TextStyle? size24SemiBold,
|
||||
TextStyle? size24SemiBold1,
|
||||
TextStyle? size14Bold,
|
||||
TextStyle? size24Bold,
|
||||
TextStyle? size64Black,
|
||||
}) {
|
||||
return AppThemeTextStyles(
|
||||
size14Regular: size14Regular ?? this.size14Regular,
|
||||
size14Regular1: size14Regular1 ?? this.size14Regular1,
|
||||
size16Medium: size16Medium ?? this.size16Medium,
|
||||
size16SemiBold: size16SemiBold ?? this.size16SemiBold,
|
||||
size24SemiBold: size24SemiBold ?? this.size24SemiBold,
|
||||
size24SemiBold1: size24SemiBold1 ?? this.size24SemiBold1,
|
||||
size14Bold: size14Bold ?? this.size14Bold,
|
||||
size24Bold: size24Bold ?? this.size24Bold,
|
||||
size64Black: size64Black ?? this.size64Black,
|
||||
@@ -164,9 +204,11 @@ class AppThemeTextStyles extends ThemeExtension<AppThemeTextStyles> {
|
||||
if (other is! AppThemeTextStyles) return this;
|
||||
return AppThemeTextStyles(
|
||||
size14Regular: TextStyle.lerp(size14Regular, other.size14Regular, t)!,
|
||||
size14Regular1: TextStyle.lerp(size14Regular1, other.size14Regular1, t)!,
|
||||
size16Medium: TextStyle.lerp(size16Medium, other.size16Medium, t)!,
|
||||
size16SemiBold: TextStyle.lerp(size16SemiBold, other.size16SemiBold, t)!,
|
||||
size24SemiBold: TextStyle.lerp(size24SemiBold, other.size24SemiBold, t)!,
|
||||
size24SemiBold1: TextStyle.lerp(size24SemiBold1, other.size24SemiBold1, t)!,
|
||||
size14Bold: TextStyle.lerp(size14Bold, other.size14Bold, t)!,
|
||||
size24Bold: TextStyle.lerp(size24Bold, other.size24Bold, t)!,
|
||||
size64Black: TextStyle.lerp(size64Black, other.size64Black, t)!,
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -108,7 +108,12 @@ class _WLoginBodyState extends State<WLoginBody> {
|
||||
),
|
||||
10.verticalSpace,
|
||||
AppTextFormField(
|
||||
prefixIcon: Text("+ 998"),
|
||||
prefixIcon: Text(
|
||||
"+ 998",
|
||||
style: context
|
||||
.appThemeTextStyles
|
||||
.size14Regular,
|
||||
),
|
||||
controller: _phoneNumberController,
|
||||
hintText: context.loc.enter_email_or_phone,
|
||||
inputFormatters: [
|
||||
@@ -143,7 +148,9 @@ class _WLoginBodyState extends State<WLoginBody> {
|
||||
Align(
|
||||
alignment: AlignmentGeometry.centerRight,
|
||||
child: TextButton(
|
||||
onPressed: () {},
|
||||
onPressed: () {
|
||||
context.push(Routes.forgotPassword);
|
||||
},
|
||||
child: Text(
|
||||
context.loc.forgot_password,
|
||||
style: AppTextStyles.size14Regular
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,8 @@ class _MyAppState extends State<MyApp> {
|
||||
debugShowCheckedModeBanner: false,
|
||||
theme: AppTheme.lightTheme,
|
||||
darkTheme: AppTheme.darkTheme,
|
||||
themeMode: themeState.themeMode,
|
||||
themeMode: ThemeMode.dark,
|
||||
// themeMode: themeState.themeMode,
|
||||
routerConfig: sl<AppRoutes>().router,
|
||||
locale: state.currentLocale,
|
||||
supportedLocales: L10n.locales,
|
||||
|
||||
Reference in New Issue
Block a user