feat:verify phone number page ui done
This commit is contained in:
@@ -174,7 +174,16 @@
|
|||||||
"repeat_password": "Repeat password",
|
"repeat_password": "Repeat password",
|
||||||
"enter_repeat_password": "Enter repeat password",
|
"enter_repeat_password": "Enter repeat password",
|
||||||
"already_has_account": "Already have an account?",
|
"already_has_account": "Already have an account?",
|
||||||
"unexpected_error": "Unexpected error"
|
"unexpected_error": "Unexpected error",
|
||||||
|
"consent_message": "By proceeding, you consent to get calls or SMS messages, including by automated means, from {appName} and its affiliates to the number provided.",
|
||||||
|
"@consent_message": {
|
||||||
|
"placeholders": {
|
||||||
|
"appName": {
|
||||||
|
"type": "String",
|
||||||
|
"example": "Uber"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -169,7 +169,16 @@
|
|||||||
"repeat_password": "Повторите пароль",
|
"repeat_password": "Повторите пароль",
|
||||||
"enter_repeat_password": "Введите пароль ещё раз",
|
"enter_repeat_password": "Введите пароль ещё раз",
|
||||||
"already_has_account": "Уже есть аккаунт?",
|
"already_has_account": "Уже есть аккаунт?",
|
||||||
"unexpected_error": "Неожиданная ошибка"
|
"unexpected_error": "Неожиданная ошибка",
|
||||||
|
"consent_message": "Продолжая, вы соглашаетесь получать звонки или SMS-сообщения, включая автоматические, от {appName} и его партнёров на указанный номер.",
|
||||||
|
"@consent_message": {
|
||||||
|
"placeholders": {
|
||||||
|
"appName": {
|
||||||
|
"type": "String",
|
||||||
|
"example": "Uber"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -169,7 +169,16 @@
|
|||||||
"repeat_password": "Parolni takrorlang",
|
"repeat_password": "Parolni takrorlang",
|
||||||
"enter_repeat_password": "Parolni qayta kiriting",
|
"enter_repeat_password": "Parolni qayta kiriting",
|
||||||
"already_has_account": "Akkountingiz bormi?",
|
"already_has_account": "Akkountingiz bormi?",
|
||||||
"unexpected_error": "Kutilmagan xatolik"
|
"unexpected_error": "Kutilmagan xatolik",
|
||||||
|
"consent_message": "Davom etish orqali siz {appName} va uning hamkorlaridan siz kiritgan raqamga, shu jumladan avtomatik vositalar orqali, qo‘ng‘iroqlar yoki SMS xabarlar olishingizga rozilik bildirasiz.",
|
||||||
|
"@consent_message": {
|
||||||
|
"placeholders": {
|
||||||
|
"appName": {
|
||||||
|
"type": "String",
|
||||||
|
"example": "Uber"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -861,6 +861,12 @@ abstract class AppLocalizations {
|
|||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
/// **'Unexpected error'**
|
/// **'Unexpected error'**
|
||||||
String get unexpected_error;
|
String get unexpected_error;
|
||||||
|
|
||||||
|
/// No description provided for @consent_message.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'By proceeding, you consent to get calls or SMS messages, including by automated means, from {appName} and its affiliates to the number provided.'**
|
||||||
|
String consent_message(String appName);
|
||||||
}
|
}
|
||||||
|
|
||||||
class _AppLocalizationsDelegate
|
class _AppLocalizationsDelegate
|
||||||
|
|||||||
@@ -401,4 +401,9 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String get unexpected_error => 'Unexpected error';
|
String get unexpected_error => 'Unexpected error';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String consent_message(String appName) {
|
||||||
|
return 'By proceeding, you consent to get calls or SMS messages, including by automated means, from $appName and its affiliates to the number provided.';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -401,4 +401,9 @@ class AppLocalizationsRu extends AppLocalizations {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String get unexpected_error => 'Неожиданная ошибка';
|
String get unexpected_error => 'Неожиданная ошибка';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String consent_message(String appName) {
|
||||||
|
return 'Продолжая, вы соглашаетесь получать звонки или SMS-сообщения, включая автоматические, от $appName и его партнёров на указанный номер.';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -402,4 +402,9 @@ class AppLocalizationsUz extends AppLocalizations {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String get unexpected_error => 'Kutilmagan xatolik';
|
String get unexpected_error => 'Kutilmagan xatolik';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String consent_message(String appName) {
|
||||||
|
return 'Davom etish orqali siz $appName va uning hamkorlaridan siz kiritgan raqamga, shu jumladan avtomatik vositalar orqali, qo‘ng‘iroqlar yoki SMS xabarlar olishingizga rozilik bildirasiz.';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ import 'package:flutter/cupertino.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/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/register_page/register_page.dart';
|
import 'package:food_delivery_client/feature/auth/presentation/pages/register_page/register_page.dart';
|
||||||
|
import 'package:food_delivery_client/feature/auth/presentation/pages/reset_password_page/reset_password_page.dart';
|
||||||
|
import 'package:food_delivery_client/feature/auth/presentation/pages/verify_otp_code_page/verify_otp_code_page.dart';
|
||||||
|
import 'package:food_delivery_client/feature/auth/presentation/pages/verify_phone_number_page/verify_phone_page.dart';
|
||||||
import 'package:food_delivery_client/feature/home/presentation/pages/restaurants_by_category_page/restaurants_by_category_page.dart';
|
import 'package:food_delivery_client/feature/home/presentation/pages/restaurants_by_category_page/restaurants_by_category_page.dart';
|
||||||
|
|
||||||
import '../../food_delivery_client.dart';
|
import '../../food_delivery_client.dart';
|
||||||
@@ -29,6 +32,25 @@ class AppRoutes {
|
|||||||
pageBuilder: (context, state) =>
|
pageBuilder: (context, state) =>
|
||||||
CupertinoPage(child: ForgotPasswordPage()),
|
CupertinoPage(child: ForgotPasswordPage()),
|
||||||
),
|
),
|
||||||
|
GoRoute(
|
||||||
|
path: Routes.verifyPhoneNumber,
|
||||||
|
pageBuilder: (context, state) => CupertinoPage(
|
||||||
|
child: VerifyPhoneNumberPage(isRegister: state.extra as bool),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
GoRoute(
|
||||||
|
path: Routes.verifyOtpCode,
|
||||||
|
pageBuilder: (context, state) => CupertinoPage(
|
||||||
|
child: VerifyOtpCodePage(isRegister: state.extra as bool),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
GoRoute(
|
||||||
|
path: Routes.resetPassword,
|
||||||
|
pageBuilder: (context, state) =>
|
||||||
|
CupertinoPage(child: ResetPasswordPage()),
|
||||||
|
),
|
||||||
|
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: Routes.main,
|
path: Routes.main,
|
||||||
|
|||||||
@@ -8,4 +8,7 @@ abstract class Routes {
|
|||||||
static const String browse = '/browse';
|
static const String browse = '/browse';
|
||||||
static const String forgotPassword = "/forgot-password";
|
static const String forgotPassword = "/forgot-password";
|
||||||
static const String restaurantsByCategory = '/restaurants-by-category';
|
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";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,5 +26,7 @@ abstract class AppColors {
|
|||||||
static const Color c660000 = Color(0x66000000);
|
static const Color c660000 = Color(0x66000000);
|
||||||
static const Color c6A6E7F = Color(0xFF6A6E7F);
|
static const Color c6A6E7F = Color(0xFF6A6E7F);
|
||||||
static const Color c7F7F7F = Color(0xFF7F7F7F);
|
static const Color c7F7F7F = Color(0xFF7F7F7F);
|
||||||
|
static const Color c888888 = Color(0xFF888888);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,6 +49,12 @@ abstract class AppTextStyles {
|
|||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
static const TextStyle size12Medium = TextStyle(
|
||||||
|
color: _defaultColor,
|
||||||
|
fontSize: SizesCons.size_12,
|
||||||
|
fontFamily: _fontMedium,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
);
|
||||||
static const TextStyle size15Medium = TextStyle(
|
static const TextStyle size15Medium = TextStyle(
|
||||||
color: _defaultColor,
|
color: _defaultColor,
|
||||||
fontSize: SizesCons.size_15,
|
fontSize: SizesCons.size_15,
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ class _WLoginBodyState extends State<WLoginBody> {
|
|||||||
alignment: AlignmentGeometry.centerRight,
|
alignment: AlignmentGeometry.centerRight,
|
||||||
child: TextButton(
|
child: TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
context.push(Routes.forgotPassword);
|
context.push(Routes.verifyPhoneNumber, extra: false);
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
context.loc.forgot_password,
|
context.loc.forgot_password,
|
||||||
@@ -148,7 +148,10 @@ class _WLoginBodyState extends State<WLoginBody> {
|
|||||||
),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
context.pushReplacement(Routes.register);
|
context.push(
|
||||||
|
Routes.verifyPhoneNumber,
|
||||||
|
extra: true,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
context.loc.sign_up,
|
context.loc.sign_up,
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import 'package:food_delivery_client/feature/auth/presentation/widgets/w_auth_background.dart';
|
||||||
|
|
||||||
|
import '../../../../../food_delivery_client.dart';
|
||||||
|
|
||||||
|
class ResetPasswordPage extends StatelessWidget {
|
||||||
|
const ResetPasswordPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return WLayout(
|
||||||
|
top: false,
|
||||||
|
child: Scaffold(
|
||||||
|
body: WAuthBackground(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import 'package:food_delivery_client/feature/auth/presentation/widgets/w_auth_background.dart';
|
||||||
|
|
||||||
|
import '../../../../../food_delivery_client.dart';
|
||||||
|
|
||||||
|
class VerifyOtpCodePage extends StatelessWidget {
|
||||||
|
const VerifyOtpCodePage({super.key, required this.isRegister});
|
||||||
|
|
||||||
|
final bool isRegister;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return WLayout(
|
||||||
|
top: false,
|
||||||
|
child: Scaffold(body: WAuthBackground(child: Column())),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
import 'package:food_delivery_client/core/helpers/formatters.dart';
|
||||||
|
import 'package:food_delivery_client/core/helpers/validator_helpers.dart';
|
||||||
|
import 'package:food_delivery_client/feature/auth/presentation/widgets/w_auth_background.dart';
|
||||||
|
|
||||||
|
import '../../../../../food_delivery_client.dart';
|
||||||
|
|
||||||
|
class VerifyPhoneNumberPage extends StatefulWidget {
|
||||||
|
const VerifyPhoneNumberPage({super.key, required this.isRegister});
|
||||||
|
|
||||||
|
final bool isRegister;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<VerifyPhoneNumberPage> createState() => _VerifyPhoneNumberPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _VerifyPhoneNumberPageState extends State<VerifyPhoneNumberPage> {
|
||||||
|
late TextEditingController _phoneNumberController;
|
||||||
|
final _formKey = GlobalKey<FormState>();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
_phoneNumberController = TextEditingController();
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_phoneNumberController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Form(
|
||||||
|
key: _formKey,
|
||||||
|
child: WLayout(
|
||||||
|
top: false,
|
||||||
|
child: Scaffold(
|
||||||
|
body: WAuthBackground(
|
||||||
|
child: SizedBox(
|
||||||
|
width: context.w,
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
50.verticalSpace,
|
||||||
|
Text(
|
||||||
|
context.loc.enter_phone_number,
|
||||||
|
style: AppTextStyles.size20Medium,
|
||||||
|
),
|
||||||
|
20.verticalSpace,
|
||||||
|
AppTextFormField(
|
||||||
|
controller: _phoneNumberController,
|
||||||
|
borderRadius: AppUtils.kBorderRadius8,
|
||||||
|
hintText: context.loc.phone_number,
|
||||||
|
keyBoardType: TextInputType.phone,
|
||||||
|
inputFormatters: [
|
||||||
|
FilteringTextInputFormatter.digitsOnly,
|
||||||
|
Formatters.phoneFormatter,
|
||||||
|
LengthLimitingTextInputFormatter(12),
|
||||||
|
],
|
||||||
|
|
||||||
|
prefixIcon: Text(
|
||||||
|
"+ 998",
|
||||||
|
style: AppTextStyles.size16Regular,
|
||||||
|
),
|
||||||
|
validator: (value) {
|
||||||
|
return Validators.validatePhoneNumber(
|
||||||
|
_phoneNumberController.text.trim(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
25.verticalSpace,
|
||||||
|
AppButton(
|
||||||
|
onPressed: () {
|
||||||
|
if (_formKey.currentState?.validate() ?? false) {}
|
||||||
|
},
|
||||||
|
name: context.loc.continue_str,
|
||||||
|
borderRadius: 15,
|
||||||
|
backgroundColor: AppColors.c34A853,
|
||||||
|
),
|
||||||
|
10.verticalSpace,
|
||||||
|
Text(
|
||||||
|
context.loc.consent_message("Felix Eats"),
|
||||||
|
style: AppTextStyles.size12Medium.copyWith(
|
||||||
|
color: AppColors.c888888,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
).paddingSymmetric(horizontal: 16),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,2 +1,3 @@
|
|||||||
export 'presentation/widgets/widgets.dart';
|
export 'presentation/widgets/widgets.dart';
|
||||||
export 'presentation/blocs/language_bloc/language_bloc.dart';
|
export 'presentation/blocs/language_bloc/language_bloc.dart';
|
||||||
|
export 'data/models/success_model.dart';
|
||||||
38
lib/feature/common/data/models/success_model.dart
Normal file
38
lib/feature/common/data/models/success_model.dart
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import 'package:equatable/equatable.dart';
|
||||||
|
|
||||||
|
class SuccessModel extends Equatable {
|
||||||
|
final String message;
|
||||||
|
final bool success;
|
||||||
|
|
||||||
|
const SuccessModel({
|
||||||
|
required this.message,
|
||||||
|
required this.success,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory SuccessModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
return SuccessModel(
|
||||||
|
message: json['message'] as String? ?? '',
|
||||||
|
success: json['success'] as bool? ?? false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return {
|
||||||
|
'message': message,
|
||||||
|
'success': success,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
SuccessModel copyWith({
|
||||||
|
String? message,
|
||||||
|
bool? success,
|
||||||
|
}) {
|
||||||
|
return SuccessModel(
|
||||||
|
message: message ?? this.message,
|
||||||
|
success: success ?? this.success,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [message, success];
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user