Compare commits
3 Commits
d3ad5b8ddd
...
a2fbd9f90d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a2fbd9f90d | ||
|
|
ece15635eb | ||
|
|
2ed2c430c0 |
3
assets/icons/ic_arrow_right_light.svg
Normal file
3
assets/icons/ic_arrow_right_light.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="22" height="18" viewBox="0 0 22 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M21.4469 9L14.5457 18H10.8296L16.6691 10.5H0V7.5H16.6691L10.8296 0H14.5457L21.4469 9Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 214 B |
BIN
assets/images/img_burger2.png
Normal file
BIN
assets/images/img_burger2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 999 KiB |
@@ -156,7 +156,26 @@
|
||||
"baskets": "Baskets",
|
||||
"account": "Account",
|
||||
"changeLanguage": "Change language",
|
||||
"language": "Language"
|
||||
"language": "Language",
|
||||
"login": "Login",
|
||||
"phone_number": "Phone number",
|
||||
"enter_phone_number": "Enter phone number",
|
||||
"password": "Password",
|
||||
"enter_password": "Enter password",
|
||||
"forgot_password": "Forgot password",
|
||||
"continue_str": "Continue",
|
||||
"dont_have_account": "Don't have an account?",
|
||||
"sign_up": "SignUp",
|
||||
"field_cannot_be_empty": "This field cannot be empty",
|
||||
"password_too_short": "Password must be at least 6 characters long",
|
||||
"invalid_phone_format": "Invalid phone number format",
|
||||
"first_name": "First name",
|
||||
"enter_first_name": "Enter first name",
|
||||
"repeat_password": "Repeat password",
|
||||
"enter_repeat_password": "Enter repeat password",
|
||||
"already_has_account": "Already have an account?",
|
||||
"unexpected_error": "Unexpected error"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -151,7 +151,26 @@
|
||||
"baskets": "Корзина",
|
||||
"account": "Аккаунт",
|
||||
"language": "Язык",
|
||||
"changeLanguage": "Сменить язык"
|
||||
"changeLanguage": "Сменить язык",
|
||||
"login": "Вход",
|
||||
"phone_number": "Номер телефона",
|
||||
"enter_phone_number": "Введите номер телефона",
|
||||
"password": "Пароль",
|
||||
"enter_password": "Введите пароль",
|
||||
"forgot_password": "Забыли пароль",
|
||||
"continue_str": "Продолжить",
|
||||
"dont_have_account": "У вас нет аккаунта?",
|
||||
"sign_up": "Зарегистрироваться",
|
||||
"field_cannot_be_empty": "Это поле не может быть пустым",
|
||||
"password_too_short": "Пароль не может быть короче 6 символов",
|
||||
"invalid_phone_format": "Неверный формат номера телефона",
|
||||
"first_name": "Имя",
|
||||
"enter_first_name": "Введите имя",
|
||||
"repeat_password": "Повторите пароль",
|
||||
"enter_repeat_password": "Введите пароль ещё раз",
|
||||
"already_has_account": "Уже есть аккаунт?",
|
||||
"unexpected_error": "Неожиданная ошибка"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -151,7 +151,26 @@
|
||||
"baskets": "Savatcha",
|
||||
"account": "Profil",
|
||||
"language": "Til",
|
||||
"changeLanguage": "Tilni o'zgartirish"
|
||||
"changeLanguage": "Tilni o'zgartirish",
|
||||
"login": "Kirish",
|
||||
"phone_number": "Telefon raqami",
|
||||
"enter_phone_number": "Telefon raqamingizni kiriting",
|
||||
"password": "Parol",
|
||||
"enter_password": "Parolni kiriting",
|
||||
"forgot_password": "Parolni unutdingizmi",
|
||||
"continue_str": "Davom etish",
|
||||
"dont_have_account": "Hisobingiz yo‘qmi?",
|
||||
"sign_up": "Ro‘yxatdan o‘tish",
|
||||
"field_cannot_be_empty": "Bu maydon bo'sh bo'lishi mumkin emas",
|
||||
"password_too_short": "Parol 6 ta belgidan kam bo'lishi mumkin emas",
|
||||
"invalid_phone_format": "Noto'g'ri telefon raqam formati",
|
||||
"first_name": "Ism",
|
||||
"enter_first_name": "Ismingizni kiriting",
|
||||
"repeat_password": "Parolni takrorlang",
|
||||
"enter_repeat_password": "Parolni qayta kiriting",
|
||||
"already_has_account": "Akkountingiz bormi?",
|
||||
"unexpected_error": "Kutilmagan xatolik"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ abstract class AppLocaleKeys {
|
||||
///Storage keys
|
||||
static const String language = 'language';
|
||||
static const String browseSearchHistory = 'browse-search-history';
|
||||
static const String token = 'token';
|
||||
|
||||
static const String fontBold = "fontBold";
|
||||
static const String fontMedium = "fontMedium";
|
||||
|
||||
@@ -71,7 +71,10 @@ extension GetItInjectableX on _i174.GetIt {
|
||||
() => _i241.LoginUseCase(gh<_i884.AuthRepository>()),
|
||||
);
|
||||
gh.factory<_i1065.LoginBloc>(
|
||||
() => _i1065.LoginBloc(gh<_i241.LoginUseCase>()),
|
||||
() => _i1065.LoginBloc(
|
||||
gh<_i241.LoginUseCase>(),
|
||||
gh<_i321.StorageService>(),
|
||||
),
|
||||
);
|
||||
return this;
|
||||
}
|
||||
|
||||
28
lib/core/helpers/validator_helpers.dart
Normal file
28
lib/core/helpers/validator_helpers.dart
Normal file
@@ -0,0 +1,28 @@
|
||||
import 'package:food_delivery_client/core/core.dart';
|
||||
|
||||
abstract class Validators {
|
||||
static String? validatePhoneNumber(String phoneNumber) {
|
||||
if (phoneNumber.isEmpty) {
|
||||
return navigatorKey.currentContext?.loc.field_cannot_be_empty;
|
||||
} else if (phoneNumber.length < 12) {
|
||||
return navigatorKey.currentContext?.loc.invalid_phone_format;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static String? validatePassword(String password) {
|
||||
if (password.isEmpty) {
|
||||
return navigatorKey.currentContext?.loc.field_cannot_be_empty;
|
||||
} else if (password.length < 6) {
|
||||
return navigatorKey.currentContext?.loc.password_too_short;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static String? validateFields(String value) {
|
||||
if (value.isEmpty) {
|
||||
return navigatorKey.currentContext?.loc.field_cannot_be_empty;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -753,6 +753,114 @@ abstract class AppLocalizations {
|
||||
/// In en, this message translates to:
|
||||
/// **'Language'**
|
||||
String get language;
|
||||
|
||||
/// No description provided for @login.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Login'**
|
||||
String get login;
|
||||
|
||||
/// No description provided for @phone_number.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Phone number'**
|
||||
String get phone_number;
|
||||
|
||||
/// No description provided for @enter_phone_number.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Enter phone number'**
|
||||
String get enter_phone_number;
|
||||
|
||||
/// No description provided for @password.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Password'**
|
||||
String get password;
|
||||
|
||||
/// No description provided for @enter_password.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Enter password'**
|
||||
String get enter_password;
|
||||
|
||||
/// No description provided for @forgot_password.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Forgot password'**
|
||||
String get forgot_password;
|
||||
|
||||
/// No description provided for @continue_str.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Continue'**
|
||||
String get continue_str;
|
||||
|
||||
/// No description provided for @dont_have_account.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Don\'t have an account?'**
|
||||
String get dont_have_account;
|
||||
|
||||
/// No description provided for @sign_up.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'SignUp'**
|
||||
String get sign_up;
|
||||
|
||||
/// No description provided for @field_cannot_be_empty.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'This field cannot be empty'**
|
||||
String get field_cannot_be_empty;
|
||||
|
||||
/// No description provided for @password_too_short.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Password must be at least 6 characters long'**
|
||||
String get password_too_short;
|
||||
|
||||
/// No description provided for @invalid_phone_format.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Invalid phone number format'**
|
||||
String get invalid_phone_format;
|
||||
|
||||
/// No description provided for @first_name.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'First name'**
|
||||
String get first_name;
|
||||
|
||||
/// No description provided for @enter_first_name.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Enter first name'**
|
||||
String get enter_first_name;
|
||||
|
||||
/// No description provided for @repeat_password.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Repeat password'**
|
||||
String get repeat_password;
|
||||
|
||||
/// No description provided for @enter_repeat_password.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Enter repeat password'**
|
||||
String get enter_repeat_password;
|
||||
|
||||
/// No description provided for @already_has_account.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Already have an account?'**
|
||||
String get already_has_account;
|
||||
|
||||
/// No description provided for @unexpected_error.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Unexpected error'**
|
||||
String get unexpected_error;
|
||||
}
|
||||
|
||||
class _AppLocalizationsDelegate
|
||||
|
||||
@@ -346,4 +346,59 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get language => 'Language';
|
||||
|
||||
@override
|
||||
String get login => 'Login';
|
||||
|
||||
@override
|
||||
String get phone_number => 'Phone number';
|
||||
|
||||
@override
|
||||
String get enter_phone_number => 'Enter phone number';
|
||||
|
||||
@override
|
||||
String get password => 'Password';
|
||||
|
||||
@override
|
||||
String get enter_password => 'Enter password';
|
||||
|
||||
@override
|
||||
String get forgot_password => 'Forgot password';
|
||||
|
||||
@override
|
||||
String get continue_str => 'Continue';
|
||||
|
||||
@override
|
||||
String get dont_have_account => 'Don\'t have an account?';
|
||||
|
||||
@override
|
||||
String get sign_up => 'SignUp';
|
||||
|
||||
@override
|
||||
String get field_cannot_be_empty => 'This field cannot be empty';
|
||||
|
||||
@override
|
||||
String get password_too_short =>
|
||||
'Password must be at least 6 characters long';
|
||||
|
||||
@override
|
||||
String get invalid_phone_format => 'Invalid phone number format';
|
||||
|
||||
@override
|
||||
String get first_name => 'First name';
|
||||
|
||||
@override
|
||||
String get enter_first_name => 'Enter first name';
|
||||
|
||||
@override
|
||||
String get repeat_password => 'Repeat password';
|
||||
|
||||
@override
|
||||
String get enter_repeat_password => 'Enter repeat password';
|
||||
|
||||
@override
|
||||
String get already_has_account => 'Already have an account?';
|
||||
|
||||
@override
|
||||
String get unexpected_error => 'Unexpected error';
|
||||
}
|
||||
|
||||
@@ -347,4 +347,58 @@ class AppLocalizationsRu extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get language => 'Язык';
|
||||
|
||||
@override
|
||||
String get login => 'Вход';
|
||||
|
||||
@override
|
||||
String get phone_number => 'Номер телефона';
|
||||
|
||||
@override
|
||||
String get enter_phone_number => 'Введите номер телефона';
|
||||
|
||||
@override
|
||||
String get password => 'Пароль';
|
||||
|
||||
@override
|
||||
String get enter_password => 'Введите пароль';
|
||||
|
||||
@override
|
||||
String get forgot_password => 'Забыли пароль';
|
||||
|
||||
@override
|
||||
String get continue_str => 'Продолжить';
|
||||
|
||||
@override
|
||||
String get dont_have_account => 'У вас нет аккаунта?';
|
||||
|
||||
@override
|
||||
String get sign_up => 'Зарегистрироваться';
|
||||
|
||||
@override
|
||||
String get field_cannot_be_empty => 'Это поле не может быть пустым';
|
||||
|
||||
@override
|
||||
String get password_too_short => 'Пароль не может быть короче 6 символов';
|
||||
|
||||
@override
|
||||
String get invalid_phone_format => 'Неверный формат номера телефона';
|
||||
|
||||
@override
|
||||
String get first_name => 'Имя';
|
||||
|
||||
@override
|
||||
String get enter_first_name => 'Введите имя';
|
||||
|
||||
@override
|
||||
String get repeat_password => 'Повторите пароль';
|
||||
|
||||
@override
|
||||
String get enter_repeat_password => 'Введите пароль ещё раз';
|
||||
|
||||
@override
|
||||
String get already_has_account => 'Уже есть аккаунт?';
|
||||
|
||||
@override
|
||||
String get unexpected_error => 'Неожиданная ошибка';
|
||||
}
|
||||
|
||||
@@ -347,4 +347,59 @@ class AppLocalizationsUz extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get language => 'Til';
|
||||
|
||||
@override
|
||||
String get login => 'Kirish';
|
||||
|
||||
@override
|
||||
String get phone_number => 'Telefon raqami';
|
||||
|
||||
@override
|
||||
String get enter_phone_number => 'Telefon raqamingizni kiriting';
|
||||
|
||||
@override
|
||||
String get password => 'Parol';
|
||||
|
||||
@override
|
||||
String get enter_password => 'Parolni kiriting';
|
||||
|
||||
@override
|
||||
String get forgot_password => 'Parolni unutdingizmi';
|
||||
|
||||
@override
|
||||
String get continue_str => 'Davom etish';
|
||||
|
||||
@override
|
||||
String get dont_have_account => 'Hisobingiz yo‘qmi?';
|
||||
|
||||
@override
|
||||
String get sign_up => 'Ro‘yxatdan o‘tish';
|
||||
|
||||
@override
|
||||
String get field_cannot_be_empty => 'Bu maydon bo\'sh bo\'lishi mumkin emas';
|
||||
|
||||
@override
|
||||
String get password_too_short =>
|
||||
'Parol 6 ta belgidan kam bo\'lishi mumkin emas';
|
||||
|
||||
@override
|
||||
String get invalid_phone_format => 'Noto\'g\'ri telefon raqam formati';
|
||||
|
||||
@override
|
||||
String get first_name => 'Ism';
|
||||
|
||||
@override
|
||||
String get enter_first_name => 'Ismingizni kiriting';
|
||||
|
||||
@override
|
||||
String get repeat_password => 'Parolni takrorlang';
|
||||
|
||||
@override
|
||||
String get enter_repeat_password => 'Parolni qayta kiriting';
|
||||
|
||||
@override
|
||||
String get already_has_account => 'Akkountingiz bormi?';
|
||||
|
||||
@override
|
||||
String get unexpected_error => 'Kutilmagan xatolik';
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:food_delivery_client/core/network/header_interceptors.dart';
|
||||
import 'package:food_delivery_client/food_delivery_client.dart';
|
||||
import 'error_handler_interceptor.dart';
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
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/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/home/presentation/pages/restaurants_by_category_page/restaurants_by_category_page.dart';
|
||||
|
||||
import '../../food_delivery_client.dart';
|
||||
@@ -18,6 +20,16 @@ class AppRoutes {
|
||||
pageBuilder: (context, state) => CupertinoPage(child: LoginPage()),
|
||||
),
|
||||
|
||||
GoRoute(
|
||||
path: Routes.register,
|
||||
pageBuilder: (context, state) => CupertinoPage(child: RegisterPage()),
|
||||
),
|
||||
GoRoute(
|
||||
path: Routes.forgotPassword,
|
||||
pageBuilder: (context, state) =>
|
||||
CupertinoPage(child: ForgotPasswordPage()),
|
||||
),
|
||||
|
||||
GoRoute(
|
||||
path: Routes.main,
|
||||
pageBuilder: (context, state) => CupertinoPage(child: MainPage()),
|
||||
|
||||
@@ -6,5 +6,6 @@ abstract class Routes {
|
||||
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';
|
||||
}
|
||||
|
||||
@@ -25,5 +25,6 @@ abstract class AppColors {
|
||||
static const Color cE8E8E8 = Color(0xFFE8E8E8);
|
||||
static const Color c660000 = Color(0x66000000);
|
||||
static const Color c6A6E7F = Color(0xFF6A6E7F);
|
||||
static const Color c7F7F7F = Color(0xFF7F7F7F);
|
||||
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ abstract class AppIcons {
|
||||
static const String icWallet = "$baseUrl/ic_wallet.svg";
|
||||
static const String icOrdersSvg = "$baseUrl/ic_orders_svg.svg";
|
||||
static const String icLanguage = "$baseUrl/ic_language.svg";
|
||||
static const String icArrowRightLight = "$baseUrl/ic_arrow_right_light.svg";
|
||||
|
||||
///.png icons
|
||||
static const String icBestOverall = "$baseUrl/ic_best.png";
|
||||
|
||||
@@ -23,4 +23,5 @@ abstract class AppImages {
|
||||
static const String imgDesert = "$baseUrl/img_desert.png";
|
||||
static const String imgPickUp = "$baseUrl/img_pick_up.png";
|
||||
static const String imgAvatar = "$baseUrl/img_avatar.jpg";
|
||||
static const String imgBurger2 = "$baseUrl/img_burger2.png";
|
||||
}
|
||||
|
||||
@@ -83,6 +83,19 @@ abstract class AppTextStyles {
|
||||
fontFamily: _fontMedium,
|
||||
fontWeight: FontWeight.w500,
|
||||
);
|
||||
static const TextStyle size14Bold= TextStyle(
|
||||
color: _defaultColor,
|
||||
fontSize: SizesCons.size_14,
|
||||
fontFamily: _fontBold,
|
||||
fontWeight: FontWeight.w700,
|
||||
);
|
||||
|
||||
static const TextStyle size15Bold= TextStyle(
|
||||
color: _defaultColor,
|
||||
fontSize: SizesCons.size_15,
|
||||
fontFamily: _fontBold,
|
||||
fontWeight: FontWeight.w700,
|
||||
);
|
||||
|
||||
static const TextStyle size16Bold= TextStyle(
|
||||
color: _defaultColor,
|
||||
|
||||
@@ -13,6 +13,7 @@ abstract class AppUtils {
|
||||
static const Radius kRadius22 = Radius.circular(22);
|
||||
static const Radius kRadius24 = Radius.circular(24);
|
||||
static const Radius kRadius25 = Radius.circular(25);
|
||||
static const Radius kRadius30 = Radius.circular(30);
|
||||
static const BorderRadius kBorderRadius = BorderRadius.zero;
|
||||
static const BorderRadius kBorderRadius2 = BorderRadius.all(
|
||||
Radius.circular(2),
|
||||
@@ -92,6 +93,11 @@ abstract class AppUtils {
|
||||
topLeft: kRadius20,
|
||||
topRight: kRadius20,
|
||||
);
|
||||
|
||||
static const BorderRadius kBorderRadiusTop30 = BorderRadius.only(
|
||||
topLeft: kRadius30,
|
||||
topRight: kRadius30,
|
||||
);
|
||||
static const BorderRadius kBorderRadiusTop20Bottom20 = BorderRadius.only(
|
||||
bottomRight: kRadius20,
|
||||
topRight: kRadius20,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:food_delivery_client/feature/auth/domain/usecases/login_usecase.dart';
|
||||
import 'package:food_delivery_client/feature/common/presentation/widgets/w_toastification.dart';
|
||||
import 'package:food_delivery_client/food_delivery_client.dart';
|
||||
|
||||
part 'login_event.dart';
|
||||
@@ -10,8 +11,10 @@ part 'login_bloc.freezed.dart';
|
||||
@injectable
|
||||
class LoginBloc extends Bloc<LoginEvent, LoginState> {
|
||||
final LoginUseCase _loginUseCase;
|
||||
final StorageService _storageService;
|
||||
|
||||
LoginBloc(this._loginUseCase) : super(const LoginState()) {
|
||||
LoginBloc(this._loginUseCase, this._storageService)
|
||||
: super(const LoginState()) {
|
||||
on<_Login>(_onLogin);
|
||||
}
|
||||
|
||||
@@ -23,10 +26,14 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> {
|
||||
response.fold(
|
||||
(l) {
|
||||
log("${l.errorMessage}");
|
||||
showErrorToast(l.errorMessage);
|
||||
emit(state.copyWith(status: RequestStatus.error));
|
||||
},
|
||||
(r) {
|
||||
log(r.token);
|
||||
showSuccessToast("Login success");
|
||||
_storageService.setString(key: AppLocaleKeys.token, value: r.token);
|
||||
final token = _storageService.getString(key: AppLocaleKeys.token);
|
||||
log('Token:$token');
|
||||
emit(state.copyWith(status: RequestStatus.loaded));
|
||||
},
|
||||
);
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import '../../../../../food_delivery_client.dart';
|
||||
|
||||
class ForgotPasswordPage extends StatelessWidget {
|
||||
const ForgotPasswordPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WLayout(
|
||||
child: Scaffold(body: Column(children: [Text('Forgot password')])),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
import 'package:food_delivery_client/feature/auth/presentation/blocs/login_bloc/login_bloc.dart';
|
||||
import 'package:food_delivery_client/feature/auth/presentation/pages/login_page/widgets/login_body.dart';
|
||||
|
||||
import '../../../../../food_delivery_client.dart';
|
||||
|
||||
class LoginPage extends StatelessWidget {
|
||||
@@ -11,11 +10,9 @@ class LoginPage extends StatelessWidget {
|
||||
return BlocProvider(
|
||||
create: (context) => sl<LoginBloc>(),
|
||||
child: WLayout(
|
||||
child: Scaffold(
|
||||
body: WLoginBody(),
|
||||
),
|
||||
top: false,
|
||||
child: Scaffold(resizeToAvoidBottomInset: true, body: WLoginBody()),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
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/domain/usecases/login_usecase.dart';
|
||||
|
||||
import 'package:food_delivery_client/feature/auth/presentation/widgets/w_auth_background.dart';
|
||||
import '../../../../../../food_delivery_client.dart';
|
||||
import '../../../blocs/login_bloc/login_bloc.dart';
|
||||
|
||||
@@ -38,86 +38,131 @@ class _WLoginBodyState extends State<WLoginBody> {
|
||||
return Form(
|
||||
key: _formKey,
|
||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
45.verticalSpace,
|
||||
Align(
|
||||
alignment: AlignmentGeometry.center,
|
||||
child: Text("Let's go", style: AppTextStyles.size24Bold),
|
||||
),
|
||||
20.verticalSpace,
|
||||
Text(
|
||||
'Phone number',
|
||||
style: AppTextStyles.size14Regular.copyWith(
|
||||
color: AppColors.c6A6E7F,
|
||||
child: WAuthBackground(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
25.verticalSpace,
|
||||
Align(
|
||||
alignment: AlignmentGeometry.center,
|
||||
child: Text(
|
||||
context.loc.login,
|
||||
style: AppTextStyles.size24Bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
5.verticalSpace,
|
||||
AppTextFormField(
|
||||
height: 50,
|
||||
hintText: "Enter phone number",
|
||||
prefixIcon: Text(
|
||||
"+ 998",
|
||||
style: AppTextStyles.size16Regular.copyWith(fontSize: 16),
|
||||
20.verticalSpace,
|
||||
Text(
|
||||
context.loc.phone_number,
|
||||
style: AppTextStyles.size14Regular.copyWith(
|
||||
color: AppColors.c6A6E7F,
|
||||
),
|
||||
),
|
||||
borderRadius: AppUtils.kBorderRadius8,
|
||||
controller: _phoneController,
|
||||
keyBoardType: TextInputType.number,
|
||||
5.verticalSpace,
|
||||
AppTextFormField(
|
||||
hintText: context.loc.enter_phone_number,
|
||||
prefixIcon: Text(
|
||||
"+ 998",
|
||||
style: AppTextStyles.size16Regular.copyWith(fontSize: 16),
|
||||
),
|
||||
borderRadius: AppUtils.kBorderRadius8,
|
||||
controller: _phoneController,
|
||||
keyBoardType: TextInputType.number,
|
||||
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.digitsOnly,
|
||||
Formatters.phoneFormatter,
|
||||
LengthLimitingTextInputFormatter(12),
|
||||
],
|
||||
),
|
||||
20.verticalSpace,
|
||||
Text(
|
||||
'Password',
|
||||
style: AppTextStyles.size14Regular.copyWith(
|
||||
color: AppColors.c6A6E7F,
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.digitsOnly,
|
||||
Formatters.phoneFormatter,
|
||||
LengthLimitingTextInputFormatter(12),
|
||||
],
|
||||
validator: (value) {
|
||||
return Validators.validatePhoneNumber(
|
||||
_phoneController.text.trim(),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
5.verticalSpace,
|
||||
AppTextFormField(
|
||||
height: 50,
|
||||
hintText: "Enter password",
|
||||
keyBoardType: TextInputType.text,
|
||||
borderRadius: AppUtils.kBorderRadius8,
|
||||
controller: _passwordController,
|
||||
),
|
||||
Align(
|
||||
alignment: AlignmentGeometry.centerRight,
|
||||
child: TextButton(
|
||||
onPressed: () {},
|
||||
child: Text('Forgot password'),
|
||||
10.verticalSpace,
|
||||
Text(
|
||||
context.loc.password,
|
||||
style: AppTextStyles.size14Regular.copyWith(
|
||||
color: AppColors.c6A6E7F,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
const Spacer(),
|
||||
AppButton(
|
||||
name: "Continue",
|
||||
isLoading: state.status.isLoading(),
|
||||
onPressed: () {
|
||||
if (_formKey.currentState?.validate() ?? false) {
|
||||
context.read<LoginBloc>().add(
|
||||
LoginEvent.login(
|
||||
LoginParams(
|
||||
phoneNumber:
|
||||
"+998${_phoneController.text.trim().replaceAll(" ", "")}",
|
||||
password: _passwordController.text.trim(),
|
||||
5.verticalSpace,
|
||||
AppTextFormField(
|
||||
height: 50,
|
||||
obscureText: true,
|
||||
hintText: context.loc.enter_password,
|
||||
keyBoardType: TextInputType.text,
|
||||
borderRadius: AppUtils.kBorderRadius8,
|
||||
controller: _passwordController,
|
||||
validator: (value) {
|
||||
return Validators.validatePassword(
|
||||
_passwordController.text.trim(),
|
||||
);
|
||||
},
|
||||
),
|
||||
Align(
|
||||
alignment: AlignmentGeometry.centerRight,
|
||||
child: TextButton(
|
||||
onPressed: () {
|
||||
context.push(Routes.forgotPassword);
|
||||
},
|
||||
child: Text(
|
||||
context.loc.forgot_password,
|
||||
style: AppTextStyles.size14Medium.copyWith(
|
||||
color: AppColors.c34A853,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
40.verticalSpace,
|
||||
AppButton(
|
||||
name: context.loc.continue_str,
|
||||
isLoading: state.status.isLoading(),
|
||||
trailing: SvgPicture.asset(
|
||||
AppIcons.icArrowRightLight,
|
||||
).paddingOnly(left: 10),
|
||||
onPressed: () {
|
||||
if (_formKey.currentState?.validate() ?? false) {
|
||||
context.read<LoginBloc>().add(
|
||||
LoginEvent.login(
|
||||
LoginParams(
|
||||
phoneNumber:
|
||||
"+998${_phoneController.text.trim().replaceAll(" ", "")}",
|
||||
password: _passwordController.text.trim(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
borderRadius: 15,
|
||||
backgroundColor: AppColors.c34A853,
|
||||
),
|
||||
20.verticalSpace,
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
context.loc.dont_have_account,
|
||||
style: AppTextStyles.size14Medium,
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
context.pushReplacement(Routes.register);
|
||||
},
|
||||
child: Text(
|
||||
context.loc.sign_up,
|
||||
style: AppTextStyles.size15Bold.copyWith(
|
||||
color: AppColors.c34A853,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
borderRadius: 15,
|
||||
backgroundColor: AppColors.c34A853,
|
||||
),
|
||||
20.verticalSpace,
|
||||
],
|
||||
).paddingSymmetric(horizontal: 16),
|
||||
),
|
||||
],
|
||||
),
|
||||
20.verticalSpace,
|
||||
],
|
||||
).paddingSymmetric(horizontal: 16),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import 'package:food_delivery_client/feature/auth/presentation/pages/register_page/widgets/w_register_body.dart';
|
||||
|
||||
import '../../../../../food_delivery_client.dart';
|
||||
|
||||
class RegisterPage extends StatelessWidget {
|
||||
const RegisterPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WLayout(
|
||||
top: false,
|
||||
child: Scaffold(body: WRegisterBody()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
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 WRegisterBody extends StatefulWidget {
|
||||
const WRegisterBody({super.key});
|
||||
|
||||
@override
|
||||
State<WRegisterBody> createState() => _WRegisterBodyState();
|
||||
}
|
||||
|
||||
class _WRegisterBodyState extends State<WRegisterBody> {
|
||||
late TextEditingController _firstNameController;
|
||||
late TextEditingController _lastNameController;
|
||||
late TextEditingController _phoneNumberController;
|
||||
late TextEditingController _passwordController;
|
||||
late TextEditingController _repeatPasswordController;
|
||||
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_firstNameController = TextEditingController();
|
||||
_lastNameController = TextEditingController();
|
||||
_phoneNumberController = TextEditingController();
|
||||
_passwordController = TextEditingController();
|
||||
_repeatPasswordController = TextEditingController();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_firstNameController.dispose();
|
||||
_lastNameController.dispose();
|
||||
_phoneNumberController.dispose();
|
||||
_passwordController.dispose();
|
||||
_repeatPasswordController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Form(
|
||||
key: _formKey,
|
||||
child: WAuthBackground(
|
||||
child: SizedBox(
|
||||
width: context.w,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
20.verticalSpace,
|
||||
Align(
|
||||
alignment: AlignmentGeometry.center,
|
||||
child: Text(
|
||||
context.loc.sign_up,
|
||||
style: AppTextStyles.size24Bold,
|
||||
),
|
||||
),
|
||||
20.verticalSpace,
|
||||
Text(
|
||||
context.loc.first_name,
|
||||
style: AppTextStyles.size14Regular.copyWith(
|
||||
color: AppColors.c6A6E7F,
|
||||
),
|
||||
),
|
||||
5.verticalSpace,
|
||||
AppTextFormField(
|
||||
hintText: context.loc.enter_first_name,
|
||||
controller: _firstNameController,
|
||||
borderRadius: AppUtils.kBorderRadius8,
|
||||
keyBoardType: TextInputType.name,
|
||||
validator: (value) {
|
||||
return Validators.validateFields(
|
||||
_firstNameController.text.trim(),
|
||||
);
|
||||
},
|
||||
),
|
||||
10.verticalSpace,
|
||||
Text(
|
||||
'Last name',
|
||||
style: AppTextStyles.size14Regular.copyWith(
|
||||
color: AppColors.c6A6E7F,
|
||||
),
|
||||
),
|
||||
5.verticalSpace,
|
||||
AppTextFormField(
|
||||
hintText: "Enter LastName",
|
||||
controller: _lastNameController,
|
||||
borderRadius: AppUtils.kBorderRadius8,
|
||||
keyBoardType: TextInputType.text,
|
||||
validator: (value) {
|
||||
return Validators.validateFields(
|
||||
_lastNameController.text.trim(),
|
||||
);
|
||||
},
|
||||
),
|
||||
10.verticalSpace,
|
||||
/* Text(
|
||||
context.loc.phone_number,
|
||||
style: AppTextStyles.size14Regular.copyWith(
|
||||
color: AppColors.c6A6E7F,
|
||||
),
|
||||
),
|
||||
5.verticalSpace,
|
||||
AppTextFormField(
|
||||
hintText: context.loc.enter_phone_number,
|
||||
controller: _phoneNumberController,
|
||||
borderRadius: AppUtils.kBorderRadius8,
|
||||
keyBoardType: TextInputType.phone,
|
||||
prefixIcon: Text("+ 998", style: AppTextStyles.size16Regular),
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.digitsOnly,
|
||||
Formatters.phoneFormatter,
|
||||
LengthLimitingTextInputFormatter(12),
|
||||
],
|
||||
validator: (value) {
|
||||
return Validators.validatePhoneNumber(
|
||||
_phoneNumberController.text.trim(),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
*/
|
||||
10.verticalSpace,
|
||||
Text(
|
||||
context.loc.enter_password,
|
||||
style: AppTextStyles.size14Regular.copyWith(
|
||||
color: AppColors.c6A6E7F,
|
||||
),
|
||||
),
|
||||
5.verticalSpace,
|
||||
AppTextFormField(
|
||||
obscureText: true,
|
||||
hintText: context.loc.password,
|
||||
controller: _passwordController,
|
||||
borderRadius: AppUtils.kBorderRadius8,
|
||||
keyBoardType: TextInputType.visiblePassword,
|
||||
validator: (value) {
|
||||
return Validators.validatePassword(
|
||||
_passwordController.text.trim(),
|
||||
);
|
||||
},
|
||||
),
|
||||
10.verticalSpace,
|
||||
|
||||
Text(
|
||||
context.loc.repeat_password,
|
||||
style: AppTextStyles.size14Regular.copyWith(
|
||||
color: AppColors.c6A6E7F,
|
||||
),
|
||||
),
|
||||
5.verticalSpace,
|
||||
AppTextFormField(
|
||||
obscureText: true,
|
||||
hintText: context.loc.enter_repeat_password,
|
||||
controller: _repeatPasswordController,
|
||||
borderRadius: AppUtils.kBorderRadius8,
|
||||
keyBoardType: TextInputType.visiblePassword,
|
||||
validator: (value) {
|
||||
return Validators.validatePassword(
|
||||
_repeatPasswordController.text.trim(),
|
||||
);
|
||||
},
|
||||
),
|
||||
20.verticalSpace,
|
||||
AppButton(
|
||||
name: context.loc.continue_str,
|
||||
borderRadius: 15,
|
||||
|
||||
backgroundColor: AppColors.c34A853,
|
||||
trailing: SvgPicture.asset(
|
||||
AppIcons.icArrowRightLight,
|
||||
).paddingOnly(left: 8),
|
||||
onPressed: () {
|
||||
if (_formKey.currentState?.validate() ?? false) {}
|
||||
},
|
||||
),
|
||||
20.verticalSpace,
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
context.loc.already_has_account,
|
||||
style: AppTextStyles.size14Medium,
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
context.pushReplacement(Routes.login);
|
||||
},
|
||||
child: Text(
|
||||
context.loc.login,
|
||||
style: AppTextStyles.size15Bold.copyWith(
|
||||
color: AppColors.c34A853,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
).paddingSymmetric(horizontal: 16),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
35
lib/feature/auth/presentation/widgets/w_auth_background.dart
Normal file
35
lib/feature/auth/presentation/widgets/w_auth_background.dart
Normal file
@@ -0,0 +1,35 @@
|
||||
import '../../../../food_delivery_client.dart';
|
||||
|
||||
class WAuthBackground extends StatelessWidget {
|
||||
const WAuthBackground({super.key, required this.child});
|
||||
|
||||
final Widget child;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Stack(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: context.h * .3,
|
||||
child: Image.asset(AppImages.imgBurger2, fit: BoxFit.cover),
|
||||
),
|
||||
SingleChildScrollView(
|
||||
// keyboardDismissBehavior:
|
||||
// ScrollViewKeyboardDismissBehavior.onDrag,
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(height: context.h * .2),
|
||||
DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.cFFFFFF,
|
||||
borderRadius: AppUtils.kBorderRadiusTop20,
|
||||
),
|
||||
child: child,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ class AppButton extends StatelessWidget {
|
||||
this.height,
|
||||
this.textColor,
|
||||
this.width,
|
||||
this.action,
|
||||
this.leading,
|
||||
this.trailing,
|
||||
this.mainAxisAlignment,
|
||||
this.isLoading = false,
|
||||
@@ -25,7 +25,7 @@ class AppButton extends StatelessWidget {
|
||||
final double? borderRadius;
|
||||
final double? width;
|
||||
final double? height;
|
||||
final Widget? action;
|
||||
final Widget? leading;
|
||||
final Widget? trailing;
|
||||
final bool isLoading;
|
||||
final MainAxisAlignment? mainAxisAlignment;
|
||||
@@ -57,7 +57,7 @@ class AppButton extends StatelessWidget {
|
||||
mainAxisAlignment:
|
||||
mainAxisAlignment ?? MainAxisAlignment.center,
|
||||
children: [
|
||||
action ?? AppUtils.kSizedBox,
|
||||
leading?? AppUtils.kSizedBox,
|
||||
Text(
|
||||
name,
|
||||
style: AppTextStyles.size16Bold.copyWith(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import '../../../../food_delivery_client.dart';
|
||||
|
||||
class AppTextFormField extends StatelessWidget {
|
||||
class AppTextFormField extends StatefulWidget {
|
||||
AppTextFormField({
|
||||
super.key,
|
||||
this.maxLines,
|
||||
@@ -21,6 +21,8 @@ class AppTextFormField extends StatelessWidget {
|
||||
this.focusNode,
|
||||
this.borderRadius,
|
||||
this.height,
|
||||
this.suffixIcon,
|
||||
this.validator,
|
||||
});
|
||||
|
||||
final int? maxLines;
|
||||
@@ -32,65 +34,88 @@ class AppTextFormField extends StatelessWidget {
|
||||
final Function(String? value)? onChanged;
|
||||
final List<TextInputFormatter>? inputFormatters;
|
||||
final TextInputType? keyBoardType;
|
||||
FormFieldValidator<String>? validator;
|
||||
final bool obscureText;
|
||||
final Color? fillColor;
|
||||
final String? hintText;
|
||||
final TextStyle? hintTextStyle;
|
||||
late final Widget? prefixIcon;
|
||||
final Widget? prefixIcon;
|
||||
final String? prefixSvgPath;
|
||||
final FocusNode? focusNode;
|
||||
final BorderRadius? borderRadius;
|
||||
final double? height;
|
||||
final Widget? suffixIcon;
|
||||
FormFieldValidator<String>? validator;
|
||||
|
||||
@override
|
||||
State<AppTextFormField> createState() => _AppTextFormFieldState();
|
||||
}
|
||||
|
||||
class _AppTextFormFieldState extends State<AppTextFormField> {
|
||||
bool visibility = true;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
height: height ?? 44,
|
||||
child: TextFormField(
|
||||
return TextFormField(
|
||||
enabled: true,
|
||||
//autofocus: true,
|
||||
maxLines: widget.maxLines ?? 1,
|
||||
minLines: widget.minLines ?? 1,
|
||||
onChanged: widget.onChanged,
|
||||
focusNode: widget.focusNode,
|
||||
inputFormatters: widget.inputFormatters,
|
||||
keyboardType: widget.keyBoardType,
|
||||
style: widget.textStyle ?? AppTextStyles.size16Regular,
|
||||
onTap: widget.onTap,
|
||||
textAlign: widget.textAlign ?? TextAlign.start,
|
||||
controller: widget.controller,
|
||||
validator: widget.validator,
|
||||
obscureText: widget.obscureText ? visibility : false,
|
||||
obscuringCharacter: "*",
|
||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||
decoration: InputDecoration(
|
||||
enabled: true,
|
||||
autofocus: true,
|
||||
maxLines: maxLines ?? 1,
|
||||
minLines: minLines ?? 1,
|
||||
onChanged: onChanged,
|
||||
focusNode: focusNode,
|
||||
inputFormatters: inputFormatters,
|
||||
keyboardType: keyBoardType,
|
||||
style: textStyle ?? AppTextStyles.size16Regular,
|
||||
onTap: onTap,
|
||||
textAlign: textAlign ?? TextAlign.start,
|
||||
controller: controller,
|
||||
validator: validator,
|
||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||
decoration: InputDecoration(
|
||||
enabled: true,
|
||||
filled: true,
|
||||
fillColor: fillColor ?? AppColors.cEEEEEE,
|
||||
hintText: hintText,
|
||||
hintStyle: hintTextStyle,
|
||||
prefixIconConstraints: BoxConstraints(minHeight: 24, minWidth: 0),
|
||||
prefixIcon: prefixIcon?.paddingOnly(left: 10).paddingAll(3),
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 12, horizontal: 12),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: borderRadius ?? AppUtils.kBorderRadius40,
|
||||
borderSide: BorderSide.none,
|
||||
),
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderRadius: borderRadius ?? AppUtils.kBorderRadius40,
|
||||
borderSide: BorderSide.none,
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: borderRadius ?? AppUtils.kBorderRadius40,
|
||||
borderSide: BorderSide.none,
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: borderRadius ?? AppUtils.kBorderRadius40,
|
||||
borderSide: BorderSide.none,
|
||||
),
|
||||
disabledBorder: OutlineInputBorder(
|
||||
borderRadius: borderRadius ?? AppUtils.kBorderRadius40,
|
||||
borderSide: BorderSide.none,
|
||||
),
|
||||
filled: true,
|
||||
|
||||
fillColor: widget.fillColor ?? AppColors.cEEEEEE,
|
||||
hintText: widget.hintText,
|
||||
hintStyle:
|
||||
widget.hintTextStyle ??
|
||||
AppTextStyles.size16Regular.copyWith(color: AppColors.c7F7F7F),
|
||||
suffixIcon: widget.obscureText
|
||||
? IconButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
visibility = !visibility;
|
||||
});
|
||||
},
|
||||
icon: Icon(
|
||||
visibility ? Icons.visibility : Icons.visibility_off,
|
||||
color: AppColors.c000000,
|
||||
),
|
||||
)
|
||||
: widget.suffixIcon,
|
||||
prefixIconConstraints: BoxConstraints(minHeight: 24, minWidth: 0),
|
||||
prefixIcon: widget.prefixIcon?.paddingOnly(left: 10).paddingAll(3),
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 12, horizontal: 12),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: widget.borderRadius ?? AppUtils.kBorderRadius40,
|
||||
borderSide: BorderSide.none,
|
||||
),
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderRadius: widget.borderRadius ?? AppUtils.kBorderRadius40,
|
||||
borderSide: BorderSide.none,
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: widget.borderRadius ?? AppUtils.kBorderRadius40,
|
||||
borderSide: BorderSide.none,
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: widget.borderRadius ?? AppUtils.kBorderRadius40,
|
||||
borderSide: BorderSide.none,
|
||||
),
|
||||
disabledBorder: OutlineInputBorder(
|
||||
borderRadius: widget.borderRadius ?? AppUtils.kBorderRadius40,
|
||||
borderSide: BorderSide.none,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
import 'package:toastification/toastification.dart';
|
||||
import '../../../../food_delivery_client.dart';
|
||||
|
||||
showErrorToast(String? message) {
|
||||
toastification.show(
|
||||
context: navigatorKey.currentContext,
|
||||
type: ToastificationType.error,
|
||||
style: ToastificationStyle.fillColored,
|
||||
title: Text(
|
||||
message ?? navigatorKey.currentContext!.loc.unexpected_error,
|
||||
maxLines: 5,
|
||||
),
|
||||
autoCloseDuration: TimeDelayConst.duration3,
|
||||
);
|
||||
}
|
||||
|
||||
showSuccessToast(String message) {
|
||||
toastification.show(
|
||||
context: navigatorKey.currentContext,
|
||||
type: ToastificationType.success,
|
||||
style: ToastificationStyle.fillColored,
|
||||
title: Text(message, maxLines: 5),
|
||||
autoCloseDuration: TimeDelayConst.duration3,
|
||||
);
|
||||
}
|
||||
|
||||
showWarningToast(String message) {
|
||||
toastification.show(
|
||||
context: navigatorKey.currentContext,
|
||||
type: ToastificationType.warning,
|
||||
style: ToastificationStyle.fillColored,
|
||||
title: Text(message, maxLines: 5),
|
||||
autoCloseDuration: TimeDelayConst.duration3,
|
||||
);
|
||||
}
|
||||
|
||||
showInfoToast(String message) {
|
||||
toastification.show(
|
||||
alignment: Alignment.bottomCenter,
|
||||
context: navigatorKey.currentContext,
|
||||
type: ToastificationType.info,
|
||||
style: ToastificationStyle.fillColored,
|
||||
title: Text(message, maxLines: 5),
|
||||
autoCloseDuration: TimeDelayConst.duration3,
|
||||
);
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:food_delivery_client/feature/common/presentation/blocs/language_bloc/language_bloc.dart';
|
||||
import 'package:toastification/toastification.dart';
|
||||
|
||||
import 'food_delivery_client.dart';
|
||||
|
||||
@@ -44,28 +45,30 @@ class _MyAppState extends State<MyApp> {
|
||||
return BlocBuilder<LanguageBloc, LanguageState>(
|
||||
bloc: context.read<LanguageBloc>()..add(LanguageEvent.started()),
|
||||
builder: (context, state) {
|
||||
return MaterialApp.router(
|
||||
title: "Uber Eats",
|
||||
debugShowCheckedModeBanner: false,
|
||||
theme: AppTheme.lightTheme,
|
||||
routerConfig: sl<AppRoutes>().router,
|
||||
locale: state.currentLocale,
|
||||
supportedLocales: L10n.locales,
|
||||
localizationsDelegates: [
|
||||
AppLocalizations.delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
builder: (context, child) => GestureDetector(
|
||||
onTap: () {
|
||||
FocusManager.instance.primaryFocus?.unfocus();
|
||||
},
|
||||
child: MediaQuery(
|
||||
data: MediaQuery.of(
|
||||
context,
|
||||
).copyWith(textScaler: const TextScaler.linear(1)),
|
||||
child: child!,
|
||||
return ToastificationWrapper(
|
||||
child: MaterialApp.router(
|
||||
title: "Uber Eats",
|
||||
debugShowCheckedModeBanner: false,
|
||||
theme: AppTheme.lightTheme,
|
||||
routerConfig: sl<AppRoutes>().router,
|
||||
locale: state.currentLocale,
|
||||
supportedLocales: L10n.locales,
|
||||
localizationsDelegates: [
|
||||
AppLocalizations.delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
builder: (context, child) => GestureDetector(
|
||||
onTap: () {
|
||||
FocusManager.instance.primaryFocus?.unfocus();
|
||||
},
|
||||
child: MediaQuery(
|
||||
data: MediaQuery.of(
|
||||
context,
|
||||
).copyWith(textScaler: const TextScaler.linear(1)),
|
||||
child: child!,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
24
pubspec.lock
24
pubspec.lock
@@ -397,6 +397,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.1.2"
|
||||
iconsax_flutter:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: iconsax_flutter
|
||||
sha256: d14b4cec8586025ac15276bdd40f6eea308cb85748135965bb6255f14beb2564
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
injectable:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -605,6 +613,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.0"
|
||||
pausable_timer:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pausable_timer
|
||||
sha256: "6ef1a95441ec3439de6fb63f39a011b67e693198e7dae14e20675c3c00e86074"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.0+3"
|
||||
petitparser:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -882,6 +898,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.6"
|
||||
toastification:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: toastification
|
||||
sha256: "69db2bff425b484007409650d8bcd5ed1ce2e9666293ece74dcd917dacf23112"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.3"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@@ -24,6 +24,8 @@ dependencies:
|
||||
dartz: ^0.10.1
|
||||
mask_text_input_formatter: ^2.9.0
|
||||
|
||||
#for notify user about error or success
|
||||
toastification: ^3.0.3
|
||||
|
||||
#DI
|
||||
get_it: ^8.2.0
|
||||
|
||||
Reference in New Issue
Block a user