feat: login page ui done
This commit is contained in:
261
assets/icons/common/ic_login.svg
Normal file
261
assets/icons/common/ic_login.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 126 KiB |
8
assets/icons/common/ic_visibility.svg
Normal file
8
assets/icons/common/ic_visibility.svg
Normal file
@@ -0,0 +1,8 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M12.9833 10C12.9833 11.65 11.6499 12.9833 9.99993 12.9833C8.34993 12.9833 7.0166 11.65 7.0166 10C7.0166 8.35 8.34993 7.01666 9.99993 7.01666C11.6499 7.01666 12.9833 8.35 12.9833 10Z"
|
||||
stroke="#A7AEC1" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
|
||||
<path
|
||||
d="M10.0001 16.8916C12.9418 16.8916 15.6834 15.1583 17.5918 12.1583C18.3418 10.9833 18.3418 9.00831 17.5918 7.83331C15.6834 4.83331 12.9418 3.09998 10.0001 3.09998C7.05845 3.09998 4.31678 4.83331 2.40845 7.83331C1.65845 9.00831 1.65845 10.9833 2.40845 12.1583C4.31678 15.1583 7.05845 16.8916 10.0001 16.8916Z"
|
||||
stroke="#A7AEC1" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 823 B |
17
assets/icons/common/ic_visibility_off.svg
Normal file
17
assets/icons/common/ic_visibility_off.svg
Normal file
@@ -0,0 +1,17 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M12.1083 7.89166L7.8916 12.1083C7.34994 11.5667 7.0166 10.825 7.0166 10C7.0166 8.35 8.34994 7.01666 9.99994 7.01666C10.8249 7.01666 11.5666 7.35 12.1083 7.89166Z"
|
||||
stroke="#A7AEC1" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
|
||||
<path
|
||||
d="M14.8501 4.80834C13.3918 3.70834 11.7251 3.10834 10.0001 3.10834C7.05845 3.10834 4.31678 4.84167 2.40845 7.84167C1.65845 9.01667 1.65845 10.9917 2.40845 12.1667C3.06678 13.2 3.83345 14.0917 4.66678 14.8083"
|
||||
stroke="#A7AEC1" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
|
||||
<path
|
||||
d="M7.0166 16.275C7.9666 16.675 8.97493 16.8917 9.99993 16.8917C12.9416 16.8917 15.6833 15.1583 17.5916 12.1583C18.3416 10.9833 18.3416 9.00834 17.5916 7.83334C17.3166 7.4 17.0166 6.99167 16.7083 6.60834"
|
||||
stroke="#A7AEC1" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
|
||||
<path d="M12.925 10.5833C12.7083 11.7583 11.75 12.7166 10.575 12.9333" stroke="#A7AEC1"
|
||||
stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
|
||||
<path d="M7.89175 12.1083L1.66675 18.3333" stroke="#A7AEC1" stroke-width="1.5"
|
||||
stroke-linecap="round" stroke-linejoin="round" />
|
||||
<path d="M18.3334 1.66669L12.1084 7.89169" stroke="#A7AEC1" stroke-width="1.5"
|
||||
stroke-linecap="round" stroke-linejoin="round" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
6
assets/icons/dark/ic_arrow_left.svg
Normal file
6
assets/icons/dark/ic_arrow_left.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8.77254 5.43582L3.20837 11L8.77254 16.5642" stroke="white" stroke-width="1.5"
|
||||
stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round" />
|
||||
<path d="M18.7916 11H3.36414" stroke="white" stroke-width="1.5" stroke-miterlimit="10"
|
||||
stroke-linecap="round" stroke-linejoin="round" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 425 B |
4
assets/icons/light/ic_arrow_left.svg
Normal file
4
assets/icons/light/ic_arrow_left.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8.77217 5.43585L3.20801 11L8.77217 16.5642" stroke="#151B33" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M18.7918 11H3.36426" stroke="#151B33" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 403 B |
@@ -10,6 +10,26 @@
|
||||
"onboarding_button_next": "Next",
|
||||
"onboarding_title_2": "A place for extraordinary people in the world",
|
||||
"onboarding_subtitle_2": "Discover your favorite meals and get them delivered fast wherever you are.",
|
||||
"onboarding_button_get_started": "Get Started"
|
||||
"onboarding_button_get_started": "Get Started",
|
||||
"welcome_to_volt": "Welcome to {name}",
|
||||
"@welcome_to_volt":{
|
||||
"placeholders": {
|
||||
"name": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"please_login": "Please login to your account",
|
||||
"email_or_phone": "Phone Number",
|
||||
"enter_email_or_phone": "Enter your email or phone number",
|
||||
"password": "Password",
|
||||
"enter_password": "Enter your password",
|
||||
"forgot_password": "Forgot Password?",
|
||||
"login": "Login",
|
||||
"or_login_with": "Or login with",
|
||||
"google": "Google",
|
||||
"facebook": "Facebook",
|
||||
"dont_have_account": "Don’t have an account?",
|
||||
"register": "Register"
|
||||
|
||||
}
|
||||
@@ -10,6 +10,26 @@
|
||||
"onboarding_button_next": "Далее",
|
||||
"onboarding_title_2": "Место для выдающихся людей по всему миру",
|
||||
"onboarding_subtitle_2": "Находите свои любимые блюда и получайте их быстро, где бы вы ни находились.",
|
||||
"onboarding_button_get_started": "Начать"
|
||||
"onboarding_button_get_started": "Начать",
|
||||
"welcome_to_volt": "Добро пожаловать в {name}",
|
||||
"@welcome_to_volt":{
|
||||
"placeholders": {
|
||||
"name": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"please_login": "Пожалуйста, войдите в свой аккаунт",
|
||||
"email_or_phone": "Номер телефона",
|
||||
"enter_email_or_phone": "Введите свою почту или номер телефона",
|
||||
"password": "Пароль",
|
||||
"enter_password": "Введите свой пароль",
|
||||
"forgot_password": "Забыли пароль?",
|
||||
"login": "Войти",
|
||||
"or_login_with": "Или войдите с помощью",
|
||||
"google": "Google",
|
||||
"facebook": "Facebook",
|
||||
"dont_have_account": "У вас нет аккаунта?",
|
||||
"register": "Зарегистрироваться"
|
||||
|
||||
}
|
||||
@@ -10,6 +10,26 @@
|
||||
"onboarding_button_next": "Keyingi",
|
||||
"onboarding_title_2": "Butun dunyodagi ajoyib insonlar uchun joy",
|
||||
"onboarding_subtitle_2": "Sevimli taomlaringizni toping va ularni tezda yetkazib oling, qaerda bo‘lishingizdan qat’i nazar.",
|
||||
"onboarding_button_get_started": "Boshlash"
|
||||
"onboarding_button_get_started": "Boshlash",
|
||||
"welcome_to_volt": "{name} ilovasiga xush kelibsiz",
|
||||
"@welcome_to_volt":{
|
||||
"placeholders": {
|
||||
"name": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"please_login": "Iltimos, akkauntingizga kiring",
|
||||
"email_or_phone": "Telefon raqami",
|
||||
"enter_email_or_phone": "Email yoki telefon raqamingizni kiriting",
|
||||
"password": "Parol",
|
||||
"enter_password": "Parolingizni kiriting",
|
||||
"forgot_password": "Parolni unutdingizmi?",
|
||||
"login": "Kirish",
|
||||
"or_login_with": "Yoki quyidagi orqali kiring",
|
||||
"google": "Google",
|
||||
"facebook": "Facebook",
|
||||
"dont_have_account": "Akkauntingiz yo‘qmi?",
|
||||
"register": "Ro‘yxatdan o‘tish"
|
||||
|
||||
}
|
||||
@@ -4,6 +4,8 @@ abstract class AppLocaleKeys {
|
||||
static const String browseSearchHistory = 'browse-search-history';
|
||||
static const String token = 'token';
|
||||
|
||||
static const String appName = "Felix Eats";
|
||||
|
||||
static const String fontBlack = "fontBlack";
|
||||
static const String fontBold = "fontBold";
|
||||
static const String fontSemiBold = "fontSemiBold";
|
||||
|
||||
@@ -171,6 +171,84 @@ abstract class AppLocalizations {
|
||||
/// In en, this message translates to:
|
||||
/// **'Get Started'**
|
||||
String get onboarding_button_get_started;
|
||||
|
||||
/// No description provided for @welcome_to_volt.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Welcome to {name}'**
|
||||
String welcome_to_volt(String name);
|
||||
|
||||
/// No description provided for @please_login.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Please login to your account'**
|
||||
String get please_login;
|
||||
|
||||
/// No description provided for @email_or_phone.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Phone Number'**
|
||||
String get email_or_phone;
|
||||
|
||||
/// No description provided for @enter_email_or_phone.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Enter your email or phone number'**
|
||||
String get enter_email_or_phone;
|
||||
|
||||
/// 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 your 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 @login.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Login'**
|
||||
String get login;
|
||||
|
||||
/// No description provided for @or_login_with.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Or login with'**
|
||||
String get or_login_with;
|
||||
|
||||
/// No description provided for @google.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Google'**
|
||||
String get google;
|
||||
|
||||
/// No description provided for @facebook.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Facebook'**
|
||||
String get facebook;
|
||||
|
||||
/// 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 @register.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Register'**
|
||||
String get register;
|
||||
}
|
||||
|
||||
class _AppLocalizationsDelegate
|
||||
|
||||
@@ -49,4 +49,45 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get onboarding_button_get_started => 'Get Started';
|
||||
|
||||
@override
|
||||
String welcome_to_volt(String name) {
|
||||
return 'Welcome to $name';
|
||||
}
|
||||
|
||||
@override
|
||||
String get please_login => 'Please login to your account';
|
||||
|
||||
@override
|
||||
String get email_or_phone => 'Phone Number';
|
||||
|
||||
@override
|
||||
String get enter_email_or_phone => 'Enter your email or phone number';
|
||||
|
||||
@override
|
||||
String get password => 'Password';
|
||||
|
||||
@override
|
||||
String get enter_password => 'Enter your password';
|
||||
|
||||
@override
|
||||
String get forgot_password => 'Forgot Password?';
|
||||
|
||||
@override
|
||||
String get login => 'Login';
|
||||
|
||||
@override
|
||||
String get or_login_with => 'Or login with';
|
||||
|
||||
@override
|
||||
String get google => 'Google';
|
||||
|
||||
@override
|
||||
String get facebook => 'Facebook';
|
||||
|
||||
@override
|
||||
String get dont_have_account => 'Don’t have an account?';
|
||||
|
||||
@override
|
||||
String get register => 'Register';
|
||||
}
|
||||
|
||||
@@ -47,4 +47,45 @@ class AppLocalizationsRu extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get onboarding_button_get_started => 'Начать';
|
||||
|
||||
@override
|
||||
String welcome_to_volt(String name) {
|
||||
return 'Добро пожаловать в $name';
|
||||
}
|
||||
|
||||
@override
|
||||
String get please_login => 'Пожалуйста, войдите в свой аккаунт';
|
||||
|
||||
@override
|
||||
String get email_or_phone => 'Номер телефона';
|
||||
|
||||
@override
|
||||
String get enter_email_or_phone => 'Введите свою почту или номер телефона';
|
||||
|
||||
@override
|
||||
String get password => 'Пароль';
|
||||
|
||||
@override
|
||||
String get enter_password => 'Введите свой пароль';
|
||||
|
||||
@override
|
||||
String get forgot_password => 'Забыли пароль?';
|
||||
|
||||
@override
|
||||
String get login => 'Войти';
|
||||
|
||||
@override
|
||||
String get or_login_with => 'Или войдите с помощью';
|
||||
|
||||
@override
|
||||
String get google => 'Google';
|
||||
|
||||
@override
|
||||
String get facebook => 'Facebook';
|
||||
|
||||
@override
|
||||
String get dont_have_account => 'У вас нет аккаунта?';
|
||||
|
||||
@override
|
||||
String get register => 'Зарегистрироваться';
|
||||
}
|
||||
|
||||
@@ -47,4 +47,45 @@ class AppLocalizationsUz extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get onboarding_button_get_started => 'Boshlash';
|
||||
|
||||
@override
|
||||
String welcome_to_volt(String name) {
|
||||
return '$name ilovasiga xush kelibsiz';
|
||||
}
|
||||
|
||||
@override
|
||||
String get please_login => 'Iltimos, akkauntingizga kiring';
|
||||
|
||||
@override
|
||||
String get email_or_phone => 'Telefon raqami';
|
||||
|
||||
@override
|
||||
String get enter_email_or_phone => 'Email yoki telefon raqamingizni kiriting';
|
||||
|
||||
@override
|
||||
String get password => 'Parol';
|
||||
|
||||
@override
|
||||
String get enter_password => 'Parolingizni kiriting';
|
||||
|
||||
@override
|
||||
String get forgot_password => 'Parolni unutdingizmi?';
|
||||
|
||||
@override
|
||||
String get login => 'Kirish';
|
||||
|
||||
@override
|
||||
String get or_login_with => 'Yoki quyidagi orqali kiring';
|
||||
|
||||
@override
|
||||
String get google => 'Google';
|
||||
|
||||
@override
|
||||
String get facebook => 'Facebook';
|
||||
|
||||
@override
|
||||
String get dont_have_account => 'Akkauntingiz yo‘qmi?';
|
||||
|
||||
@override
|
||||
String get register => 'Ro‘yxatdan o‘tish';
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:food_delivery_client/feature/auth/presentation/login_page/login_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';
|
||||
|
||||
@@ -20,6 +21,11 @@ class AppRoutes {
|
||||
path: Routes.onBoarding,
|
||||
pageBuilder: (context, state) => CupertinoPage(child: OnboardingPage()),
|
||||
),
|
||||
|
||||
GoRoute(
|
||||
path: Routes.login,
|
||||
pageBuilder: (context, state) => CupertinoPage(child: LoginPage()),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -50,7 +50,9 @@ abstract class AppColors {
|
||||
static const Color cFFAB40 = Color(0xFFFFAB40);
|
||||
static const Color cD6D4D4 = Color(0xFFD6D4D4);
|
||||
static const Color c1A202C = Color(0xFF1A202C);
|
||||
static const Color c524242 = Color(0xFF524242 );
|
||||
|
||||
static const Color c524242 = Color(0xFF524242);
|
||||
static const Color cE2E4EA = Color(0xFFE2E4EA);
|
||||
static const Color cA7AEC1 = Color(0xFFA7AEC1);
|
||||
static const Color c151B33 = Color(0xFF151B33);
|
||||
|
||||
}
|
||||
|
||||
@@ -4,15 +4,20 @@ abstract class AppIcons {
|
||||
static const String icOnBoarding1 = "$baseUrl/ic_onboarding1.svg";
|
||||
static const String icOnBoarding2 = "$baseUrl/ic_onboarding2.svg";
|
||||
static const String icOnBoarding3 = "$baseUrl/ic_onboarding3.svg";
|
||||
static const String icLogin = "$baseUrl/ic_login.svg";
|
||||
static const String icVisibility = "$baseUrl/ic_visibility.svg";
|
||||
static const String icVisibilityOff = "$baseUrl/ic_visibility_off.svg";
|
||||
|
||||
}
|
||||
|
||||
abstract class AppLightSvgs {
|
||||
static const String baseUrl = "assets/icons/light";
|
||||
|
||||
static const String icSplash = "$baseUrl/ic_splash.svg";
|
||||
static const String icArrowLeft = "$baseUrl/ic_arrow_left.svg";
|
||||
}
|
||||
|
||||
abstract class AppDarkSvgs {
|
||||
static const String baseUrl = "assets/icons/dark";
|
||||
static const String icSplash = "$baseUrl/ic_splash.svg";
|
||||
static const String icArrowLeft = "$baseUrl/ic_arrow_left.svg";
|
||||
}
|
||||
|
||||
@@ -4,35 +4,57 @@ import 'package:food_delivery_client/food_delivery_client.dart';
|
||||
class AppThemeColors extends ThemeExtension<AppThemeColors> {
|
||||
final Color onBoardingColor;
|
||||
final Color boxShadow;
|
||||
final Color iconColor;
|
||||
final Color buttonInactiveColor;
|
||||
final Color borderColor;
|
||||
|
||||
AppThemeColors({required this.onBoardingColor, required this.boxShadow});
|
||||
|
||||
AppThemeColors({
|
||||
required this.onBoardingColor,
|
||||
required this.boxShadow,
|
||||
required this.iconColor,
|
||||
required this.buttonInactiveColor,
|
||||
required this.borderColor
|
||||
});
|
||||
|
||||
static AppThemeColors light = AppThemeColors(
|
||||
onBoardingColor: AppColors.cFFFFFF,
|
||||
boxShadow: AppColors.cD6D4D4,
|
||||
onBoardingColor: AppColors.cFFFFFF,
|
||||
boxShadow: AppColors.cD6D4D4,
|
||||
buttonInactiveColor: AppColors.cE2E4EA,
|
||||
iconColor: AppColors.cFFFFFF,
|
||||
borderColor:AppColors.cE2E4EA
|
||||
|
||||
);
|
||||
|
||||
static AppThemeColors dark = AppThemeColors(
|
||||
onBoardingColor: AppColors.c131720,
|
||||
boxShadow: AppColors.c524242,
|
||||
onBoardingColor: AppColors.c131720,
|
||||
boxShadow: AppColors.c524242,
|
||||
buttonInactiveColor: AppColors.c292F3D,
|
||||
iconColor: AppColors.c131720,
|
||||
borderColor: AppColors.c292F3D
|
||||
);
|
||||
|
||||
@override
|
||||
ThemeExtension<AppThemeColors> copyWith({
|
||||
Color? onBoardingColor,
|
||||
Color? boxShadow,
|
||||
Color? iconColor,
|
||||
Color? buttonInactiveColor,
|
||||
Color? borderColor
|
||||
}) {
|
||||
return AppThemeColors(
|
||||
onBoardingColor: onBoardingColor ?? this.onBoardingColor,
|
||||
boxShadow: boxShadow ?? this.boxShadow,
|
||||
iconColor: iconColor ?? this.iconColor,
|
||||
buttonInactiveColor: buttonInactiveColor ?? this.buttonInactiveColor,
|
||||
borderColor: borderColor??this.borderColor
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
ThemeExtension<AppThemeColors> lerp(
|
||||
covariant ThemeExtension<AppThemeColors>? other,
|
||||
double t,
|
||||
) {
|
||||
covariant ThemeExtension<AppThemeColors>? other,
|
||||
double t,) {
|
||||
if (other is! AppThemeColors) return this;
|
||||
return t < 0.5 ? this : other;
|
||||
}
|
||||
|
||||
@@ -42,13 +42,17 @@ class AppThemeTextStyles extends ThemeExtension<AppThemeTextStyles> {
|
||||
static AppThemeTextStyles light = AppThemeTextStyles(
|
||||
size14Regular: TextStyle(
|
||||
fontSize: 14,
|
||||
height: 1.6,
|
||||
fontWeight: FontWeight.w400,
|
||||
fontFamily: _fontRegular,
|
||||
color: AppColors.c151B33,
|
||||
),
|
||||
size16Medium: TextStyle(
|
||||
fontSize: 16,
|
||||
height: 1.3,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontFamily: _fontMedium,
|
||||
color: AppColors.c151B33,
|
||||
),
|
||||
size16SemiBold: TextStyle(
|
||||
fontSize: 16,
|
||||
@@ -70,8 +74,10 @@ class AppThemeTextStyles extends ThemeExtension<AppThemeTextStyles> {
|
||||
),
|
||||
size24Bold: TextStyle(
|
||||
fontSize: 24,
|
||||
height: 1.3,
|
||||
fontWeight: FontWeight.w700,
|
||||
fontFamily: _fontBold,
|
||||
color: AppColors.c151B33,
|
||||
),
|
||||
size64Black: TextStyle(
|
||||
fontSize: 64,
|
||||
@@ -84,13 +90,17 @@ class AppThemeTextStyles extends ThemeExtension<AppThemeTextStyles> {
|
||||
static AppThemeTextStyles dark = AppThemeTextStyles(
|
||||
size14Regular: TextStyle(
|
||||
fontSize: 14,
|
||||
height: 1.6,
|
||||
fontWeight: FontWeight.w400,
|
||||
fontFamily: _fontRegular,
|
||||
color: AppColors.cFFFFFF,
|
||||
),
|
||||
size16Medium: TextStyle(
|
||||
fontSize: 16,
|
||||
height: 1.3,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontFamily: _fontMedium,
|
||||
color: AppColors.cFFFFFF,
|
||||
),
|
||||
size16SemiBold: TextStyle(
|
||||
fontSize: 16,
|
||||
@@ -112,8 +122,10 @@ class AppThemeTextStyles extends ThemeExtension<AppThemeTextStyles> {
|
||||
),
|
||||
size24Bold: TextStyle(
|
||||
fontSize: 24,
|
||||
height: 1.3,
|
||||
fontWeight: FontWeight.w700,
|
||||
fontFamily: _fontBold,
|
||||
color: AppColors.cFFFFFF,
|
||||
),
|
||||
size64Black: TextStyle(
|
||||
fontSize: 64,
|
||||
|
||||
@@ -3,16 +3,29 @@ import 'package:food_delivery_client/core/core.dart';
|
||||
|
||||
class AppThemeIcons extends ThemeExtension<AppThemeIcons> {
|
||||
final String icSplash;
|
||||
final String icArrowLeft;
|
||||
|
||||
AppThemeIcons({required this.icSplash});
|
||||
AppThemeIcons({required this.icSplash, required this.icArrowLeft});
|
||||
|
||||
static AppThemeIcons light = AppThemeIcons(icSplash: AppLightSvgs.icSplash);
|
||||
static AppThemeIcons light = AppThemeIcons(
|
||||
icSplash: AppLightSvgs.icSplash,
|
||||
icArrowLeft: AppLightSvgs.icArrowLeft,
|
||||
);
|
||||
|
||||
static AppThemeIcons dark = AppThemeIcons(icSplash: AppDarkSvgs.icSplash);
|
||||
static AppThemeIcons dark = AppThemeIcons(
|
||||
icSplash: AppDarkSvgs.icSplash,
|
||||
icArrowLeft: AppDarkSvgs.icArrowLeft,
|
||||
);
|
||||
|
||||
@override
|
||||
ThemeExtension<AppThemeIcons> copyWith({String? icSplash}) {
|
||||
return AppThemeIcons(icSplash: icSplash ?? this.icSplash);
|
||||
ThemeExtension<AppThemeIcons> copyWith({
|
||||
String? icSplash,
|
||||
String? icArrowLeft,
|
||||
}) {
|
||||
return AppThemeIcons(
|
||||
icSplash: icSplash ?? this.icSplash,
|
||||
icArrowLeft: icArrowLeft ?? this.icArrowLeft,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
import '../../food_delivery_client.dart';
|
||||
|
||||
abstract class AppUtils {
|
||||
static const Gradient kGradient = LinearGradient(
|
||||
begin: AlignmentGeometry.bottomCenter,
|
||||
end: AlignmentGeometry.topCenter,
|
||||
colors: [AppColors.cFF6F00, AppColors.cFFAB40],
|
||||
);
|
||||
|
||||
static const SizedBox kSizedBox = SizedBox.shrink();
|
||||
|
||||
static const Radius kRadius = Radius.zero;
|
||||
|
||||
15
lib/feature/auth/presentation/login_page/login_page.dart
Normal file
15
lib/feature/auth/presentation/login_page/login_page.dart
Normal file
@@ -0,0 +1,15 @@
|
||||
import 'package:food_delivery_client/feature/auth/presentation/login_page/widgets/login_body.dart';
|
||||
import 'package:food_delivery_client/feature/common/presentation/widgets/w_back_button.dart';
|
||||
|
||||
import '../../../../food_delivery_client.dart';
|
||||
|
||||
class LoginPage extends StatelessWidget {
|
||||
const LoginPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WLoginBody();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
155
lib/feature/auth/presentation/login_page/widgets/login_body.dart
Normal file
155
lib/feature/auth/presentation/login_page/widgets/login_body.dart
Normal file
@@ -0,0 +1,155 @@
|
||||
import 'package:food_delivery_client/feature/auth/presentation/login_page/widgets/welcome_text.dart';
|
||||
import 'package:food_delivery_client/feature/common/presentation/widgets/app_text_form_field.dart';
|
||||
|
||||
import '../../../../../food_delivery_client.dart';
|
||||
|
||||
class WLoginBody extends StatefulWidget {
|
||||
const WLoginBody({super.key});
|
||||
|
||||
@override
|
||||
State<WLoginBody> createState() => _WLoginBodyState();
|
||||
}
|
||||
|
||||
class _WLoginBodyState extends State<WLoginBody> {
|
||||
late TextEditingController _phoneNumberController;
|
||||
late TextEditingController _passwordController;
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_phoneNumberController = TextEditingController();
|
||||
_passwordController = TextEditingController();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_phoneNumberController.dispose();
|
||||
_passwordController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Form(
|
||||
key: _formKey,
|
||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||
child: WLayout(
|
||||
top: false,
|
||||
child: Scaffold(
|
||||
body: Stack(
|
||||
children: [
|
||||
SvgPicture.asset(AppIcons.icLogin),
|
||||
Positioned(
|
||||
child: Material(
|
||||
color: AppColors.cTransparent,
|
||||
child:
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
30.verticalSpace,
|
||||
WBackButton(),
|
||||
20.verticalSpace,
|
||||
WelcomeText(
|
||||
text: context.loc.welcome_to_volt(
|
||||
AppLocaleKeys.appName,
|
||||
),
|
||||
),
|
||||
8.verticalSpace,
|
||||
Text(
|
||||
context.loc.please_login,
|
||||
style: AppTextStyles.size14Regular.copyWith(
|
||||
color: AppColors.cA7AEC1,
|
||||
height: 1.6,
|
||||
),
|
||||
),
|
||||
54.verticalSpace,
|
||||
Text(
|
||||
context.loc.email_or_phone,
|
||||
style: context.appThemeTextStyles.size16Medium,
|
||||
),
|
||||
10.verticalSpace,
|
||||
AppTextFormField(
|
||||
controller: _phoneNumberController,
|
||||
hintText: context.loc.enter_email_or_phone,
|
||||
),
|
||||
20.verticalSpace,
|
||||
Text(
|
||||
context.loc.password,
|
||||
style: context.appThemeTextStyles.size16Medium,
|
||||
),
|
||||
10.verticalSpace,
|
||||
AppTextFormField(
|
||||
obscureText: true,
|
||||
controller: _passwordController,
|
||||
hintText: context.loc.enter_password,
|
||||
),
|
||||
10.verticalSpace,
|
||||
Align(
|
||||
alignment: AlignmentGeometry.centerRight,
|
||||
child: TextButton(
|
||||
onPressed: () {},
|
||||
child: Text(
|
||||
context.loc.forgot_password,
|
||||
style: AppTextStyles.size14Regular.copyWith(
|
||||
color: AppColors.cFF6F00,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
60.verticalSpace,
|
||||
AppButton(
|
||||
name: context.loc.login,
|
||||
onPressed: () {
|
||||
if (_formKey.currentState?.validate() ?? false) {}
|
||||
},
|
||||
),
|
||||
15.verticalSpace,
|
||||
Align(
|
||||
alignment: AlignmentGeometry.center,
|
||||
child: RichText(
|
||||
text: TextSpan(
|
||||
text: context.loc.dont_have_account,
|
||||
style: context.appThemeTextStyles.size14Regular,
|
||||
children: [
|
||||
WidgetSpan(
|
||||
baseline: TextBaseline.alphabetic,
|
||||
alignment: PlaceholderAlignment.baseline,
|
||||
|
||||
child: TextButton(
|
||||
onPressed: () {},
|
||||
style: ButtonStyle(
|
||||
shadowColor: WidgetStatePropertyAll(
|
||||
AppColors.cFF6F00.newWithOpacity(.2),
|
||||
),
|
||||
padding: WidgetStatePropertyAll(
|
||||
EdgeInsets.zero,
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
context.loc.register,
|
||||
style: AppTextStyles.size14Bold
|
||||
.copyWith(color: AppColors.cFF6F00),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
).paddingOnly(
|
||||
left: 24,
|
||||
right: 24,
|
||||
top: context.mq.viewPadding.top,
|
||||
bottom: context.mq.viewPadding.bottom,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
import '../../../../../food_delivery_client.dart';
|
||||
|
||||
class WelcomeText extends StatelessWidget {
|
||||
final String text;
|
||||
|
||||
const WelcomeText({Key? key, required this.text}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final voltIndex = text.toLowerCase().indexOf(
|
||||
AppLocaleKeys.appName.toLowerCase(),
|
||||
);
|
||||
|
||||
if (voltIndex == -1) {
|
||||
return Text(
|
||||
text,
|
||||
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
|
||||
);
|
||||
}
|
||||
|
||||
final before = text.substring(0, voltIndex);
|
||||
final volt = text.substring(
|
||||
voltIndex,
|
||||
voltIndex + AppLocaleKeys.appName.length,
|
||||
);
|
||||
final after = text.substring(voltIndex + AppLocaleKeys.appName.length);
|
||||
|
||||
return Text.rich(
|
||||
TextSpan(
|
||||
children: [
|
||||
TextSpan(text: before, style: context.appThemeTextStyles.size24Bold),
|
||||
WidgetSpan(
|
||||
alignment: PlaceholderAlignment.baseline,
|
||||
baseline: TextBaseline.alphabetic,
|
||||
child: ShaderMask(
|
||||
shaderCallback: (bounds) =>
|
||||
AppUtils.kGradient.createShader(bounds),
|
||||
child: Text(
|
||||
volt,
|
||||
style: context.appThemeTextStyles.size24Bold.copyWith(
|
||||
color: AppColors.cFFFFFF,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
// "Volt" dan keyingi text
|
||||
TextSpan(text: after, style: context.appThemeTextStyles.size24Bold),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
export 'presentation/widgets/widgets.dart';
|
||||
export 'presentation/blocs/language_bloc/language_bloc.dart';
|
||||
export 'data/models/success_model.dart';
|
||||
export 'data/models/success_model.dart';
|
||||
|
||||
@@ -57,10 +57,10 @@ class AppButton extends StatelessWidget {
|
||||
mainAxisAlignment:
|
||||
mainAxisAlignment ?? MainAxisAlignment.center,
|
||||
children: [
|
||||
leading?? AppUtils.kSizedBox,
|
||||
leading ?? AppUtils.kSizedBox,
|
||||
Text(
|
||||
name,
|
||||
style: AppTextStyles.size16Bold.copyWith(
|
||||
style: AppTextStyles.size14Bold.copyWith(
|
||||
color: AppColors.cFFFFFF,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -55,67 +55,92 @@ class _AppTextFormFieldState extends State<AppTextFormField> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
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(
|
||||
return DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
offset: const Offset(0, 4),
|
||||
color: AppColors.cA7AEC1.newWithOpacity(.15),
|
||||
blurRadius: 70,
|
||||
),
|
||||
],
|
||||
),
|
||||
child: TextFormField(
|
||||
enabled: true,
|
||||
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,
|
||||
//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 ?? context.appThemeTextStyles.size14Regular,
|
||||
onTap: widget.onTap,
|
||||
textAlign: widget.textAlign ?? TextAlign.start,
|
||||
controller: widget.controller,
|
||||
validator: widget.validator,
|
||||
obscureText: widget.obscureText ? visibility : false,
|
||||
obscuringCharacter: "*",
|
||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||
cursorColor: AppColors.cFF6F00,
|
||||
decoration: InputDecoration(
|
||||
enabled: true,
|
||||
filled: true,
|
||||
fillColor: context.appThemeColors.iconColor ?? AppColors.cEEEEEE,
|
||||
hintText: widget.hintText,
|
||||
hintStyle:
|
||||
widget.hintTextStyle ??
|
||||
context.appThemeTextStyles.size14Regular.copyWith(
|
||||
color: AppColors.cA7AEC1,
|
||||
),
|
||||
suffixIcon: widget.obscureText
|
||||
? IconButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
visibility = !visibility;
|
||||
});
|
||||
},
|
||||
icon: SvgPicture.asset(
|
||||
visibility ? AppIcons.icVisibility : AppIcons.icVisibilityOff,
|
||||
color: AppColors.c000000,
|
||||
),
|
||||
)
|
||||
: widget.suffixIcon,
|
||||
prefixIconConstraints: BoxConstraints(minHeight: 24, minWidth: 0),
|
||||
prefixIcon: widget.prefixIcon?.paddingOnly(left: 10).paddingAll(3),
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16, horizontal: 14),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: widget.borderRadius ?? AppUtils.kBorderRadius16,
|
||||
borderSide: BorderSide(
|
||||
color: context.appThemeColors.borderColor,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderRadius: widget.borderRadius ?? AppUtils.kBorderRadius16,
|
||||
borderSide: BorderSide(
|
||||
color: context.appThemeColors.borderColor,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: widget.borderRadius ?? AppUtils.kBorderRadius16,
|
||||
borderSide: BorderSide(
|
||||
color: context.appThemeColors.borderColor,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: widget.borderRadius ?? AppUtils.kBorderRadius16,
|
||||
borderSide: BorderSide(color: AppColors.cFF6F00, width: 1),
|
||||
),
|
||||
disabledBorder: OutlineInputBorder(
|
||||
borderRadius: widget.borderRadius ?? AppUtils.kBorderRadius40,
|
||||
borderSide: BorderSide(
|
||||
color: context.appThemeColors.borderColor,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
31
lib/feature/common/presentation/widgets/w_back_button.dart
Normal file
31
lib/feature/common/presentation/widgets/w_back_button.dart
Normal file
@@ -0,0 +1,31 @@
|
||||
import '../../../../food_delivery_client.dart';
|
||||
|
||||
class WBackButton extends StatelessWidget {
|
||||
const WBackButton({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return InkWell(
|
||||
onTap: () {},
|
||||
borderRadius: AppUtils.kBorderRadius22,
|
||||
child: Ink(
|
||||
height: 44,
|
||||
width: 44,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: AppUtils.kBorderRadius22,
|
||||
color: context.appThemeColors.iconColor,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: AppColors.cA7AEC1.newWithOpacity(.3),
|
||||
offset: const Offset(0, 4),
|
||||
blurRadius: 80,
|
||||
),
|
||||
],
|
||||
),
|
||||
child: SvgPicture.asset(
|
||||
context.appThemeIcons.icArrowLeft,
|
||||
).paddingAll(10),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -5,3 +5,4 @@ export 'w_stories_list_item.dart';
|
||||
export 'w_custom_modal_bottom_sheet.dart';
|
||||
export 'app_button.dart';
|
||||
export 'app_list_tile.dart';
|
||||
export 'w_back_button.dart';
|
||||
|
||||
@@ -73,9 +73,8 @@ class _OnboardingPageState extends State<OnboardingPage> {
|
||||
onPressed: () {
|
||||
if (currentIndex < 1) {
|
||||
onPressed();
|
||||
}
|
||||
if (currentIndex == 1) {
|
||||
log("Navigate to login");
|
||||
} else {
|
||||
context.go(Routes.login);
|
||||
}
|
||||
},
|
||||
),
|
||||
|
||||
@@ -31,15 +31,11 @@ class SplashPage extends StatelessWidget {
|
||||
Center(child: SvgPicture.asset(AppIcons.icLogo)),
|
||||
ShaderMask(
|
||||
shaderCallback: (bounds) =>
|
||||
const LinearGradient(
|
||||
begin: AlignmentGeometry.bottomCenter,
|
||||
end: AlignmentGeometry.topCenter,
|
||||
colors: [AppColors.cFF6F00, AppColors.cFFAB40],
|
||||
).createShader(
|
||||
AppUtils.kGradient.createShader(
|
||||
Rect.fromLTWH(0, 0, bounds.width, bounds.height),
|
||||
),
|
||||
child: Text(
|
||||
"Felix Eats",
|
||||
AppLocaleKeys.appName,
|
||||
style: context.appThemeTextStyles.size64Black,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -46,11 +46,11 @@ class _MyAppState extends State<MyApp> {
|
||||
builder: (context, state) {
|
||||
return ToastificationWrapper(
|
||||
child: MaterialApp.router(
|
||||
title: "Felix Eats",
|
||||
title: AppLocaleKeys.appName,
|
||||
debugShowCheckedModeBanner: false,
|
||||
theme: AppTheme.lightTheme,
|
||||
darkTheme: AppTheme.darkTheme,
|
||||
themeMode: ThemeMode.light,
|
||||
themeMode: ThemeMode.dark,
|
||||
routerConfig: sl<AppRoutes>().router,
|
||||
locale: state.currentLocale,
|
||||
supportedLocales: L10n.locales,
|
||||
|
||||
Reference in New Issue
Block a user