diff --git a/assets/icons/common/ic_cart.svg b/assets/icons/common/ic_cart.svg new file mode 100644 index 0000000..7172517 --- /dev/null +++ b/assets/icons/common/ic_cart.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/icons/common/ic_cart1.svg b/assets/icons/common/ic_cart1.svg new file mode 100644 index 0000000..0e8b9a9 --- /dev/null +++ b/assets/icons/common/ic_cart1.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + diff --git a/assets/icons/common/ic_discover.svg b/assets/icons/common/ic_discover.svg new file mode 100644 index 0000000..8aef969 --- /dev/null +++ b/assets/icons/common/ic_discover.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/icons/common/ic_home.svg b/assets/icons/common/ic_home.svg new file mode 100644 index 0000000..e46c464 --- /dev/null +++ b/assets/icons/common/ic_home.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/icons/common/ic_profile.svg b/assets/icons/common/ic_profile.svg new file mode 100644 index 0000000..9d94585 --- /dev/null +++ b/assets/icons/common/ic_profile.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/icons/common/ic_transactions.svg b/assets/icons/common/ic_transactions.svg new file mode 100644 index 0000000..8bf4447 --- /dev/null +++ b/assets/icons/common/ic_transactions.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/assets/icons/dark/ic_cart.svg b/assets/icons/dark/ic_cart.svg new file mode 100644 index 0000000..1f726f6 --- /dev/null +++ b/assets/icons/dark/ic_cart.svg @@ -0,0 +1,5 @@ + + + diff --git a/assets/icons/dark/ic_cart1.svg b/assets/icons/dark/ic_cart1.svg new file mode 100644 index 0000000..b97d527 --- /dev/null +++ b/assets/icons/dark/ic_cart1.svg @@ -0,0 +1,16 @@ + + + + + + diff --git a/assets/icons/dark/ic_discover.svg b/assets/icons/dark/ic_discover.svg new file mode 100644 index 0000000..3806fbd --- /dev/null +++ b/assets/icons/dark/ic_discover.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/icons/dark/ic_home.svg b/assets/icons/dark/ic_home.svg new file mode 100644 index 0000000..cc59a9a --- /dev/null +++ b/assets/icons/dark/ic_home.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/icons/dark/ic_profile.svg b/assets/icons/dark/ic_profile.svg new file mode 100644 index 0000000..79841fe --- /dev/null +++ b/assets/icons/dark/ic_profile.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/icons/dark/ic_transactions.svg b/assets/icons/dark/ic_transactions.svg new file mode 100644 index 0000000..96b57f1 --- /dev/null +++ b/assets/icons/dark/ic_transactions.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/icons/light/ic_cart.svg b/assets/icons/light/ic_cart.svg new file mode 100644 index 0000000..ec67f62 --- /dev/null +++ b/assets/icons/light/ic_cart.svg @@ -0,0 +1,5 @@ + + + diff --git a/assets/icons/light/ic_cart1.svg b/assets/icons/light/ic_cart1.svg new file mode 100644 index 0000000..02f99f6 --- /dev/null +++ b/assets/icons/light/ic_cart1.svg @@ -0,0 +1,16 @@ + + + + + + diff --git a/assets/icons/light/ic_discover.svg b/assets/icons/light/ic_discover.svg new file mode 100644 index 0000000..e6c5b53 --- /dev/null +++ b/assets/icons/light/ic_discover.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/icons/light/ic_home.svg b/assets/icons/light/ic_home.svg new file mode 100644 index 0000000..77fcde3 --- /dev/null +++ b/assets/icons/light/ic_home.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/icons/light/ic_profile.svg b/assets/icons/light/ic_profile.svg new file mode 100644 index 0000000..eb97fc0 --- /dev/null +++ b/assets/icons/light/ic_profile.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/icons/light/ic_transactions.svg b/assets/icons/light/ic_transactions.svg new file mode 100644 index 0000000..2883600 --- /dev/null +++ b/assets/icons/light/ic_transactions.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/translations/app_en.arb b/assets/translations/app_en.arb index a61ba64..71dddc9 100644 --- a/assets/translations/app_en.arb +++ b/assets/translations/app_en.arb @@ -30,6 +30,11 @@ "google": "Google", "facebook": "Facebook", "dont_have_account": "Don’t have an account?", - "register": "Register" + "register": "Register", + "home": "Home", + "discover": "Discover", + "cart": "Cart", + "transactions": "Transactions", + "profile": "Profile" } \ No newline at end of file diff --git a/assets/translations/app_ru.arb b/assets/translations/app_ru.arb index db87340..5ae464e 100644 --- a/assets/translations/app_ru.arb +++ b/assets/translations/app_ru.arb @@ -30,6 +30,11 @@ "google": "Google", "facebook": "Facebook", "dont_have_account": "У вас нет аккаунта?", - "register": "Зарегистрироваться" + "register": "Зарегистрироваться", + "home": "Главная", + "discover": "Обзор", + "cart": "Корзина", + "transactions": "Транзакции", + "profile": "Профиль" } \ No newline at end of file diff --git a/assets/translations/app_uz.arb b/assets/translations/app_uz.arb index 3f03d6e..5fd8f8c 100644 --- a/assets/translations/app_uz.arb +++ b/assets/translations/app_uz.arb @@ -30,6 +30,11 @@ "google": "Google", "facebook": "Facebook", "dont_have_account": "Akkauntingiz yo‘qmi?", - "register": "Ro‘yxatdan o‘tish" + "register": "Ro‘yxatdan o‘tish", + "home": "Bosh sahifa", + "discover": "Kashf etish", + "cart": "Savat", + "transactions": "Tranzaksiyalar", + "profile": "Profil" } \ No newline at end of file diff --git a/lib/core/di/injection_container.config.dart b/lib/core/di/injection_container.config.dart index 8087c7b..1c22a91 100644 --- a/lib/core/di/injection_container.config.dart +++ b/lib/core/di/injection_container.config.dart @@ -13,6 +13,31 @@ import 'package:dio/dio.dart' as _i361; import 'package:get_it/get_it.dart' as _i174; import 'package:injectable/injectable.dart' as _i526; +import '../../feature/auth/data/datasource/auth_datasource.dart' as _i246; +import '../../feature/auth/data/repository/auth_repository_impl.dart' as _i648; +import '../../feature/auth/domain/repository/auth_repository.dart' as _i884; +import '../../feature/auth/domain/usecases/login_usecase.dart' as _i241; +import '../../feature/auth/domain/usecases/register_usecase.dart' as _i607; +import '../../feature/auth/domain/usecases/reset_password_usecase.dart' + as _i694; +import '../../feature/auth/domain/usecases/verify_otp_code_login_usecase.dart' + as _i318; +import '../../feature/auth/domain/usecases/verify_otp_code_register_usecase.dart' + as _i406; +import '../../feature/auth/domain/usecases/verify_phone_login_usecase.dart' + as _i801; +import '../../feature/auth/domain/usecases/verify_phone_register_usecase.dart' + as _i664; +import '../../feature/auth/presentation/blocs/login_bloc/login_bloc.dart' + as _i1065; +import '../../feature/auth/presentation/blocs/register_bloc/register_bloc.dart' + as _i1050; +import '../../feature/auth/presentation/blocs/reset_password_bloc/reset_password_bloc.dart' + as _i97; +import '../../feature/auth/presentation/blocs/verify_otp_bloc/verify_otp_bloc.dart' + as _i323; +import '../../feature/auth/presentation/blocs/verify_phone_bloc/verify_phone_bloc.dart' + as _i224; import '../../feature/common/presentation/blocs/language_bloc/language_bloc.dart' as _i942; import '../../feature/main/presentation/blocs/main_bloc/main_bloc.dart' @@ -47,6 +72,63 @@ extension GetItInjectableX on _i174.GetIt { gh.singleton<_i354.RequestHandlerService>( () => _i354.RequestHandlerService(gh<_i361.Dio>()), ); + gh.lazySingleton<_i246.AuthDatasource>( + () => _i246.AuthDatasourceImpl(gh<_i354.RequestHandlerService>()), + ); + gh.lazySingleton<_i884.AuthRepository>( + () => _i648.AuthRepositoryImpl( + gh<_i354.RequestHandlerService>(), + gh<_i246.AuthDatasource>(), + ), + ); + gh.factory<_i607.RegisterUseCase>( + () => _i607.RegisterUseCase(gh<_i884.AuthRepository>()), + ); + gh.factory<_i241.LoginUseCase>( + () => _i241.LoginUseCase(gh<_i884.AuthRepository>()), + ); + gh.factory<_i694.ResetPasswordUseCase>( + () => _i694.ResetPasswordUseCase(gh<_i884.AuthRepository>()), + ); + gh.factory<_i318.VerifyOtpCodeForgotPasswordUseCase>( + () => + _i318.VerifyOtpCodeForgotPasswordUseCase(gh<_i884.AuthRepository>()), + ); + gh.factory<_i801.VerifyPhoneNumberLoginUseCase>( + () => _i801.VerifyPhoneNumberLoginUseCase(gh<_i884.AuthRepository>()), + ); + gh.factory<_i664.VerifyPhoneRegisterUseCase>( + () => _i664.VerifyPhoneRegisterUseCase(gh<_i884.AuthRepository>()), + ); + gh.factory<_i406.VerifyOtpCodeRegisterUseCase>( + () => _i406.VerifyOtpCodeRegisterUseCase(gh<_i884.AuthRepository>()), + ); + gh.factory<_i323.VerifyOtpBloc>( + () => _i323.VerifyOtpBloc( + gh<_i406.VerifyOtpCodeRegisterUseCase>(), + gh<_i318.VerifyOtpCodeForgotPasswordUseCase>(), + gh<_i664.VerifyPhoneRegisterUseCase>(), + gh<_i801.VerifyPhoneNumberLoginUseCase>(), + ), + ); + gh.factory<_i224.VerifyPhoneBloc>( + () => _i224.VerifyPhoneBloc( + gh<_i801.VerifyPhoneNumberLoginUseCase>(), + gh<_i664.VerifyPhoneRegisterUseCase>(), + ), + ); + gh.factory<_i1050.RegisterBloc>( + () => _i1050.RegisterBloc(gh<_i607.RegisterUseCase>()), + ); + gh.factory<_i97.ResetPasswordBloc>( + () => _i97.ResetPasswordBloc(gh<_i694.ResetPasswordUseCase>()), + ); + gh.factory<_i1065.LoginBloc>( + () => _i1065.LoginBloc( + gh<_i241.LoginUseCase>(), + gh<_i321.StorageService>(), + ), + ); return this; } } diff --git a/lib/core/l10n/app_localizations.dart b/lib/core/l10n/app_localizations.dart index c8a8822..3c2dc92 100644 --- a/lib/core/l10n/app_localizations.dart +++ b/lib/core/l10n/app_localizations.dart @@ -249,6 +249,36 @@ abstract class AppLocalizations { /// In en, this message translates to: /// **'Register'** String get register; + + /// No description provided for @home. + /// + /// In en, this message translates to: + /// **'Home'** + String get home; + + /// No description provided for @discover. + /// + /// In en, this message translates to: + /// **'Discover'** + String get discover; + + /// No description provided for @cart. + /// + /// In en, this message translates to: + /// **'Cart'** + String get cart; + + /// No description provided for @transactions. + /// + /// In en, this message translates to: + /// **'Transactions'** + String get transactions; + + /// No description provided for @profile. + /// + /// In en, this message translates to: + /// **'Profile'** + String get profile; } class _AppLocalizationsDelegate diff --git a/lib/core/l10n/app_localizations_en.dart b/lib/core/l10n/app_localizations_en.dart index 9ec64b8..6463562 100644 --- a/lib/core/l10n/app_localizations_en.dart +++ b/lib/core/l10n/app_localizations_en.dart @@ -90,4 +90,19 @@ class AppLocalizationsEn extends AppLocalizations { @override String get register => 'Register'; + + @override + String get home => 'Home'; + + @override + String get discover => 'Discover'; + + @override + String get cart => 'Cart'; + + @override + String get transactions => 'Transactions'; + + @override + String get profile => 'Profile'; } diff --git a/lib/core/l10n/app_localizations_ru.dart b/lib/core/l10n/app_localizations_ru.dart index 3e60d40..a39cfd0 100644 --- a/lib/core/l10n/app_localizations_ru.dart +++ b/lib/core/l10n/app_localizations_ru.dart @@ -88,4 +88,19 @@ class AppLocalizationsRu extends AppLocalizations { @override String get register => 'Зарегистрироваться'; + + @override + String get home => 'Главная'; + + @override + String get discover => 'Обзор'; + + @override + String get cart => 'Корзина'; + + @override + String get transactions => 'Транзакции'; + + @override + String get profile => 'Профиль'; } diff --git a/lib/core/l10n/app_localizations_uz.dart b/lib/core/l10n/app_localizations_uz.dart index 8cbfd9b..0b88e4c 100644 --- a/lib/core/l10n/app_localizations_uz.dart +++ b/lib/core/l10n/app_localizations_uz.dart @@ -88,4 +88,19 @@ class AppLocalizationsUz extends AppLocalizations { @override String get register => 'Ro‘yxatdan o‘tish'; + + @override + String get home => 'Bosh sahifa'; + + @override + String get discover => 'Kashf etish'; + + @override + String get cart => 'Savat'; + + @override + String get transactions => 'Tranzaksiyalar'; + + @override + String get profile => 'Profil'; } diff --git a/lib/core/router/app_routes.dart b/lib/core/router/app_routes.dart index a73006f..cdc25d8 100644 --- a/lib/core/router/app_routes.dart +++ b/lib/core/router/app_routes.dart @@ -1,5 +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/auth/presentation/pages/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'; @@ -26,6 +26,10 @@ class AppRoutes { path: Routes.login, pageBuilder: (context, state) => CupertinoPage(child: LoginPage()), ), + GoRoute( + path: Routes.main, + pageBuilder: (context, state) => CupertinoPage(child: MainPage()), + ), ], ); } diff --git a/lib/core/theme/app_colors.dart b/lib/core/theme/app_colors.dart index 3aa4a5b..a0282e7 100644 --- a/lib/core/theme/app_colors.dart +++ b/lib/core/theme/app_colors.dart @@ -54,5 +54,7 @@ abstract class AppColors { static const Color cE2E4EA = Color(0xFFE2E4EA); static const Color cA7AEC1 = Color(0xFFA7AEC1); static const Color c151B33 = Color(0xFF151B33); + static const Color cE5E7EB = Color(0xFFE5E7EB); + } diff --git a/lib/core/theme/app_icons.dart b/lib/core/theme/app_icons.dart index 241b93a..4ec9ed3 100644 --- a/lib/core/theme/app_icons.dart +++ b/lib/core/theme/app_icons.dart @@ -7,17 +7,34 @@ abstract class AppIcons { 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"; - + static const String icHome = "$baseUrl/ic_home.svg"; + static const String icDiscover = "$baseUrl/ic_discover.svg"; + static const String icCart = "$baseUrl/ic_cart.svg"; + static const String icCart1 = "$baseUrl/ic_cart1.svg"; + static const String icTransactions = "$baseUrl/ic_transactions.svg"; + static const String icProfile = "$baseUrl/ic_profile.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"; + static const String icHome = "$baseUrl/ic_home.svg"; + static const String icDiscover = "$baseUrl/ic_discover.svg"; + static const String icCart = "$baseUrl/ic_cart.svg"; + static const String icCart1 = "$baseUrl/ic_cart1.svg"; + static const String icTransactions = "$baseUrl/ic_transactions.svg"; + static const String icProfile = "$baseUrl/ic_profile.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"; + static const String icHome = "$baseUrl/ic_home.svg"; + static const String icDiscover = "$baseUrl/ic_discover.svg"; + static const String icCart = "$baseUrl/ic_cart.svg"; + static const String icCart1 = "$baseUrl/ic_cart1.svg"; + static const String icTransactions = "$baseUrl/ic_transactions.svg"; + static const String icProfile = "$baseUrl/ic_profile.svg"; } diff --git a/lib/core/theme/app_theme.dart b/lib/core/theme/app_theme.dart index 7483063..5e6082f 100644 --- a/lib/core/theme/app_theme.dart +++ b/lib/core/theme/app_theme.dart @@ -46,17 +46,17 @@ abstract class AppTheme { ), bottomNavigationBarTheme: BottomNavigationBarThemeData( elevation: 0, - showSelectedLabels: true, - showUnselectedLabels: true, + showSelectedLabels: false, + showUnselectedLabels: false, backgroundColor: AppColors.cFFFFFF, type: BottomNavigationBarType.fixed, - unselectedItemColor: AppColors.cB5B5B5, - selectedItemColor: AppColors.c000000, - selectedLabelStyle: AppTextStyles.size10Regular.copyWith( - color: Colors.red, + unselectedItemColor: AppColors.cA9A9A9, + selectedItemColor: AppColors.cFF6F00, + selectedLabelStyle: AppTextStyles.size12Medium.copyWith( + color: AppColors.cFF6F00, ), unselectedLabelStyle: AppTextStyles.size10Regular.copyWith( - color: AppColors.c000000, + color: AppColors.cA9A9A9, ), // unselectedLabelStyle: AppTextStyles.size14Medium.copyWith( // color: AppColors.c888888, @@ -138,17 +138,17 @@ abstract class AppTheme { ), bottomNavigationBarTheme: BottomNavigationBarThemeData( elevation: 0, - showSelectedLabels: true, - showUnselectedLabels: true, - backgroundColor: AppColors.cFFFFFF, + showSelectedLabels: false, + showUnselectedLabels: false, + backgroundColor: AppColors.c131720, type: BottomNavigationBarType.fixed, - unselectedItemColor: AppColors.cB5B5B5, - selectedItemColor: AppColors.c000000, - selectedLabelStyle: AppTextStyles.size10Regular.copyWith( - color: Colors.red, + unselectedItemColor: AppColors.c626262, + selectedItemColor: AppColors.cFF6F00, + selectedLabelStyle: AppTextStyles.size12Medium.copyWith( + color: AppColors.cFF6F00, ), - unselectedLabelStyle: AppTextStyles.size10Regular.copyWith( - color: AppColors.c000000, + unselectedLabelStyle: AppTextStyles.size12Medium.copyWith( + color: AppColors.c626262, ), // unselectedLabelStyle: AppTextStyles.size14Medium.copyWith( // color: AppColors.c888888, diff --git a/lib/core/theme/app_theme_colors.dart b/lib/core/theme/app_theme_colors.dart index 11d4826..ac86d80 100644 --- a/lib/core/theme/app_theme_colors.dart +++ b/lib/core/theme/app_theme_colors.dart @@ -8,6 +8,10 @@ class AppThemeColors extends ThemeExtension { final Color buttonInactiveColor; final Color borderColor; final Color inActiveColor; + final Color inActiveColor1; + final Color inActiveColor2; + + AppThemeColors({ required this.onBoardingColor, @@ -16,6 +20,9 @@ class AppThemeColors extends ThemeExtension { required this.buttonInactiveColor, required this.borderColor, required this.inActiveColor, + required this.inActiveColor1, + required this.inActiveColor2, + }); static AppThemeColors light = AppThemeColors( @@ -25,6 +32,8 @@ class AppThemeColors extends ThemeExtension { iconColor: AppColors.cFFFFFF, borderColor: AppColors.cE2E4EA, inActiveColor: AppColors.cE2E4EA, + inActiveColor1: AppColors.cA9A9A9, + inActiveColor2: AppColors.cE5E7EB ); static AppThemeColors dark = AppThemeColors( @@ -34,6 +43,8 @@ class AppThemeColors extends ThemeExtension { iconColor: AppColors.c131720, borderColor: AppColors.c292F3D, inActiveColor: AppColors.c292F3D, + inActiveColor1: AppColors.c626262, + inActiveColor2: AppColors.c292F3D ); @override @@ -44,6 +55,9 @@ class AppThemeColors extends ThemeExtension { Color? buttonInactiveColor, Color? borderColor, Color? inActiveColor, + Color? inActiveColor1, + Color? inActiveColor2, + }) { return AppThemeColors( onBoardingColor: onBoardingColor ?? this.onBoardingColor, @@ -52,6 +66,8 @@ class AppThemeColors extends ThemeExtension { buttonInactiveColor: buttonInactiveColor ?? this.buttonInactiveColor, borderColor: borderColor ?? this.borderColor, inActiveColor: inActiveColor ?? this.inActiveColor, + inActiveColor1: inActiveColor1 ?? this.inActiveColor1, + inActiveColor2: inActiveColor2??this.inActiveColor2 ); } diff --git a/lib/core/theme/theme_icons.dart b/lib/core/theme/theme_icons.dart index 6f4737e..f18cb39 100644 --- a/lib/core/theme/theme_icons.dart +++ b/lib/core/theme/theme_icons.dart @@ -4,27 +4,66 @@ import 'package:food_delivery_client/core/core.dart'; class AppThemeIcons extends ThemeExtension { final String icSplash; final String icArrowLeft; + final String icHome; + final String icDiscover; + final String icCart; + final String icCart1; + final String icTransactions; + final String icProfile; - AppThemeIcons({required this.icSplash, required this.icArrowLeft}); + AppThemeIcons({ + required this.icSplash, + required this.icArrowLeft, + required this.icHome, + required this.icDiscover, + required this.icCart, + required this.icTransactions, + required this.icProfile, + required this.icCart1, + }); static AppThemeIcons light = AppThemeIcons( icSplash: AppLightSvgs.icSplash, icArrowLeft: AppLightSvgs.icArrowLeft, + icHome: AppLightSvgs.icHome, + icDiscover: AppLightSvgs.icDiscover, + icCart: AppLightSvgs.icCart, + icTransactions: AppLightSvgs.icTransactions, + icProfile: AppLightSvgs.icProfile, + icCart1: AppLightSvgs.icCart1, ); static AppThemeIcons dark = AppThemeIcons( icSplash: AppDarkSvgs.icSplash, icArrowLeft: AppDarkSvgs.icArrowLeft, + icHome: AppDarkSvgs.icHome, + icDiscover: AppDarkSvgs.icDiscover, + icCart: AppDarkSvgs.icCart, + icTransactions: AppDarkSvgs.icTransactions, + icProfile: AppDarkSvgs.icProfile, + icCart1: AppDarkSvgs.icCart1, ); @override ThemeExtension copyWith({ String? icSplash, String? icArrowLeft, + String? icHome, + String? icDiscover, + String? icCart, + String? icCart1, + String? icTransactions, + String? icProfile, }) { return AppThemeIcons( icSplash: icSplash ?? this.icSplash, icArrowLeft: icArrowLeft ?? this.icArrowLeft, + icHome: icHome ?? this.icHome, + icDiscover: icDiscover ?? this.icDiscover, + icCart: icCart ?? this.icCart, + icTransactions: icTransactions ?? this.icTransactions, + icProfile: icProfile ?? this.icProfile, + icCart1: icCart ?? this.icCart1, ); } diff --git a/lib/core/utils/app_utils.dart b/lib/core/utils/app_utils.dart index 75391aa..816e97c 100644 --- a/lib/core/utils/app_utils.dart +++ b/lib/core/utils/app_utils.dart @@ -2,8 +2,8 @@ import '../../food_delivery_client.dart'; abstract class AppUtils { static const Gradient kGradient = LinearGradient( - begin: AlignmentGeometry.bottomCenter, - end: AlignmentGeometry.topCenter, + end: AlignmentGeometry.bottomCenter, + begin: AlignmentGeometry.topCenter, colors: [AppColors.cFF6F00, AppColors.cFFAB40], ); diff --git a/lib/feature/auth/data/datasource/auth_datasource.dart b/lib/feature/auth/data/datasource/auth_datasource.dart new file mode 100644 index 0000000..d75b105 --- /dev/null +++ b/lib/feature/auth/data/datasource/auth_datasource.dart @@ -0,0 +1,138 @@ +import 'package:food_delivery_client/core/services/request_handler_service.dart'; +import 'package:food_delivery_client/feature/auth/data/models/response/login_response.dart'; +import 'package:food_delivery_client/feature/auth/domain/usecases/register_usecase.dart'; +import 'package:food_delivery_client/feature/auth/domain/usecases/reset_password_usecase.dart'; +import 'package:food_delivery_client/feature/auth/domain/usecases/verify_otp_code_login_usecase.dart'; +import 'package:food_delivery_client/feature/auth/domain/usecases/verify_phone_login_usecase.dart'; +import 'package:food_delivery_client/food_delivery_client.dart'; + +abstract class AuthDatasource { + Future login({ + required String phoneNumber, + required String password, + }); + + Future verifyPhoneResetPassword({ + required VerifyPhoneNumberParams params, + }); + + Future verifyOtpCodeResetPassword({ + required VerifyOtpCodeParams params, + }); + + Future resetPassword({required ResetPasswordParams params}); + + Future verifyPhoneRegister({ + required VerifyPhoneNumberParams params, + }); + + Future verifyOtpCodeRegister({ + required VerifyOtpCodeParams params, + }); + + Future register({required RegisterParams params}); +} + +@LazySingleton(as: AuthDatasource) +class AuthDatasourceImpl implements AuthDatasource { + final RequestHandlerService _requestHandlerService; + + AuthDatasourceImpl(this._requestHandlerService); + + @override + Future login({ + required String phoneNumber, + required String password, + }) async { + return _requestHandlerService.handleRequest( + path: ApiConst.login, + method: RequestMethodEnum.post, + data: {"password": password, "phoneNumber": phoneNumber}, + fromJson: (response) async => LoginResponseModel.fromJson(response.data), + ); + } + + @override + Future register({required RegisterParams params}) async { + return _requestHandlerService.handleRequest( + path: ApiConst.register, + method: RequestMethodEnum.post, + + data: { + "firstName": params.firstName, + "lastName": params.lastName, + "password": params.password, + "phoneNumber": params.phoneNumber, + }, + + fromJson: (response) async { + return SuccessModel.fromJson(response.data); + }, + ); + } + + @override + Future resetPassword({ + required ResetPasswordParams params, + }) async { + return _requestHandlerService.handleRequest( + path: ApiConst.resetPassword, + method: RequestMethodEnum.post, + data: { + "newPassword": params.newPassword, + "phoneNumber": params.phoneNumber, + }, + + fromJson: (response) async => SuccessModel.fromJson(response.data), + ); + } + + @override + Future verifyOtpCodeRegister({ + required VerifyOtpCodeParams params, + }) async { + return _requestHandlerService.handleRequest( + path: ApiConst.verifyCode, + method: RequestMethodEnum.post, + data: {"code": params.otpCode, "phoneNumber": params.phoneNumber}, + fromJson: (response) async => SuccessModel.fromJson(response.data), + ); + } + + @override + Future verifyOtpCodeResetPassword({ + required VerifyOtpCodeParams params, + }) async { + return _requestHandlerService.handleRequest( + path: ApiConst.forgotPassword, + method: RequestMethodEnum.post, + data: {"code": params.otpCode, "phoneNumber": params.phoneNumber}, + fromJson: (response) async => SuccessModel.fromJson(response.data), + ); + } + + @override + Future verifyPhoneRegister({ + required VerifyPhoneNumberParams params, + }) async { + return _requestHandlerService.handleRequest( + path: ApiConst.verifyPhone, + method: RequestMethodEnum.post, + + data: {"phoneNumber": params.phoneNumber}, + fromJson: (response) async => SuccessModel.fromJson(response.data), + ); + } + + @override + Future verifyPhoneResetPassword({ + required VerifyPhoneNumberParams params, + }) async { + return _requestHandlerService.handleRequest( + path: ApiConst.sendCode, + method: RequestMethodEnum.post, + data: {"phoneNumber": params.phoneNumber}, + fromJson: (response) async => SuccessModel.fromJson(response.data), + ); + } +} diff --git a/lib/feature/auth/data/models/response/login_response.dart b/lib/feature/auth/data/models/response/login_response.dart new file mode 100644 index 0000000..a68951c --- /dev/null +++ b/lib/feature/auth/data/models/response/login_response.dart @@ -0,0 +1,26 @@ +import 'package:equatable/equatable.dart'; + +class LoginResponseModel extends Equatable { + final String token; + + const LoginResponseModel({required this.token}); + + factory LoginResponseModel.fromJson(Map json) { + return LoginResponseModel( + token: json['token'] as String, + ); + } + + Map toJson() => { + 'token': token, + }; + + LoginResponseModel copyWith({String? token}) { + return LoginResponseModel( + token: token ?? this.token, + ); + } + + @override + List get props => [token]; +} diff --git a/lib/feature/auth/data/repository/auth_repository_impl.dart b/lib/feature/auth/data/repository/auth_repository_impl.dart new file mode 100644 index 0000000..8d3f1f9 --- /dev/null +++ b/lib/feature/auth/data/repository/auth_repository_impl.dart @@ -0,0 +1,90 @@ +import 'package:dartz/dartz.dart'; +import 'package:food_delivery_client/core/services/request_handler_service.dart'; +import 'package:food_delivery_client/feature/auth/data/datasource/auth_datasource.dart'; +import 'package:food_delivery_client/feature/auth/data/models/response/login_response.dart'; +import 'package:food_delivery_client/food_delivery_client.dart'; + +import '../../domain/repository/auth_repository.dart'; +import '../../domain/usecases/register_usecase.dart'; +import '../../domain/usecases/reset_password_usecase.dart'; +import '../../domain/usecases/verify_otp_code_login_usecase.dart'; +import '../../domain/usecases/verify_phone_login_usecase.dart'; + + +@LazySingleton(as: AuthRepository) +class AuthRepositoryImpl implements AuthRepository { + final RequestHandlerService _requestHandlerService; + final AuthDatasource _authDatasource; + + AuthRepositoryImpl(this._requestHandlerService, this._authDatasource); + + @override + Future> login({ + required String phoneNumber, + required String password, + }) async { + return _requestHandlerService.handleRequestInRepository( + onRequest: () async { + return _authDatasource.login( + phoneNumber: phoneNumber, + password: password, + ); + }, + ); + } + + @override + Future> register({ + required RegisterParams params, + }) async { + return _requestHandlerService.handleRequestInRepository( + onRequest: () async => _authDatasource.register(params: params), + ); + } + + @override + Future> resetPassword({ + required ResetPasswordParams params, + }) async { + return _requestHandlerService.handleRequestInRepository( + onRequest: () => _authDatasource.resetPassword(params: params), + ); + } + + @override + Future> verifyOtpCodeRegister({ + required VerifyOtpCodeParams params, + }) async { + return _requestHandlerService.handleRequestInRepository( + onRequest: () => _authDatasource.verifyOtpCodeRegister(params: params), + ); + } + + @override + Future> verifyOtpCodeResetPassword({ + required VerifyOtpCodeParams params, + }) async { + return _requestHandlerService.handleRequestInRepository( + onRequest: () => + _authDatasource.verifyOtpCodeResetPassword(params: params), + ); + } + + @override + Future> verifyPhoneRegister({ + required VerifyPhoneNumberParams params, + }) async { + return _requestHandlerService.handleRequestInRepository( + onRequest: () => _authDatasource.verifyPhoneRegister(params: params), + ); + } + + @override + Future> verifyPhoneResetPassword({ + required VerifyPhoneNumberParams params, + }) async { + return _requestHandlerService.handleRequestInRepository( + onRequest: () => _authDatasource.verifyPhoneResetPassword(params: params), + ); + } +} \ No newline at end of file diff --git a/lib/feature/auth/domain/repository/auth_repository.dart b/lib/feature/auth/domain/repository/auth_repository.dart new file mode 100644 index 0000000..02e2903 --- /dev/null +++ b/lib/feature/auth/domain/repository/auth_repository.dart @@ -0,0 +1,43 @@ +import 'package:dartz/dartz.dart'; +import 'package:food_delivery_client/core/services/request_handler_service.dart'; +import 'package:food_delivery_client/feature/auth/data/datasource/auth_datasource.dart'; +import 'package:food_delivery_client/feature/auth/data/models/response/login_response.dart'; +import 'package:food_delivery_client/food_delivery_client.dart'; + +import '../usecases/register_usecase.dart'; +import '../usecases/reset_password_usecase.dart'; +import '../usecases/verify_otp_code_login_usecase.dart'; +import '../usecases/verify_phone_login_usecase.dart'; + +abstract class AuthRepository { + Future> login({ + required String phoneNumber, + required String password, + }); + + Future> verifyPhoneResetPassword({ + required VerifyPhoneNumberParams params, + }); + + Future> verifyOtpCodeResetPassword({ + required VerifyOtpCodeParams params, + }); + + Future> resetPassword({ + required ResetPasswordParams params, + }); + + Future> verifyPhoneRegister({ + required VerifyPhoneNumberParams params, + }); + + Future> verifyOtpCodeRegister({ + required VerifyOtpCodeParams params, + }); + + Future> register({ + required RegisterParams params, + }); +} + + diff --git a/lib/feature/auth/domain/usecases/login_usecase.dart b/lib/feature/auth/domain/usecases/login_usecase.dart new file mode 100644 index 0000000..cd9b0c9 --- /dev/null +++ b/lib/feature/auth/domain/usecases/login_usecase.dart @@ -0,0 +1,26 @@ +import 'package:dartz/dartz.dart'; +import 'package:food_delivery_client/core/usecase/usecase.dart'; +import 'package:food_delivery_client/feature/auth/data/models/response/login_response.dart'; +import 'package:food_delivery_client/feature/auth/domain/repository/auth_repository.dart'; +import 'package:food_delivery_client/food_delivery_client.dart'; +@injectable +class LoginUseCase implements UseCase { + final AuthRepository _authRepository; + + LoginUseCase(this._authRepository); + + @override + Future> call(LoginParams params) async { + return _authRepository.login( + phoneNumber: params.phoneNumber, + password: params.password, + ); + } +} + +class LoginParams { + final String phoneNumber; + final String password; + + LoginParams({required this.phoneNumber, required this.password}); +} diff --git a/lib/feature/auth/domain/usecases/register_usecase.dart b/lib/feature/auth/domain/usecases/register_usecase.dart new file mode 100644 index 0000000..aaabb3d --- /dev/null +++ b/lib/feature/auth/domain/usecases/register_usecase.dart @@ -0,0 +1,32 @@ +import 'package:dartz/dartz.dart'; +import 'package:food_delivery_client/core/exceptions/failure.dart'; +import 'package:food_delivery_client/feature/auth/domain/repository/auth_repository.dart'; +import 'package:food_delivery_client/feature/common/common.dart'; +import 'package:food_delivery_client/food_delivery_client.dart'; + +import '../../../../core/usecase/usecase.dart'; +@injectable +class RegisterUseCase implements UseCase { + final AuthRepository _authRepository; + + RegisterUseCase(this._authRepository); + + @override + Future> call(RegisterParams params) async { + return _authRepository.register(params: params); + } +} + +class RegisterParams { + final String firstName; + final String lastName; + final String phoneNumber; + final String password; + + RegisterParams({ + required this.firstName, + required this.lastName, + required this.phoneNumber, + required this.password, + }); +} diff --git a/lib/feature/auth/domain/usecases/reset_password_usecase.dart b/lib/feature/auth/domain/usecases/reset_password_usecase.dart new file mode 100644 index 0000000..3deacf7 --- /dev/null +++ b/lib/feature/auth/domain/usecases/reset_password_usecase.dart @@ -0,0 +1,26 @@ +import 'package:dartz/dartz.dart'; +import 'package:food_delivery_client/core/exceptions/failure.dart'; +import 'package:food_delivery_client/feature/auth/domain/repository/auth_repository.dart'; +import 'package:food_delivery_client/feature/common/common.dart'; +import 'package:food_delivery_client/food_delivery_client.dart'; + +import '../../../../core/usecase/usecase.dart'; +@injectable +class ResetPasswordUseCase + implements UseCase { + final AuthRepository _authRepository; + + ResetPasswordUseCase(this._authRepository); + + @override + Future> call(ResetPasswordParams params) async { + return _authRepository.resetPassword(params: params); + } +} + +class ResetPasswordParams { + final String newPassword; + final String phoneNumber; + + ResetPasswordParams({required this.newPassword, required this.phoneNumber}); +} diff --git a/lib/feature/auth/domain/usecases/verify_otp_code_login_usecase.dart b/lib/feature/auth/domain/usecases/verify_otp_code_login_usecase.dart new file mode 100644 index 0000000..6cb2544 --- /dev/null +++ b/lib/feature/auth/domain/usecases/verify_otp_code_login_usecase.dart @@ -0,0 +1,33 @@ +import 'package:dartz/dartz.dart'; + +import 'package:food_delivery_client/feature/auth/domain/repository/auth_repository.dart'; +import 'package:food_delivery_client/food_delivery_client.dart'; + +import '../../../../core/usecase/usecase.dart'; + +@injectable +class VerifyOtpCodeForgotPasswordUseCase + implements UseCase { + final AuthRepository _authRepository; + + VerifyOtpCodeForgotPasswordUseCase(this._authRepository); + + @override + Future> call(VerifyOtpCodeParams params) async { + return _authRepository.verifyOtpCodeResetPassword(params: params); + } +} + +class VerifyOtpCodeParams { + final dynamic otpCode; + final String phoneNumber; + + VerifyOtpCodeParams({required this.otpCode, required this.phoneNumber}); +} + +class OtpCodePageParams { + final String phoneNumber; + final bool isRegister; + + OtpCodePageParams({required this.phoneNumber, required this.isRegister}); +} diff --git a/lib/feature/auth/domain/usecases/verify_otp_code_register_usecase.dart b/lib/feature/auth/domain/usecases/verify_otp_code_register_usecase.dart new file mode 100644 index 0000000..5ee73b0 --- /dev/null +++ b/lib/feature/auth/domain/usecases/verify_otp_code_register_usecase.dart @@ -0,0 +1,19 @@ +import 'package:dartz/dartz.dart'; +import 'package:food_delivery_client/feature/auth/domain/repository/auth_repository.dart'; +import 'package:food_delivery_client/feature/auth/domain/usecases/verify_otp_code_login_usecase.dart'; +import 'package:food_delivery_client/food_delivery_client.dart'; + +import '../../../../core/usecase/usecase.dart'; + +@injectable +class VerifyOtpCodeRegisterUseCase + implements UseCase { + final AuthRepository _authRepository; + + VerifyOtpCodeRegisterUseCase(this._authRepository); + + @override + Future> call(VerifyOtpCodeParams params) async { + return _authRepository.verifyOtpCodeRegister(params: params); + } +} diff --git a/lib/feature/auth/domain/usecases/verify_phone_login_usecase.dart b/lib/feature/auth/domain/usecases/verify_phone_login_usecase.dart new file mode 100644 index 0000000..bdd0517 --- /dev/null +++ b/lib/feature/auth/domain/usecases/verify_phone_login_usecase.dart @@ -0,0 +1,27 @@ +import 'package:dartz/dartz.dart'; +import 'package:food_delivery_client/core/exceptions/failure.dart'; +import 'package:food_delivery_client/feature/auth/domain/repository/auth_repository.dart'; +import 'package:food_delivery_client/feature/common/common.dart'; +import 'package:food_delivery_client/food_delivery_client.dart'; + +import '../../../../core/usecase/usecase.dart'; +@injectable +class VerifyPhoneNumberLoginUseCase + implements UseCase { + final AuthRepository _authRepository; + + VerifyPhoneNumberLoginUseCase(this._authRepository); + + @override + Future> call( + VerifyPhoneNumberParams params, + ) async { + return _authRepository.verifyPhoneResetPassword(params: params); + } +} + +class VerifyPhoneNumberParams { + final String phoneNumber; + + VerifyPhoneNumberParams({required this.phoneNumber}); +} diff --git a/lib/feature/auth/domain/usecases/verify_phone_register_usecase.dart b/lib/feature/auth/domain/usecases/verify_phone_register_usecase.dart new file mode 100644 index 0000000..69b5880 --- /dev/null +++ b/lib/feature/auth/domain/usecases/verify_phone_register_usecase.dart @@ -0,0 +1,21 @@ +import 'package:dartz/dartz.dart'; +import 'package:food_delivery_client/feature/auth/domain/repository/auth_repository.dart'; +import 'package:food_delivery_client/feature/auth/domain/usecases/verify_phone_login_usecase.dart'; +import 'package:food_delivery_client/food_delivery_client.dart'; + +import '../../../../core/usecase/usecase.dart'; + +@injectable +class VerifyPhoneRegisterUseCase + implements UseCase { + final AuthRepository _authRepository; + + VerifyPhoneRegisterUseCase(this._authRepository); + + @override + Future> call( + VerifyPhoneNumberParams params, + ) async { + return _authRepository.verifyPhoneRegister(params: params); + } +} diff --git a/lib/feature/auth/presentation/blocs/login_bloc/login_bloc.dart b/lib/feature/auth/presentation/blocs/login_bloc/login_bloc.dart new file mode 100644 index 0000000..80ebcd2 --- /dev/null +++ b/lib/feature/auth/presentation/blocs/login_bloc/login_bloc.dart @@ -0,0 +1,41 @@ +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'; + +part 'login_state.dart'; + +part 'login_bloc.freezed.dart'; + +@injectable +class LoginBloc extends Bloc { + final LoginUseCase _loginUseCase; + final StorageService _storageService; + + LoginBloc(this._loginUseCase, this._storageService) + : super(const LoginState()) { + on<_Login>(_onLogin); + } + + Future _onLogin(_Login event, Emitter emit) async { + emit(state.copyWith(status: RequestStatus.loading)); + + final response = await _loginUseCase.call(event.params); + + response.fold( + (l) { + log("${l.errorMessage}"); + showErrorToast(l.errorMessage); + emit(state.copyWith(status: RequestStatus.error)); + }, + (r) { + 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)); + }, + ); + } +} diff --git a/lib/feature/auth/presentation/blocs/login_bloc/login_bloc.freezed.dart b/lib/feature/auth/presentation/blocs/login_bloc/login_bloc.freezed.dart new file mode 100644 index 0000000..1058e55 --- /dev/null +++ b/lib/feature/auth/presentation/blocs/login_bloc/login_bloc.freezed.dart @@ -0,0 +1,535 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND +// coverage:ignore-file +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'login_bloc.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; +/// @nodoc +mixin _$LoginEvent { + + + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is LoginEvent); +} + + +@override +int get hashCode => runtimeType.hashCode; + +@override +String toString() { + return 'LoginEvent()'; +} + + +} + +/// @nodoc +class $LoginEventCopyWith<$Res> { +$LoginEventCopyWith(LoginEvent _, $Res Function(LoginEvent) __); +} + + +/// Adds pattern-matching-related methods to [LoginEvent]. +extension LoginEventPatterns on LoginEvent { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap({TResult Function( _Checked value)? checked,TResult Function( _Login value)? login,required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _Checked() when checked != null: +return checked(_that);case _Login() when login != null: +return login(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map({required TResult Function( _Checked value) checked,required TResult Function( _Login value) login,}){ +final _that = this; +switch (_that) { +case _Checked(): +return checked(_that);case _Login(): +return login(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull({TResult? Function( _Checked value)? checked,TResult? Function( _Login value)? login,}){ +final _that = this; +switch (_that) { +case _Checked() when checked != null: +return checked(_that);case _Login() when login != null: +return login(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen({TResult Function()? checked,TResult Function( LoginParams params)? login,required TResult orElse(),}) {final _that = this; +switch (_that) { +case _Checked() when checked != null: +return checked();case _Login() when login != null: +return login(_that.params);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when({required TResult Function() checked,required TResult Function( LoginParams params) login,}) {final _that = this; +switch (_that) { +case _Checked(): +return checked();case _Login(): +return login(_that.params);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull({TResult? Function()? checked,TResult? Function( LoginParams params)? login,}) {final _that = this; +switch (_that) { +case _Checked() when checked != null: +return checked();case _Login() when login != null: +return login(_that.params);case _: + return null; + +} +} + +} + +/// @nodoc + + +class _Checked implements LoginEvent { + const _Checked(); + + + + + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _Checked); +} + + +@override +int get hashCode => runtimeType.hashCode; + +@override +String toString() { + return 'LoginEvent.checked()'; +} + + +} + + + + +/// @nodoc + + +class _Login implements LoginEvent { + const _Login(this.params); + + + final LoginParams params; + +/// Create a copy of LoginEvent +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$LoginCopyWith<_Login> get copyWith => __$LoginCopyWithImpl<_Login>(this, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _Login&&(identical(other.params, params) || other.params == params)); +} + + +@override +int get hashCode => Object.hash(runtimeType,params); + +@override +String toString() { + return 'LoginEvent.login(params: $params)'; +} + + +} + +/// @nodoc +abstract mixin class _$LoginCopyWith<$Res> implements $LoginEventCopyWith<$Res> { + factory _$LoginCopyWith(_Login value, $Res Function(_Login) _then) = __$LoginCopyWithImpl; +@useResult +$Res call({ + LoginParams params +}); + + + + +} +/// @nodoc +class __$LoginCopyWithImpl<$Res> + implements _$LoginCopyWith<$Res> { + __$LoginCopyWithImpl(this._self, this._then); + + final _Login _self; + final $Res Function(_Login) _then; + +/// Create a copy of LoginEvent +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') $Res call({Object? params = null,}) { + return _then(_Login( +null == params ? _self.params : params // ignore: cast_nullable_to_non_nullable +as LoginParams, + )); +} + + +} + +/// @nodoc +mixin _$LoginState { + + RequestStatus get status; +/// Create a copy of LoginState +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$LoginStateCopyWith get copyWith => _$LoginStateCopyWithImpl(this as LoginState, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is LoginState&&(identical(other.status, status) || other.status == status)); +} + + +@override +int get hashCode => Object.hash(runtimeType,status); + +@override +String toString() { + return 'LoginState(status: $status)'; +} + + +} + +/// @nodoc +abstract mixin class $LoginStateCopyWith<$Res> { + factory $LoginStateCopyWith(LoginState value, $Res Function(LoginState) _then) = _$LoginStateCopyWithImpl; +@useResult +$Res call({ + RequestStatus status +}); + + + + +} +/// @nodoc +class _$LoginStateCopyWithImpl<$Res> + implements $LoginStateCopyWith<$Res> { + _$LoginStateCopyWithImpl(this._self, this._then); + + final LoginState _self; + final $Res Function(LoginState) _then; + +/// Create a copy of LoginState +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? status = null,}) { + return _then(_self.copyWith( +status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable +as RequestStatus, + )); +} + +} + + +/// Adds pattern-matching-related methods to [LoginState]. +extension LoginStatePatterns on LoginState { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _LoginState value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _LoginState() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _LoginState value) $default,){ +final _that = this; +switch (_that) { +case _LoginState(): +return $default(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _LoginState value)? $default,){ +final _that = this; +switch (_that) { +case _LoginState() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( RequestStatus status)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _LoginState() when $default != null: +return $default(_that.status);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( RequestStatus status) $default,) {final _that = this; +switch (_that) { +case _LoginState(): +return $default(_that.status);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( RequestStatus status)? $default,) {final _that = this; +switch (_that) { +case _LoginState() when $default != null: +return $default(_that.status);case _: + return null; + +} +} + +} + +/// @nodoc + + +class _LoginState implements LoginState { + const _LoginState({this.status = RequestStatus.initial}); + + +@override@JsonKey() final RequestStatus status; + +/// Create a copy of LoginState +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$LoginStateCopyWith<_LoginState> get copyWith => __$LoginStateCopyWithImpl<_LoginState>(this, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _LoginState&&(identical(other.status, status) || other.status == status)); +} + + +@override +int get hashCode => Object.hash(runtimeType,status); + +@override +String toString() { + return 'LoginState(status: $status)'; +} + + +} + +/// @nodoc +abstract mixin class _$LoginStateCopyWith<$Res> implements $LoginStateCopyWith<$Res> { + factory _$LoginStateCopyWith(_LoginState value, $Res Function(_LoginState) _then) = __$LoginStateCopyWithImpl; +@override @useResult +$Res call({ + RequestStatus status +}); + + + + +} +/// @nodoc +class __$LoginStateCopyWithImpl<$Res> + implements _$LoginStateCopyWith<$Res> { + __$LoginStateCopyWithImpl(this._self, this._then); + + final _LoginState _self; + final $Res Function(_LoginState) _then; + +/// Create a copy of LoginState +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? status = null,}) { + return _then(_LoginState( +status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable +as RequestStatus, + )); +} + + +} + +// dart format on diff --git a/lib/feature/auth/presentation/blocs/login_bloc/login_event.dart b/lib/feature/auth/presentation/blocs/login_bloc/login_event.dart new file mode 100644 index 0000000..c8f3962 --- /dev/null +++ b/lib/feature/auth/presentation/blocs/login_bloc/login_event.dart @@ -0,0 +1,8 @@ +part of 'login_bloc.dart'; + +@freezed +class LoginEvent with _$LoginEvent { + const factory LoginEvent.checked() = _Checked; + + const factory LoginEvent.login(LoginParams params) = _Login; +} diff --git a/lib/feature/auth/presentation/blocs/login_bloc/login_state.dart b/lib/feature/auth/presentation/blocs/login_bloc/login_state.dart new file mode 100644 index 0000000..e13c125 --- /dev/null +++ b/lib/feature/auth/presentation/blocs/login_bloc/login_state.dart @@ -0,0 +1,8 @@ +part of 'login_bloc.dart'; + +@freezed +abstract class LoginState with _$LoginState { + const factory LoginState({ + @Default(RequestStatus.initial) RequestStatus status, + }) = _LoginState; +} diff --git a/lib/feature/auth/presentation/blocs/register_bloc/register_bloc.dart b/lib/feature/auth/presentation/blocs/register_bloc/register_bloc.dart new file mode 100644 index 0000000..b7e6f61 --- /dev/null +++ b/lib/feature/auth/presentation/blocs/register_bloc/register_bloc.dart @@ -0,0 +1,35 @@ +import 'package:food_delivery_client/feature/auth/domain/usecases/register_usecase.dart'; +import 'package:food_delivery_client/feature/common/presentation/widgets/w_toastification.dart'; +import 'package:food_delivery_client/food_delivery_client.dart'; + +part 'register_event.dart'; + +part 'register_state.dart'; + +part 'register_bloc.freezed.dart'; + +@injectable +class RegisterBloc extends Bloc { + final RegisterUseCase _registerUseCase; + + RegisterBloc(this._registerUseCase) : super(const RegisterState()) { + on<_Loaded>(_onLoaded); + } + + Future _onLoaded(_Loaded event, Emitter emit) async { + emit(state.copyWith(status: RequestStatus.loading)); + + final response = await _registerUseCase.call(event.params); + + response.fold( + (l) { + showErrorToast(l.errorMessage); + emit(state.copyWith(status: RequestStatus.error)); + }, + (r) { + showSuccessToast(r.message); + emit(state.copyWith(status: RequestStatus.loaded)); + }, + ); + } +} diff --git a/lib/feature/auth/presentation/blocs/register_bloc/register_bloc.freezed.dart b/lib/feature/auth/presentation/blocs/register_bloc/register_bloc.freezed.dart new file mode 100644 index 0000000..b45bbba --- /dev/null +++ b/lib/feature/auth/presentation/blocs/register_bloc/register_bloc.freezed.dart @@ -0,0 +1,535 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND +// coverage:ignore-file +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'register_bloc.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; +/// @nodoc +mixin _$RegisterEvent { + + + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is RegisterEvent); +} + + +@override +int get hashCode => runtimeType.hashCode; + +@override +String toString() { + return 'RegisterEvent()'; +} + + +} + +/// @nodoc +class $RegisterEventCopyWith<$Res> { +$RegisterEventCopyWith(RegisterEvent _, $Res Function(RegisterEvent) __); +} + + +/// Adds pattern-matching-related methods to [RegisterEvent]. +extension RegisterEventPatterns on RegisterEvent { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap({TResult Function( _Started value)? started,TResult Function( _Loaded value)? loaded,required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _Started() when started != null: +return started(_that);case _Loaded() when loaded != null: +return loaded(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map({required TResult Function( _Started value) started,required TResult Function( _Loaded value) loaded,}){ +final _that = this; +switch (_that) { +case _Started(): +return started(_that);case _Loaded(): +return loaded(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull({TResult? Function( _Started value)? started,TResult? Function( _Loaded value)? loaded,}){ +final _that = this; +switch (_that) { +case _Started() when started != null: +return started(_that);case _Loaded() when loaded != null: +return loaded(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen({TResult Function()? started,TResult Function( RegisterParams params)? loaded,required TResult orElse(),}) {final _that = this; +switch (_that) { +case _Started() when started != null: +return started();case _Loaded() when loaded != null: +return loaded(_that.params);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when({required TResult Function() started,required TResult Function( RegisterParams params) loaded,}) {final _that = this; +switch (_that) { +case _Started(): +return started();case _Loaded(): +return loaded(_that.params);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull({TResult? Function()? started,TResult? Function( RegisterParams params)? loaded,}) {final _that = this; +switch (_that) { +case _Started() when started != null: +return started();case _Loaded() when loaded != null: +return loaded(_that.params);case _: + return null; + +} +} + +} + +/// @nodoc + + +class _Started implements RegisterEvent { + const _Started(); + + + + + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _Started); +} + + +@override +int get hashCode => runtimeType.hashCode; + +@override +String toString() { + return 'RegisterEvent.started()'; +} + + +} + + + + +/// @nodoc + + +class _Loaded implements RegisterEvent { + const _Loaded(this.params); + + + final RegisterParams params; + +/// Create a copy of RegisterEvent +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$LoadedCopyWith<_Loaded> get copyWith => __$LoadedCopyWithImpl<_Loaded>(this, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _Loaded&&(identical(other.params, params) || other.params == params)); +} + + +@override +int get hashCode => Object.hash(runtimeType,params); + +@override +String toString() { + return 'RegisterEvent.loaded(params: $params)'; +} + + +} + +/// @nodoc +abstract mixin class _$LoadedCopyWith<$Res> implements $RegisterEventCopyWith<$Res> { + factory _$LoadedCopyWith(_Loaded value, $Res Function(_Loaded) _then) = __$LoadedCopyWithImpl; +@useResult +$Res call({ + RegisterParams params +}); + + + + +} +/// @nodoc +class __$LoadedCopyWithImpl<$Res> + implements _$LoadedCopyWith<$Res> { + __$LoadedCopyWithImpl(this._self, this._then); + + final _Loaded _self; + final $Res Function(_Loaded) _then; + +/// Create a copy of RegisterEvent +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') $Res call({Object? params = null,}) { + return _then(_Loaded( +null == params ? _self.params : params // ignore: cast_nullable_to_non_nullable +as RegisterParams, + )); +} + + +} + +/// @nodoc +mixin _$RegisterState { + + RequestStatus get status; +/// Create a copy of RegisterState +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$RegisterStateCopyWith get copyWith => _$RegisterStateCopyWithImpl(this as RegisterState, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is RegisterState&&(identical(other.status, status) || other.status == status)); +} + + +@override +int get hashCode => Object.hash(runtimeType,status); + +@override +String toString() { + return 'RegisterState(status: $status)'; +} + + +} + +/// @nodoc +abstract mixin class $RegisterStateCopyWith<$Res> { + factory $RegisterStateCopyWith(RegisterState value, $Res Function(RegisterState) _then) = _$RegisterStateCopyWithImpl; +@useResult +$Res call({ + RequestStatus status +}); + + + + +} +/// @nodoc +class _$RegisterStateCopyWithImpl<$Res> + implements $RegisterStateCopyWith<$Res> { + _$RegisterStateCopyWithImpl(this._self, this._then); + + final RegisterState _self; + final $Res Function(RegisterState) _then; + +/// Create a copy of RegisterState +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? status = null,}) { + return _then(_self.copyWith( +status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable +as RequestStatus, + )); +} + +} + + +/// Adds pattern-matching-related methods to [RegisterState]. +extension RegisterStatePatterns on RegisterState { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _RegisterState value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _RegisterState() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _RegisterState value) $default,){ +final _that = this; +switch (_that) { +case _RegisterState(): +return $default(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _RegisterState value)? $default,){ +final _that = this; +switch (_that) { +case _RegisterState() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( RequestStatus status)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _RegisterState() when $default != null: +return $default(_that.status);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( RequestStatus status) $default,) {final _that = this; +switch (_that) { +case _RegisterState(): +return $default(_that.status);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( RequestStatus status)? $default,) {final _that = this; +switch (_that) { +case _RegisterState() when $default != null: +return $default(_that.status);case _: + return null; + +} +} + +} + +/// @nodoc + + +class _RegisterState implements RegisterState { + const _RegisterState({this.status = RequestStatus.initial}); + + +@override@JsonKey() final RequestStatus status; + +/// Create a copy of RegisterState +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$RegisterStateCopyWith<_RegisterState> get copyWith => __$RegisterStateCopyWithImpl<_RegisterState>(this, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _RegisterState&&(identical(other.status, status) || other.status == status)); +} + + +@override +int get hashCode => Object.hash(runtimeType,status); + +@override +String toString() { + return 'RegisterState(status: $status)'; +} + + +} + +/// @nodoc +abstract mixin class _$RegisterStateCopyWith<$Res> implements $RegisterStateCopyWith<$Res> { + factory _$RegisterStateCopyWith(_RegisterState value, $Res Function(_RegisterState) _then) = __$RegisterStateCopyWithImpl; +@override @useResult +$Res call({ + RequestStatus status +}); + + + + +} +/// @nodoc +class __$RegisterStateCopyWithImpl<$Res> + implements _$RegisterStateCopyWith<$Res> { + __$RegisterStateCopyWithImpl(this._self, this._then); + + final _RegisterState _self; + final $Res Function(_RegisterState) _then; + +/// Create a copy of RegisterState +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? status = null,}) { + return _then(_RegisterState( +status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable +as RequestStatus, + )); +} + + +} + +// dart format on diff --git a/lib/feature/auth/presentation/blocs/register_bloc/register_event.dart b/lib/feature/auth/presentation/blocs/register_bloc/register_event.dart new file mode 100644 index 0000000..ec74eef --- /dev/null +++ b/lib/feature/auth/presentation/blocs/register_bloc/register_event.dart @@ -0,0 +1,8 @@ +part of 'register_bloc.dart'; + +@freezed +class RegisterEvent with _$RegisterEvent { + const factory RegisterEvent.started() = _Started; + const factory RegisterEvent.loaded(RegisterParams params) = _Loaded; + +} diff --git a/lib/feature/auth/presentation/blocs/register_bloc/register_state.dart b/lib/feature/auth/presentation/blocs/register_bloc/register_state.dart new file mode 100644 index 0000000..ff80d35 --- /dev/null +++ b/lib/feature/auth/presentation/blocs/register_bloc/register_state.dart @@ -0,0 +1,8 @@ +part of 'register_bloc.dart'; + +@freezed +abstract class RegisterState with _$RegisterState { + const factory RegisterState({ + @Default(RequestStatus.initial) RequestStatus status, + }) = _RegisterState; +} diff --git a/lib/feature/auth/presentation/blocs/reset_password_bloc/reset_password_bloc.dart b/lib/feature/auth/presentation/blocs/reset_password_bloc/reset_password_bloc.dart new file mode 100644 index 0000000..0c54bfc --- /dev/null +++ b/lib/feature/auth/presentation/blocs/reset_password_bloc/reset_password_bloc.dart @@ -0,0 +1,36 @@ +import 'package:food_delivery_client/feature/auth/domain/usecases/reset_password_usecase.dart'; +import 'package:food_delivery_client/feature/common/presentation/widgets/w_toastification.dart'; +import 'package:food_delivery_client/food_delivery_client.dart'; + +part 'reset_password_event.dart'; + +part 'reset_password_state.dart'; + +part 'reset_password_bloc.freezed.dart'; + +@injectable +class ResetPasswordBloc extends Bloc { + final ResetPasswordUseCase _passwordUseCase; + + ResetPasswordBloc(this._passwordUseCase) : super(const ResetPasswordState()) { + on<_Loaded>(_onLoaded); + } + + Future _onLoaded( + _Loaded event, + Emitter emit, + ) async { + emit(state.copyWith(status: RequestStatus.loading)); + final response = await _passwordUseCase.call(event.params); + response.fold( + (l) { + showErrorToast(l.errorMessage); + emit(state.copyWith(status: RequestStatus.error)); + }, + (r) { + showSuccessToast(r.message); + emit(state.copyWith(status: RequestStatus.loaded)); + }, + ); + } +} diff --git a/lib/feature/auth/presentation/blocs/reset_password_bloc/reset_password_bloc.freezed.dart b/lib/feature/auth/presentation/blocs/reset_password_bloc/reset_password_bloc.freezed.dart new file mode 100644 index 0000000..fb7109f --- /dev/null +++ b/lib/feature/auth/presentation/blocs/reset_password_bloc/reset_password_bloc.freezed.dart @@ -0,0 +1,535 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND +// coverage:ignore-file +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'reset_password_bloc.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; +/// @nodoc +mixin _$ResetPasswordEvent { + + + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is ResetPasswordEvent); +} + + +@override +int get hashCode => runtimeType.hashCode; + +@override +String toString() { + return 'ResetPasswordEvent()'; +} + + +} + +/// @nodoc +class $ResetPasswordEventCopyWith<$Res> { +$ResetPasswordEventCopyWith(ResetPasswordEvent _, $Res Function(ResetPasswordEvent) __); +} + + +/// Adds pattern-matching-related methods to [ResetPasswordEvent]. +extension ResetPasswordEventPatterns on ResetPasswordEvent { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap({TResult Function( _Started value)? started,TResult Function( _Loaded value)? loaded,required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _Started() when started != null: +return started(_that);case _Loaded() when loaded != null: +return loaded(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map({required TResult Function( _Started value) started,required TResult Function( _Loaded value) loaded,}){ +final _that = this; +switch (_that) { +case _Started(): +return started(_that);case _Loaded(): +return loaded(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull({TResult? Function( _Started value)? started,TResult? Function( _Loaded value)? loaded,}){ +final _that = this; +switch (_that) { +case _Started() when started != null: +return started(_that);case _Loaded() when loaded != null: +return loaded(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen({TResult Function()? started,TResult Function( ResetPasswordParams params)? loaded,required TResult orElse(),}) {final _that = this; +switch (_that) { +case _Started() when started != null: +return started();case _Loaded() when loaded != null: +return loaded(_that.params);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when({required TResult Function() started,required TResult Function( ResetPasswordParams params) loaded,}) {final _that = this; +switch (_that) { +case _Started(): +return started();case _Loaded(): +return loaded(_that.params);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull({TResult? Function()? started,TResult? Function( ResetPasswordParams params)? loaded,}) {final _that = this; +switch (_that) { +case _Started() when started != null: +return started();case _Loaded() when loaded != null: +return loaded(_that.params);case _: + return null; + +} +} + +} + +/// @nodoc + + +class _Started implements ResetPasswordEvent { + const _Started(); + + + + + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _Started); +} + + +@override +int get hashCode => runtimeType.hashCode; + +@override +String toString() { + return 'ResetPasswordEvent.started()'; +} + + +} + + + + +/// @nodoc + + +class _Loaded implements ResetPasswordEvent { + const _Loaded(this.params); + + + final ResetPasswordParams params; + +/// Create a copy of ResetPasswordEvent +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$LoadedCopyWith<_Loaded> get copyWith => __$LoadedCopyWithImpl<_Loaded>(this, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _Loaded&&(identical(other.params, params) || other.params == params)); +} + + +@override +int get hashCode => Object.hash(runtimeType,params); + +@override +String toString() { + return 'ResetPasswordEvent.loaded(params: $params)'; +} + + +} + +/// @nodoc +abstract mixin class _$LoadedCopyWith<$Res> implements $ResetPasswordEventCopyWith<$Res> { + factory _$LoadedCopyWith(_Loaded value, $Res Function(_Loaded) _then) = __$LoadedCopyWithImpl; +@useResult +$Res call({ + ResetPasswordParams params +}); + + + + +} +/// @nodoc +class __$LoadedCopyWithImpl<$Res> + implements _$LoadedCopyWith<$Res> { + __$LoadedCopyWithImpl(this._self, this._then); + + final _Loaded _self; + final $Res Function(_Loaded) _then; + +/// Create a copy of ResetPasswordEvent +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') $Res call({Object? params = null,}) { + return _then(_Loaded( +null == params ? _self.params : params // ignore: cast_nullable_to_non_nullable +as ResetPasswordParams, + )); +} + + +} + +/// @nodoc +mixin _$ResetPasswordState { + + RequestStatus get status; +/// Create a copy of ResetPasswordState +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$ResetPasswordStateCopyWith get copyWith => _$ResetPasswordStateCopyWithImpl(this as ResetPasswordState, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is ResetPasswordState&&(identical(other.status, status) || other.status == status)); +} + + +@override +int get hashCode => Object.hash(runtimeType,status); + +@override +String toString() { + return 'ResetPasswordState(status: $status)'; +} + + +} + +/// @nodoc +abstract mixin class $ResetPasswordStateCopyWith<$Res> { + factory $ResetPasswordStateCopyWith(ResetPasswordState value, $Res Function(ResetPasswordState) _then) = _$ResetPasswordStateCopyWithImpl; +@useResult +$Res call({ + RequestStatus status +}); + + + + +} +/// @nodoc +class _$ResetPasswordStateCopyWithImpl<$Res> + implements $ResetPasswordStateCopyWith<$Res> { + _$ResetPasswordStateCopyWithImpl(this._self, this._then); + + final ResetPasswordState _self; + final $Res Function(ResetPasswordState) _then; + +/// Create a copy of ResetPasswordState +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? status = null,}) { + return _then(_self.copyWith( +status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable +as RequestStatus, + )); +} + +} + + +/// Adds pattern-matching-related methods to [ResetPasswordState]. +extension ResetPasswordStatePatterns on ResetPasswordState { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _ResetPasswordState value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _ResetPasswordState() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _ResetPasswordState value) $default,){ +final _that = this; +switch (_that) { +case _ResetPasswordState(): +return $default(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _ResetPasswordState value)? $default,){ +final _that = this; +switch (_that) { +case _ResetPasswordState() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( RequestStatus status)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _ResetPasswordState() when $default != null: +return $default(_that.status);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( RequestStatus status) $default,) {final _that = this; +switch (_that) { +case _ResetPasswordState(): +return $default(_that.status);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( RequestStatus status)? $default,) {final _that = this; +switch (_that) { +case _ResetPasswordState() when $default != null: +return $default(_that.status);case _: + return null; + +} +} + +} + +/// @nodoc + + +class _ResetPasswordState implements ResetPasswordState { + const _ResetPasswordState({this.status = RequestStatus.initial}); + + +@override@JsonKey() final RequestStatus status; + +/// Create a copy of ResetPasswordState +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$ResetPasswordStateCopyWith<_ResetPasswordState> get copyWith => __$ResetPasswordStateCopyWithImpl<_ResetPasswordState>(this, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _ResetPasswordState&&(identical(other.status, status) || other.status == status)); +} + + +@override +int get hashCode => Object.hash(runtimeType,status); + +@override +String toString() { + return 'ResetPasswordState(status: $status)'; +} + + +} + +/// @nodoc +abstract mixin class _$ResetPasswordStateCopyWith<$Res> implements $ResetPasswordStateCopyWith<$Res> { + factory _$ResetPasswordStateCopyWith(_ResetPasswordState value, $Res Function(_ResetPasswordState) _then) = __$ResetPasswordStateCopyWithImpl; +@override @useResult +$Res call({ + RequestStatus status +}); + + + + +} +/// @nodoc +class __$ResetPasswordStateCopyWithImpl<$Res> + implements _$ResetPasswordStateCopyWith<$Res> { + __$ResetPasswordStateCopyWithImpl(this._self, this._then); + + final _ResetPasswordState _self; + final $Res Function(_ResetPasswordState) _then; + +/// Create a copy of ResetPasswordState +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? status = null,}) { + return _then(_ResetPasswordState( +status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable +as RequestStatus, + )); +} + + +} + +// dart format on diff --git a/lib/feature/auth/presentation/blocs/reset_password_bloc/reset_password_event.dart b/lib/feature/auth/presentation/blocs/reset_password_bloc/reset_password_event.dart new file mode 100644 index 0000000..6daed9b --- /dev/null +++ b/lib/feature/auth/presentation/blocs/reset_password_bloc/reset_password_event.dart @@ -0,0 +1,8 @@ +part of 'reset_password_bloc.dart'; + +@freezed +class ResetPasswordEvent with _$ResetPasswordEvent { + const factory ResetPasswordEvent.started() = _Started; + + const factory ResetPasswordEvent.loaded(ResetPasswordParams params) = _Loaded; +} diff --git a/lib/feature/auth/presentation/blocs/reset_password_bloc/reset_password_state.dart b/lib/feature/auth/presentation/blocs/reset_password_bloc/reset_password_state.dart new file mode 100644 index 0000000..b3fddb5 --- /dev/null +++ b/lib/feature/auth/presentation/blocs/reset_password_bloc/reset_password_state.dart @@ -0,0 +1,8 @@ +part of 'reset_password_bloc.dart'; + +@freezed +abstract class ResetPasswordState with _$ResetPasswordState { + const factory ResetPasswordState({ + @Default(RequestStatus.initial) RequestStatus status, + }) = _ResetPasswordState; +} diff --git a/lib/feature/auth/presentation/blocs/verify_otp_bloc/verify_otp_bloc.dart b/lib/feature/auth/presentation/blocs/verify_otp_bloc/verify_otp_bloc.dart new file mode 100644 index 0000000..50cd0a5 --- /dev/null +++ b/lib/feature/auth/presentation/blocs/verify_otp_bloc/verify_otp_bloc.dart @@ -0,0 +1,140 @@ +import 'package:food_delivery_client/feature/auth/domain/usecases/verify_otp_code_login_usecase.dart'; +import 'package:food_delivery_client/feature/auth/domain/usecases/verify_otp_code_register_usecase.dart'; +import 'package:food_delivery_client/feature/auth/domain/usecases/verify_phone_login_usecase.dart'; +import 'package:food_delivery_client/feature/auth/domain/usecases/verify_phone_register_usecase.dart'; +import 'package:food_delivery_client/feature/common/presentation/widgets/w_toastification.dart'; +import 'package:food_delivery_client/food_delivery_client.dart'; + +part 'verify_otp_event.dart'; + +part 'verify_otp_state.dart'; + +part 'verify_otp_bloc.freezed.dart'; + +@injectable +class VerifyOtpBloc extends Bloc { + final VerifyOtpCodeRegisterUseCase _registerUseCase; + final VerifyOtpCodeForgotPasswordUseCase _passwordUseCase; + final VerifyPhoneRegisterUseCase _phoneRegisterUseCase; + final VerifyPhoneNumberLoginUseCase _phoneNumberLoginUseCase; + + VerifyOtpBloc( + this._registerUseCase, + this._passwordUseCase, + this._phoneRegisterUseCase, + this._phoneNumberLoginUseCase, + ) : super(const VerifyOtpState()) { + Timer? timer1; + + on<_CancelTimer>((event, emit) { + timer1?.cancel(); + }); + + on<_Started>((event, emit) { + int seconds = state.time; + emit(state.copyWith(time: seconds)); + timer1 = Timer.periodic(TimeDelayConst.duration1, (timer) { + if (seconds == 0) { + timer.cancel(); + } else { + seconds--; + add(VerifyOtpEvent.ticked(seconds)); + } + }); + }); + + on<_Ticked>(_onTicked); + on<_VerifyOtpReset>(_onVerifyOtpReset); + on<_VerifyOtpRegister>(_onVerifyOtpRegister); + on<_ResendRegister>(_onResendVerifyPhoneRegister); + on<_ResendForgot>(_onResendVerifyPhoneForgot); + } + + void _onTicked(_Ticked event, Emitter emit) { + emit(state.copyWith(time: event.seconds)); + } + + Future _onVerifyOtpReset( + _VerifyOtpReset event, + Emitter emit, + ) async { + emit(state.copyWith(status: RequestStatus.loading)); + final response = await _passwordUseCase.call(event.params); + + response.fold( + (l) { + showErrorToast(l.errorMessage); + emit(state.copyWith(status: RequestStatus.error)); + }, + (r) { + showSuccessToast(r.message); + emit(state.copyWith(status: RequestStatus.loaded)); + add(VerifyOtpEvent.cancelTimer()); + }, + ); + } + + Future _onVerifyOtpRegister( + _VerifyOtpRegister event, + Emitter emit, + ) async { + emit(state.copyWith(status: RequestStatus.loading)); + final response = await _registerUseCase.call(event.params); + + response.fold( + (l) { + showErrorToast(l.errorMessage); + emit(state.copyWith(status: RequestStatus.error)); + }, + (r) { + showSuccessToast(r.message); + emit(state.copyWith(status: RequestStatus.loaded)); + add(VerifyOtpEvent.cancelTimer()); + }, + ); + } + + Future _onResendVerifyPhoneRegister( + _ResendRegister event, + Emitter emit, + ) async { + emit(state.copyWith(resendStatus: RequestStatus.loading)); + final response = await _phoneRegisterUseCase.call( + VerifyPhoneNumberParams(phoneNumber: event.phoneNUmber), + ); + + response.fold( + (l) { + showErrorToast(l.errorMessage); + emit(state.copyWith(resendStatus: RequestStatus.error)); + }, + (r) { + emit(state.copyWith(resendStatus: RequestStatus.loaded)); + add(VerifyOtpEvent.ticked(120)); + add(VerifyOtpEvent.started()); + }, + ); + } + + Future _onResendVerifyPhoneForgot( + _ResendForgot event, + Emitter emit, + ) async { + emit(state.copyWith(resendStatus: RequestStatus.loading)); + final response = await _phoneNumberLoginUseCase.call( + VerifyPhoneNumberParams(phoneNumber: event.phoneNUmber), + ); + + response.fold( + (l) { + showErrorToast(l.errorMessage); + emit(state.copyWith(resendStatus: RequestStatus.error)); + }, + (r) { + emit(state.copyWith(resendStatus: RequestStatus.loaded)); + add(VerifyOtpEvent.ticked(120)); + add(VerifyOtpEvent.started()); + }, + ); + } +} diff --git a/lib/feature/auth/presentation/blocs/verify_otp_bloc/verify_otp_bloc.freezed.dart b/lib/feature/auth/presentation/blocs/verify_otp_bloc/verify_otp_bloc.freezed.dart new file mode 100644 index 0000000..e15931f --- /dev/null +++ b/lib/feature/auth/presentation/blocs/verify_otp_bloc/verify_otp_bloc.freezed.dart @@ -0,0 +1,867 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND +// coverage:ignore-file +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'verify_otp_bloc.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; +/// @nodoc +mixin _$VerifyOtpEvent { + + + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is VerifyOtpEvent); +} + + +@override +int get hashCode => runtimeType.hashCode; + +@override +String toString() { + return 'VerifyOtpEvent()'; +} + + +} + +/// @nodoc +class $VerifyOtpEventCopyWith<$Res> { +$VerifyOtpEventCopyWith(VerifyOtpEvent _, $Res Function(VerifyOtpEvent) __); +} + + +/// Adds pattern-matching-related methods to [VerifyOtpEvent]. +extension VerifyOtpEventPatterns on VerifyOtpEvent { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap({TResult Function( _Started value)? started,TResult Function( _CancelTimer value)? cancelTimer,TResult Function( _ResendRegister value)? resendRegister,TResult Function( _ResendForgot value)? resendForgot,TResult Function( _Ticked value)? ticked,TResult Function( _VerifyOtpReset value)? verifyOtpReset,TResult Function( _VerifyOtpRegister value)? verifyOtpRegister,required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _Started() when started != null: +return started(_that);case _CancelTimer() when cancelTimer != null: +return cancelTimer(_that);case _ResendRegister() when resendRegister != null: +return resendRegister(_that);case _ResendForgot() when resendForgot != null: +return resendForgot(_that);case _Ticked() when ticked != null: +return ticked(_that);case _VerifyOtpReset() when verifyOtpReset != null: +return verifyOtpReset(_that);case _VerifyOtpRegister() when verifyOtpRegister != null: +return verifyOtpRegister(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map({required TResult Function( _Started value) started,required TResult Function( _CancelTimer value) cancelTimer,required TResult Function( _ResendRegister value) resendRegister,required TResult Function( _ResendForgot value) resendForgot,required TResult Function( _Ticked value) ticked,required TResult Function( _VerifyOtpReset value) verifyOtpReset,required TResult Function( _VerifyOtpRegister value) verifyOtpRegister,}){ +final _that = this; +switch (_that) { +case _Started(): +return started(_that);case _CancelTimer(): +return cancelTimer(_that);case _ResendRegister(): +return resendRegister(_that);case _ResendForgot(): +return resendForgot(_that);case _Ticked(): +return ticked(_that);case _VerifyOtpReset(): +return verifyOtpReset(_that);case _VerifyOtpRegister(): +return verifyOtpRegister(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull({TResult? Function( _Started value)? started,TResult? Function( _CancelTimer value)? cancelTimer,TResult? Function( _ResendRegister value)? resendRegister,TResult? Function( _ResendForgot value)? resendForgot,TResult? Function( _Ticked value)? ticked,TResult? Function( _VerifyOtpReset value)? verifyOtpReset,TResult? Function( _VerifyOtpRegister value)? verifyOtpRegister,}){ +final _that = this; +switch (_that) { +case _Started() when started != null: +return started(_that);case _CancelTimer() when cancelTimer != null: +return cancelTimer(_that);case _ResendRegister() when resendRegister != null: +return resendRegister(_that);case _ResendForgot() when resendForgot != null: +return resendForgot(_that);case _Ticked() when ticked != null: +return ticked(_that);case _VerifyOtpReset() when verifyOtpReset != null: +return verifyOtpReset(_that);case _VerifyOtpRegister() when verifyOtpRegister != null: +return verifyOtpRegister(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen({TResult Function()? started,TResult Function()? cancelTimer,TResult Function( String phoneNUmber)? resendRegister,TResult Function( String phoneNUmber)? resendForgot,TResult Function( int seconds)? ticked,TResult Function( VerifyOtpCodeParams params)? verifyOtpReset,TResult Function( VerifyOtpCodeParams params)? verifyOtpRegister,required TResult orElse(),}) {final _that = this; +switch (_that) { +case _Started() when started != null: +return started();case _CancelTimer() when cancelTimer != null: +return cancelTimer();case _ResendRegister() when resendRegister != null: +return resendRegister(_that.phoneNUmber);case _ResendForgot() when resendForgot != null: +return resendForgot(_that.phoneNUmber);case _Ticked() when ticked != null: +return ticked(_that.seconds);case _VerifyOtpReset() when verifyOtpReset != null: +return verifyOtpReset(_that.params);case _VerifyOtpRegister() when verifyOtpRegister != null: +return verifyOtpRegister(_that.params);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when({required TResult Function() started,required TResult Function() cancelTimer,required TResult Function( String phoneNUmber) resendRegister,required TResult Function( String phoneNUmber) resendForgot,required TResult Function( int seconds) ticked,required TResult Function( VerifyOtpCodeParams params) verifyOtpReset,required TResult Function( VerifyOtpCodeParams params) verifyOtpRegister,}) {final _that = this; +switch (_that) { +case _Started(): +return started();case _CancelTimer(): +return cancelTimer();case _ResendRegister(): +return resendRegister(_that.phoneNUmber);case _ResendForgot(): +return resendForgot(_that.phoneNUmber);case _Ticked(): +return ticked(_that.seconds);case _VerifyOtpReset(): +return verifyOtpReset(_that.params);case _VerifyOtpRegister(): +return verifyOtpRegister(_that.params);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull({TResult? Function()? started,TResult? Function()? cancelTimer,TResult? Function( String phoneNUmber)? resendRegister,TResult? Function( String phoneNUmber)? resendForgot,TResult? Function( int seconds)? ticked,TResult? Function( VerifyOtpCodeParams params)? verifyOtpReset,TResult? Function( VerifyOtpCodeParams params)? verifyOtpRegister,}) {final _that = this; +switch (_that) { +case _Started() when started != null: +return started();case _CancelTimer() when cancelTimer != null: +return cancelTimer();case _ResendRegister() when resendRegister != null: +return resendRegister(_that.phoneNUmber);case _ResendForgot() when resendForgot != null: +return resendForgot(_that.phoneNUmber);case _Ticked() when ticked != null: +return ticked(_that.seconds);case _VerifyOtpReset() when verifyOtpReset != null: +return verifyOtpReset(_that.params);case _VerifyOtpRegister() when verifyOtpRegister != null: +return verifyOtpRegister(_that.params);case _: + return null; + +} +} + +} + +/// @nodoc + + +class _Started implements VerifyOtpEvent { + const _Started(); + + + + + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _Started); +} + + +@override +int get hashCode => runtimeType.hashCode; + +@override +String toString() { + return 'VerifyOtpEvent.started()'; +} + + +} + + + + +/// @nodoc + + +class _CancelTimer implements VerifyOtpEvent { + const _CancelTimer(); + + + + + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _CancelTimer); +} + + +@override +int get hashCode => runtimeType.hashCode; + +@override +String toString() { + return 'VerifyOtpEvent.cancelTimer()'; +} + + +} + + + + +/// @nodoc + + +class _ResendRegister implements VerifyOtpEvent { + const _ResendRegister(this.phoneNUmber); + + + final String phoneNUmber; + +/// Create a copy of VerifyOtpEvent +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$ResendRegisterCopyWith<_ResendRegister> get copyWith => __$ResendRegisterCopyWithImpl<_ResendRegister>(this, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _ResendRegister&&(identical(other.phoneNUmber, phoneNUmber) || other.phoneNUmber == phoneNUmber)); +} + + +@override +int get hashCode => Object.hash(runtimeType,phoneNUmber); + +@override +String toString() { + return 'VerifyOtpEvent.resendRegister(phoneNUmber: $phoneNUmber)'; +} + + +} + +/// @nodoc +abstract mixin class _$ResendRegisterCopyWith<$Res> implements $VerifyOtpEventCopyWith<$Res> { + factory _$ResendRegisterCopyWith(_ResendRegister value, $Res Function(_ResendRegister) _then) = __$ResendRegisterCopyWithImpl; +@useResult +$Res call({ + String phoneNUmber +}); + + + + +} +/// @nodoc +class __$ResendRegisterCopyWithImpl<$Res> + implements _$ResendRegisterCopyWith<$Res> { + __$ResendRegisterCopyWithImpl(this._self, this._then); + + final _ResendRegister _self; + final $Res Function(_ResendRegister) _then; + +/// Create a copy of VerifyOtpEvent +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') $Res call({Object? phoneNUmber = null,}) { + return _then(_ResendRegister( +null == phoneNUmber ? _self.phoneNUmber : phoneNUmber // ignore: cast_nullable_to_non_nullable +as String, + )); +} + + +} + +/// @nodoc + + +class _ResendForgot implements VerifyOtpEvent { + const _ResendForgot(this.phoneNUmber); + + + final String phoneNUmber; + +/// Create a copy of VerifyOtpEvent +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$ResendForgotCopyWith<_ResendForgot> get copyWith => __$ResendForgotCopyWithImpl<_ResendForgot>(this, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _ResendForgot&&(identical(other.phoneNUmber, phoneNUmber) || other.phoneNUmber == phoneNUmber)); +} + + +@override +int get hashCode => Object.hash(runtimeType,phoneNUmber); + +@override +String toString() { + return 'VerifyOtpEvent.resendForgot(phoneNUmber: $phoneNUmber)'; +} + + +} + +/// @nodoc +abstract mixin class _$ResendForgotCopyWith<$Res> implements $VerifyOtpEventCopyWith<$Res> { + factory _$ResendForgotCopyWith(_ResendForgot value, $Res Function(_ResendForgot) _then) = __$ResendForgotCopyWithImpl; +@useResult +$Res call({ + String phoneNUmber +}); + + + + +} +/// @nodoc +class __$ResendForgotCopyWithImpl<$Res> + implements _$ResendForgotCopyWith<$Res> { + __$ResendForgotCopyWithImpl(this._self, this._then); + + final _ResendForgot _self; + final $Res Function(_ResendForgot) _then; + +/// Create a copy of VerifyOtpEvent +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') $Res call({Object? phoneNUmber = null,}) { + return _then(_ResendForgot( +null == phoneNUmber ? _self.phoneNUmber : phoneNUmber // ignore: cast_nullable_to_non_nullable +as String, + )); +} + + +} + +/// @nodoc + + +class _Ticked implements VerifyOtpEvent { + const _Ticked(this.seconds); + + + final int seconds; + +/// Create a copy of VerifyOtpEvent +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$TickedCopyWith<_Ticked> get copyWith => __$TickedCopyWithImpl<_Ticked>(this, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _Ticked&&(identical(other.seconds, seconds) || other.seconds == seconds)); +} + + +@override +int get hashCode => Object.hash(runtimeType,seconds); + +@override +String toString() { + return 'VerifyOtpEvent.ticked(seconds: $seconds)'; +} + + +} + +/// @nodoc +abstract mixin class _$TickedCopyWith<$Res> implements $VerifyOtpEventCopyWith<$Res> { + factory _$TickedCopyWith(_Ticked value, $Res Function(_Ticked) _then) = __$TickedCopyWithImpl; +@useResult +$Res call({ + int seconds +}); + + + + +} +/// @nodoc +class __$TickedCopyWithImpl<$Res> + implements _$TickedCopyWith<$Res> { + __$TickedCopyWithImpl(this._self, this._then); + + final _Ticked _self; + final $Res Function(_Ticked) _then; + +/// Create a copy of VerifyOtpEvent +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') $Res call({Object? seconds = null,}) { + return _then(_Ticked( +null == seconds ? _self.seconds : seconds // ignore: cast_nullable_to_non_nullable +as int, + )); +} + + +} + +/// @nodoc + + +class _VerifyOtpReset implements VerifyOtpEvent { + const _VerifyOtpReset(this.params); + + + final VerifyOtpCodeParams params; + +/// Create a copy of VerifyOtpEvent +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$VerifyOtpResetCopyWith<_VerifyOtpReset> get copyWith => __$VerifyOtpResetCopyWithImpl<_VerifyOtpReset>(this, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _VerifyOtpReset&&(identical(other.params, params) || other.params == params)); +} + + +@override +int get hashCode => Object.hash(runtimeType,params); + +@override +String toString() { + return 'VerifyOtpEvent.verifyOtpReset(params: $params)'; +} + + +} + +/// @nodoc +abstract mixin class _$VerifyOtpResetCopyWith<$Res> implements $VerifyOtpEventCopyWith<$Res> { + factory _$VerifyOtpResetCopyWith(_VerifyOtpReset value, $Res Function(_VerifyOtpReset) _then) = __$VerifyOtpResetCopyWithImpl; +@useResult +$Res call({ + VerifyOtpCodeParams params +}); + + + + +} +/// @nodoc +class __$VerifyOtpResetCopyWithImpl<$Res> + implements _$VerifyOtpResetCopyWith<$Res> { + __$VerifyOtpResetCopyWithImpl(this._self, this._then); + + final _VerifyOtpReset _self; + final $Res Function(_VerifyOtpReset) _then; + +/// Create a copy of VerifyOtpEvent +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') $Res call({Object? params = null,}) { + return _then(_VerifyOtpReset( +null == params ? _self.params : params // ignore: cast_nullable_to_non_nullable +as VerifyOtpCodeParams, + )); +} + + +} + +/// @nodoc + + +class _VerifyOtpRegister implements VerifyOtpEvent { + const _VerifyOtpRegister(this.params); + + + final VerifyOtpCodeParams params; + +/// Create a copy of VerifyOtpEvent +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$VerifyOtpRegisterCopyWith<_VerifyOtpRegister> get copyWith => __$VerifyOtpRegisterCopyWithImpl<_VerifyOtpRegister>(this, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _VerifyOtpRegister&&(identical(other.params, params) || other.params == params)); +} + + +@override +int get hashCode => Object.hash(runtimeType,params); + +@override +String toString() { + return 'VerifyOtpEvent.verifyOtpRegister(params: $params)'; +} + + +} + +/// @nodoc +abstract mixin class _$VerifyOtpRegisterCopyWith<$Res> implements $VerifyOtpEventCopyWith<$Res> { + factory _$VerifyOtpRegisterCopyWith(_VerifyOtpRegister value, $Res Function(_VerifyOtpRegister) _then) = __$VerifyOtpRegisterCopyWithImpl; +@useResult +$Res call({ + VerifyOtpCodeParams params +}); + + + + +} +/// @nodoc +class __$VerifyOtpRegisterCopyWithImpl<$Res> + implements _$VerifyOtpRegisterCopyWith<$Res> { + __$VerifyOtpRegisterCopyWithImpl(this._self, this._then); + + final _VerifyOtpRegister _self; + final $Res Function(_VerifyOtpRegister) _then; + +/// Create a copy of VerifyOtpEvent +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') $Res call({Object? params = null,}) { + return _then(_VerifyOtpRegister( +null == params ? _self.params : params // ignore: cast_nullable_to_non_nullable +as VerifyOtpCodeParams, + )); +} + + +} + +/// @nodoc +mixin _$VerifyOtpState { + + RequestStatus get status; RequestStatus get resendStatus; int get time; +/// Create a copy of VerifyOtpState +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$VerifyOtpStateCopyWith get copyWith => _$VerifyOtpStateCopyWithImpl(this as VerifyOtpState, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is VerifyOtpState&&(identical(other.status, status) || other.status == status)&&(identical(other.resendStatus, resendStatus) || other.resendStatus == resendStatus)&&(identical(other.time, time) || other.time == time)); +} + + +@override +int get hashCode => Object.hash(runtimeType,status,resendStatus,time); + +@override +String toString() { + return 'VerifyOtpState(status: $status, resendStatus: $resendStatus, time: $time)'; +} + + +} + +/// @nodoc +abstract mixin class $VerifyOtpStateCopyWith<$Res> { + factory $VerifyOtpStateCopyWith(VerifyOtpState value, $Res Function(VerifyOtpState) _then) = _$VerifyOtpStateCopyWithImpl; +@useResult +$Res call({ + RequestStatus status, RequestStatus resendStatus, int time +}); + + + + +} +/// @nodoc +class _$VerifyOtpStateCopyWithImpl<$Res> + implements $VerifyOtpStateCopyWith<$Res> { + _$VerifyOtpStateCopyWithImpl(this._self, this._then); + + final VerifyOtpState _self; + final $Res Function(VerifyOtpState) _then; + +/// Create a copy of VerifyOtpState +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? status = null,Object? resendStatus = null,Object? time = null,}) { + return _then(_self.copyWith( +status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable +as RequestStatus,resendStatus: null == resendStatus ? _self.resendStatus : resendStatus // ignore: cast_nullable_to_non_nullable +as RequestStatus,time: null == time ? _self.time : time // ignore: cast_nullable_to_non_nullable +as int, + )); +} + +} + + +/// Adds pattern-matching-related methods to [VerifyOtpState]. +extension VerifyOtpStatePatterns on VerifyOtpState { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _VerifyOtpState value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _VerifyOtpState() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _VerifyOtpState value) $default,){ +final _that = this; +switch (_that) { +case _VerifyOtpState(): +return $default(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _VerifyOtpState value)? $default,){ +final _that = this; +switch (_that) { +case _VerifyOtpState() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( RequestStatus status, RequestStatus resendStatus, int time)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _VerifyOtpState() when $default != null: +return $default(_that.status,_that.resendStatus,_that.time);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( RequestStatus status, RequestStatus resendStatus, int time) $default,) {final _that = this; +switch (_that) { +case _VerifyOtpState(): +return $default(_that.status,_that.resendStatus,_that.time);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( RequestStatus status, RequestStatus resendStatus, int time)? $default,) {final _that = this; +switch (_that) { +case _VerifyOtpState() when $default != null: +return $default(_that.status,_that.resendStatus,_that.time);case _: + return null; + +} +} + +} + +/// @nodoc + + +class _VerifyOtpState implements VerifyOtpState { + const _VerifyOtpState({this.status = RequestStatus.initial, this.resendStatus = RequestStatus.initial, this.time = 120}); + + +@override@JsonKey() final RequestStatus status; +@override@JsonKey() final RequestStatus resendStatus; +@override@JsonKey() final int time; + +/// Create a copy of VerifyOtpState +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$VerifyOtpStateCopyWith<_VerifyOtpState> get copyWith => __$VerifyOtpStateCopyWithImpl<_VerifyOtpState>(this, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _VerifyOtpState&&(identical(other.status, status) || other.status == status)&&(identical(other.resendStatus, resendStatus) || other.resendStatus == resendStatus)&&(identical(other.time, time) || other.time == time)); +} + + +@override +int get hashCode => Object.hash(runtimeType,status,resendStatus,time); + +@override +String toString() { + return 'VerifyOtpState(status: $status, resendStatus: $resendStatus, time: $time)'; +} + + +} + +/// @nodoc +abstract mixin class _$VerifyOtpStateCopyWith<$Res> implements $VerifyOtpStateCopyWith<$Res> { + factory _$VerifyOtpStateCopyWith(_VerifyOtpState value, $Res Function(_VerifyOtpState) _then) = __$VerifyOtpStateCopyWithImpl; +@override @useResult +$Res call({ + RequestStatus status, RequestStatus resendStatus, int time +}); + + + + +} +/// @nodoc +class __$VerifyOtpStateCopyWithImpl<$Res> + implements _$VerifyOtpStateCopyWith<$Res> { + __$VerifyOtpStateCopyWithImpl(this._self, this._then); + + final _VerifyOtpState _self; + final $Res Function(_VerifyOtpState) _then; + +/// Create a copy of VerifyOtpState +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? status = null,Object? resendStatus = null,Object? time = null,}) { + return _then(_VerifyOtpState( +status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable +as RequestStatus,resendStatus: null == resendStatus ? _self.resendStatus : resendStatus // ignore: cast_nullable_to_non_nullable +as RequestStatus,time: null == time ? _self.time : time // ignore: cast_nullable_to_non_nullable +as int, + )); +} + + +} + +// dart format on diff --git a/lib/feature/auth/presentation/blocs/verify_otp_bloc/verify_otp_event.dart b/lib/feature/auth/presentation/blocs/verify_otp_bloc/verify_otp_event.dart new file mode 100644 index 0000000..4bc725e --- /dev/null +++ b/lib/feature/auth/presentation/blocs/verify_otp_bloc/verify_otp_event.dart @@ -0,0 +1,19 @@ +part of 'verify_otp_bloc.dart'; + +@freezed +class VerifyOtpEvent with _$VerifyOtpEvent { + const factory VerifyOtpEvent.started() = _Started; + const factory VerifyOtpEvent.cancelTimer() = _CancelTimer; + const factory VerifyOtpEvent.resendRegister(String phoneNUmber) = + _ResendRegister; + + const factory VerifyOtpEvent.resendForgot(String phoneNUmber) = _ResendForgot; + + const factory VerifyOtpEvent.ticked(int seconds) = _Ticked; + + const factory VerifyOtpEvent.verifyOtpReset(VerifyOtpCodeParams params) = + _VerifyOtpReset; + + const factory VerifyOtpEvent.verifyOtpRegister(VerifyOtpCodeParams params) = + _VerifyOtpRegister; +} diff --git a/lib/feature/auth/presentation/blocs/verify_otp_bloc/verify_otp_state.dart b/lib/feature/auth/presentation/blocs/verify_otp_bloc/verify_otp_state.dart new file mode 100644 index 0000000..aaa6621 --- /dev/null +++ b/lib/feature/auth/presentation/blocs/verify_otp_bloc/verify_otp_state.dart @@ -0,0 +1,10 @@ +part of 'verify_otp_bloc.dart'; + +@freezed +abstract class VerifyOtpState with _$VerifyOtpState { + const factory VerifyOtpState({ + @Default(RequestStatus.initial) RequestStatus status, + @Default(RequestStatus.initial) RequestStatus resendStatus, + @Default(120) int time, + }) = _VerifyOtpState; +} diff --git a/lib/feature/auth/presentation/blocs/verify_phone_bloc/verify_phone_bloc.dart b/lib/feature/auth/presentation/blocs/verify_phone_bloc/verify_phone_bloc.dart new file mode 100644 index 0000000..de1b26f --- /dev/null +++ b/lib/feature/auth/presentation/blocs/verify_phone_bloc/verify_phone_bloc.dart @@ -0,0 +1,60 @@ +import 'package:food_delivery_client/feature/auth/domain/usecases/verify_phone_login_usecase.dart'; +import 'package:food_delivery_client/feature/auth/domain/usecases/verify_phone_register_usecase.dart'; +import 'package:food_delivery_client/feature/common/presentation/widgets/w_toastification.dart'; +import 'package:food_delivery_client/food_delivery_client.dart'; + +part 'verify_phone_event.dart'; + +part 'verify_phone_state.dart'; + +part 'verify_phone_bloc.freezed.dart'; + +@injectable +class VerifyPhoneBloc extends Bloc { + final VerifyPhoneNumberLoginUseCase _loginUseCase; + final VerifyPhoneRegisterUseCase _registerUseCase; + + VerifyPhoneBloc(this._loginUseCase, this._registerUseCase) + : super(const VerifyPhoneState()) { + on<_VerifyPhoneRegister>(_onVerifyPhoneNumberRegister); + on<_VerifyPhoneReset>(_onVerifyPhoneReset); + } + + Future _onVerifyPhoneNumberRegister( + _VerifyPhoneRegister event, + Emitter emit, + ) async { + emit(state.copyWith(status: RequestStatus.loading)); + final response = await _registerUseCase.call(event.params); + + response.fold( + (l) { + showErrorToast(l.errorMessage); + emit(state.copyWith(status: RequestStatus.error)); + }, + (r) { + showSuccessToast(r.message); + emit(state.copyWith(status: RequestStatus.loaded)); + }, + ); + } + + Future _onVerifyPhoneReset( + _VerifyPhoneReset event, + Emitter emit, + ) async { + emit(state.copyWith(status: RequestStatus.loading)); + final response = await _loginUseCase.call(event.params); + + response.fold( + (l) { + showErrorToast(l.errorMessage); + emit(state.copyWith(status: RequestStatus.error)); + }, + (r) { + showSuccessToast(r.message); + emit(state.copyWith(status: RequestStatus.loaded)); + }, + ); + } +} diff --git a/lib/feature/auth/presentation/blocs/verify_phone_bloc/verify_phone_bloc.freezed.dart b/lib/feature/auth/presentation/blocs/verify_phone_bloc/verify_phone_bloc.freezed.dart new file mode 100644 index 0000000..6186058 --- /dev/null +++ b/lib/feature/auth/presentation/blocs/verify_phone_bloc/verify_phone_bloc.freezed.dart @@ -0,0 +1,607 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND +// coverage:ignore-file +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'verify_phone_bloc.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; +/// @nodoc +mixin _$VerifyPhoneEvent { + + + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is VerifyPhoneEvent); +} + + +@override +int get hashCode => runtimeType.hashCode; + +@override +String toString() { + return 'VerifyPhoneEvent()'; +} + + +} + +/// @nodoc +class $VerifyPhoneEventCopyWith<$Res> { +$VerifyPhoneEventCopyWith(VerifyPhoneEvent _, $Res Function(VerifyPhoneEvent) __); +} + + +/// Adds pattern-matching-related methods to [VerifyPhoneEvent]. +extension VerifyPhoneEventPatterns on VerifyPhoneEvent { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap({TResult Function( _Started value)? started,TResult Function( _VerifyPhoneRegister value)? verifyPhoneRegister,TResult Function( _VerifyPhoneReset value)? verifyPhoneReset,required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _Started() when started != null: +return started(_that);case _VerifyPhoneRegister() when verifyPhoneRegister != null: +return verifyPhoneRegister(_that);case _VerifyPhoneReset() when verifyPhoneReset != null: +return verifyPhoneReset(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map({required TResult Function( _Started value) started,required TResult Function( _VerifyPhoneRegister value) verifyPhoneRegister,required TResult Function( _VerifyPhoneReset value) verifyPhoneReset,}){ +final _that = this; +switch (_that) { +case _Started(): +return started(_that);case _VerifyPhoneRegister(): +return verifyPhoneRegister(_that);case _VerifyPhoneReset(): +return verifyPhoneReset(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull({TResult? Function( _Started value)? started,TResult? Function( _VerifyPhoneRegister value)? verifyPhoneRegister,TResult? Function( _VerifyPhoneReset value)? verifyPhoneReset,}){ +final _that = this; +switch (_that) { +case _Started() when started != null: +return started(_that);case _VerifyPhoneRegister() when verifyPhoneRegister != null: +return verifyPhoneRegister(_that);case _VerifyPhoneReset() when verifyPhoneReset != null: +return verifyPhoneReset(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen({TResult Function()? started,TResult Function( VerifyPhoneNumberParams params)? verifyPhoneRegister,TResult Function( VerifyPhoneNumberParams params)? verifyPhoneReset,required TResult orElse(),}) {final _that = this; +switch (_that) { +case _Started() when started != null: +return started();case _VerifyPhoneRegister() when verifyPhoneRegister != null: +return verifyPhoneRegister(_that.params);case _VerifyPhoneReset() when verifyPhoneReset != null: +return verifyPhoneReset(_that.params);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when({required TResult Function() started,required TResult Function( VerifyPhoneNumberParams params) verifyPhoneRegister,required TResult Function( VerifyPhoneNumberParams params) verifyPhoneReset,}) {final _that = this; +switch (_that) { +case _Started(): +return started();case _VerifyPhoneRegister(): +return verifyPhoneRegister(_that.params);case _VerifyPhoneReset(): +return verifyPhoneReset(_that.params);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull({TResult? Function()? started,TResult? Function( VerifyPhoneNumberParams params)? verifyPhoneRegister,TResult? Function( VerifyPhoneNumberParams params)? verifyPhoneReset,}) {final _that = this; +switch (_that) { +case _Started() when started != null: +return started();case _VerifyPhoneRegister() when verifyPhoneRegister != null: +return verifyPhoneRegister(_that.params);case _VerifyPhoneReset() when verifyPhoneReset != null: +return verifyPhoneReset(_that.params);case _: + return null; + +} +} + +} + +/// @nodoc + + +class _Started implements VerifyPhoneEvent { + const _Started(); + + + + + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _Started); +} + + +@override +int get hashCode => runtimeType.hashCode; + +@override +String toString() { + return 'VerifyPhoneEvent.started()'; +} + + +} + + + + +/// @nodoc + + +class _VerifyPhoneRegister implements VerifyPhoneEvent { + const _VerifyPhoneRegister(this.params); + + + final VerifyPhoneNumberParams params; + +/// Create a copy of VerifyPhoneEvent +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$VerifyPhoneRegisterCopyWith<_VerifyPhoneRegister> get copyWith => __$VerifyPhoneRegisterCopyWithImpl<_VerifyPhoneRegister>(this, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _VerifyPhoneRegister&&(identical(other.params, params) || other.params == params)); +} + + +@override +int get hashCode => Object.hash(runtimeType,params); + +@override +String toString() { + return 'VerifyPhoneEvent.verifyPhoneRegister(params: $params)'; +} + + +} + +/// @nodoc +abstract mixin class _$VerifyPhoneRegisterCopyWith<$Res> implements $VerifyPhoneEventCopyWith<$Res> { + factory _$VerifyPhoneRegisterCopyWith(_VerifyPhoneRegister value, $Res Function(_VerifyPhoneRegister) _then) = __$VerifyPhoneRegisterCopyWithImpl; +@useResult +$Res call({ + VerifyPhoneNumberParams params +}); + + + + +} +/// @nodoc +class __$VerifyPhoneRegisterCopyWithImpl<$Res> + implements _$VerifyPhoneRegisterCopyWith<$Res> { + __$VerifyPhoneRegisterCopyWithImpl(this._self, this._then); + + final _VerifyPhoneRegister _self; + final $Res Function(_VerifyPhoneRegister) _then; + +/// Create a copy of VerifyPhoneEvent +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') $Res call({Object? params = null,}) { + return _then(_VerifyPhoneRegister( +null == params ? _self.params : params // ignore: cast_nullable_to_non_nullable +as VerifyPhoneNumberParams, + )); +} + + +} + +/// @nodoc + + +class _VerifyPhoneReset implements VerifyPhoneEvent { + const _VerifyPhoneReset(this.params); + + + final VerifyPhoneNumberParams params; + +/// Create a copy of VerifyPhoneEvent +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$VerifyPhoneResetCopyWith<_VerifyPhoneReset> get copyWith => __$VerifyPhoneResetCopyWithImpl<_VerifyPhoneReset>(this, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _VerifyPhoneReset&&(identical(other.params, params) || other.params == params)); +} + + +@override +int get hashCode => Object.hash(runtimeType,params); + +@override +String toString() { + return 'VerifyPhoneEvent.verifyPhoneReset(params: $params)'; +} + + +} + +/// @nodoc +abstract mixin class _$VerifyPhoneResetCopyWith<$Res> implements $VerifyPhoneEventCopyWith<$Res> { + factory _$VerifyPhoneResetCopyWith(_VerifyPhoneReset value, $Res Function(_VerifyPhoneReset) _then) = __$VerifyPhoneResetCopyWithImpl; +@useResult +$Res call({ + VerifyPhoneNumberParams params +}); + + + + +} +/// @nodoc +class __$VerifyPhoneResetCopyWithImpl<$Res> + implements _$VerifyPhoneResetCopyWith<$Res> { + __$VerifyPhoneResetCopyWithImpl(this._self, this._then); + + final _VerifyPhoneReset _self; + final $Res Function(_VerifyPhoneReset) _then; + +/// Create a copy of VerifyPhoneEvent +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') $Res call({Object? params = null,}) { + return _then(_VerifyPhoneReset( +null == params ? _self.params : params // ignore: cast_nullable_to_non_nullable +as VerifyPhoneNumberParams, + )); +} + + +} + +/// @nodoc +mixin _$VerifyPhoneState { + + RequestStatus get status; +/// Create a copy of VerifyPhoneState +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$VerifyPhoneStateCopyWith get copyWith => _$VerifyPhoneStateCopyWithImpl(this as VerifyPhoneState, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is VerifyPhoneState&&(identical(other.status, status) || other.status == status)); +} + + +@override +int get hashCode => Object.hash(runtimeType,status); + +@override +String toString() { + return 'VerifyPhoneState(status: $status)'; +} + + +} + +/// @nodoc +abstract mixin class $VerifyPhoneStateCopyWith<$Res> { + factory $VerifyPhoneStateCopyWith(VerifyPhoneState value, $Res Function(VerifyPhoneState) _then) = _$VerifyPhoneStateCopyWithImpl; +@useResult +$Res call({ + RequestStatus status +}); + + + + +} +/// @nodoc +class _$VerifyPhoneStateCopyWithImpl<$Res> + implements $VerifyPhoneStateCopyWith<$Res> { + _$VerifyPhoneStateCopyWithImpl(this._self, this._then); + + final VerifyPhoneState _self; + final $Res Function(VerifyPhoneState) _then; + +/// Create a copy of VerifyPhoneState +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? status = null,}) { + return _then(_self.copyWith( +status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable +as RequestStatus, + )); +} + +} + + +/// Adds pattern-matching-related methods to [VerifyPhoneState]. +extension VerifyPhoneStatePatterns on VerifyPhoneState { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _VerifyPhoneState value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _VerifyPhoneState() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _VerifyPhoneState value) $default,){ +final _that = this; +switch (_that) { +case _VerifyPhoneState(): +return $default(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _VerifyPhoneState value)? $default,){ +final _that = this; +switch (_that) { +case _VerifyPhoneState() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( RequestStatus status)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _VerifyPhoneState() when $default != null: +return $default(_that.status);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( RequestStatus status) $default,) {final _that = this; +switch (_that) { +case _VerifyPhoneState(): +return $default(_that.status);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( RequestStatus status)? $default,) {final _that = this; +switch (_that) { +case _VerifyPhoneState() when $default != null: +return $default(_that.status);case _: + return null; + +} +} + +} + +/// @nodoc + + +class _VerifyPhoneState implements VerifyPhoneState { + const _VerifyPhoneState({this.status = RequestStatus.initial}); + + +@override@JsonKey() final RequestStatus status; + +/// Create a copy of VerifyPhoneState +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$VerifyPhoneStateCopyWith<_VerifyPhoneState> get copyWith => __$VerifyPhoneStateCopyWithImpl<_VerifyPhoneState>(this, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _VerifyPhoneState&&(identical(other.status, status) || other.status == status)); +} + + +@override +int get hashCode => Object.hash(runtimeType,status); + +@override +String toString() { + return 'VerifyPhoneState(status: $status)'; +} + + +} + +/// @nodoc +abstract mixin class _$VerifyPhoneStateCopyWith<$Res> implements $VerifyPhoneStateCopyWith<$Res> { + factory _$VerifyPhoneStateCopyWith(_VerifyPhoneState value, $Res Function(_VerifyPhoneState) _then) = __$VerifyPhoneStateCopyWithImpl; +@override @useResult +$Res call({ + RequestStatus status +}); + + + + +} +/// @nodoc +class __$VerifyPhoneStateCopyWithImpl<$Res> + implements _$VerifyPhoneStateCopyWith<$Res> { + __$VerifyPhoneStateCopyWithImpl(this._self, this._then); + + final _VerifyPhoneState _self; + final $Res Function(_VerifyPhoneState) _then; + +/// Create a copy of VerifyPhoneState +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? status = null,}) { + return _then(_VerifyPhoneState( +status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable +as RequestStatus, + )); +} + + +} + +// dart format on diff --git a/lib/feature/auth/presentation/blocs/verify_phone_bloc/verify_phone_event.dart b/lib/feature/auth/presentation/blocs/verify_phone_bloc/verify_phone_event.dart new file mode 100644 index 0000000..eb3c247 --- /dev/null +++ b/lib/feature/auth/presentation/blocs/verify_phone_bloc/verify_phone_event.dart @@ -0,0 +1,14 @@ +part of 'verify_phone_bloc.dart'; + +@freezed +class VerifyPhoneEvent with _$VerifyPhoneEvent { + const factory VerifyPhoneEvent.started() = _Started; + + const factory VerifyPhoneEvent.verifyPhoneRegister( + VerifyPhoneNumberParams params, + ) = _VerifyPhoneRegister; + + const factory VerifyPhoneEvent.verifyPhoneReset( + VerifyPhoneNumberParams params, + ) = _VerifyPhoneReset; +} diff --git a/lib/feature/auth/presentation/blocs/verify_phone_bloc/verify_phone_state.dart b/lib/feature/auth/presentation/blocs/verify_phone_bloc/verify_phone_state.dart new file mode 100644 index 0000000..94318ef --- /dev/null +++ b/lib/feature/auth/presentation/blocs/verify_phone_bloc/verify_phone_state.dart @@ -0,0 +1,8 @@ +part of 'verify_phone_bloc.dart'; + +@freezed +abstract class VerifyPhoneState with _$VerifyPhoneState { + const factory VerifyPhoneState({ + @Default(RequestStatus.initial) RequestStatus status, + }) = _VerifyPhoneState; +} diff --git a/lib/feature/auth/presentation/login_page/login_page.dart b/lib/feature/auth/presentation/login_page/login_page.dart deleted file mode 100644 index a72ef12..0000000 --- a/lib/feature/auth/presentation/login_page/login_page.dart +++ /dev/null @@ -1,15 +0,0 @@ -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(); - } -} - - diff --git a/lib/feature/auth/presentation/login_page/widgets/login_body.dart b/lib/feature/auth/presentation/login_page/widgets/login_body.dart deleted file mode 100644 index 88f4cad..0000000 --- a/lib/feature/auth/presentation/login_page/widgets/login_body.dart +++ /dev/null @@ -1,203 +0,0 @@ -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/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 createState() => _WLoginBodyState(); -} - -class _WLoginBodyState extends State { - late TextEditingController _phoneNumberController; - late TextEditingController _passwordController; - final _formKey = GlobalKey(); - bool _isValidForm = false; - - void _validateForm() { - final isValid = _formKey.currentState?.validate() ?? false; - if (isValid != _isValidForm) { - setState(() { - _isValidForm = isValid; - }); - } - } - - @override - void initState() { - _phoneNumberController = TextEditingController(); - _passwordController = TextEditingController(); - _passwordController.addListener(_validateForm); - _phoneNumberController.addListener(_validateForm); - super.initState(); - } - - @override - void dispose() { - _phoneNumberController.removeListener(_validateForm); - _passwordController.removeListener(_validateForm); - _phoneNumberController.dispose(); - _passwordController.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Form( - key: _formKey, - autovalidateMode: AutovalidateMode.onUserInteraction, - child: WLayout( - top: false, - left: false, - right: false, - child: Scaffold( - body: Stack( - children: [ - SizedBox( - width: context.w, - child: SvgPicture.asset(AppIcons.icLogin, fit: BoxFit.fitWidth), - ), - Positioned( - child: Material( - color: AppColors.cTransparent, - child: SingleChildScrollView( - keyboardDismissBehavior: - ScrollViewKeyboardDismissBehavior.onDrag, - child: - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - 30.verticalSpace, - //WBackButton(), - 60.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( - prefixIcon: Text("+ 998"), - controller: _phoneNumberController, - hintText: context.loc.enter_email_or_phone, - inputFormatters: [ - FilteringTextInputFormatter.digitsOnly, - Formatters.phoneFormatter, - LengthLimitingTextInputFormatter(12), - ], - validator: (value) { - return Validators.validatePhoneNumber( - _phoneNumberController.text.trim(), - ); - }, - ), - 20.verticalSpace, - Text( - context.loc.password, - style: context.appThemeTextStyles.size16Medium, - ), - 10.verticalSpace, - AppTextFormField( - obscureText: true, - controller: _passwordController, - hintText: context.loc.enter_password, - validator: (value) { - return Validators.validatePassword( - _passwordController.text.trim(), - ); - }, - ), - 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, - isActive: _isValidForm, - isLoading: false, - 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.symmetric(horizontal: 4), - ), - ), - 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, - ), - ), - ), - ), - ], - ), - ), - ), - ); - } -} diff --git a/lib/feature/auth/presentation/pages/login_page/login_page.dart b/lib/feature/auth/presentation/pages/login_page/login_page.dart new file mode 100644 index 0000000..9b4a3e1 --- /dev/null +++ b/lib/feature/auth/presentation/pages/login_page/login_page.dart @@ -0,0 +1,16 @@ +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 { + const LoginPage({super.key}); + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => sl(), + child: WLoginBody(), + ); + } +} diff --git a/lib/feature/auth/presentation/pages/login_page/widgets/login_body.dart b/lib/feature/auth/presentation/pages/login_page/widgets/login_body.dart new file mode 100644 index 0000000..e566a6b --- /dev/null +++ b/lib/feature/auth/presentation/pages/login_page/widgets/login_body.dart @@ -0,0 +1,234 @@ +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/pages/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'; +import '../../../blocs/login_bloc/login_bloc.dart'; + +class WLoginBody extends StatefulWidget { + const WLoginBody({super.key}); + + @override + State createState() => _WLoginBodyState(); +} + +class _WLoginBodyState extends State { + late TextEditingController _phoneNumberController; + late TextEditingController _passwordController; + final _formKey = GlobalKey(); + bool _isValidForm = false; + + void _validateForm() { + final isValid = _formKey.currentState?.validate() ?? false; + if (isValid != _isValidForm) { + setState(() { + _isValidForm = isValid; + }); + } + } + + @override + void initState() { + _phoneNumberController = TextEditingController(); + _passwordController = TextEditingController(); + _passwordController.addListener(_validateForm); + _phoneNumberController.addListener(_validateForm); + super.initState(); + } + + @override + void dispose() { + _phoneNumberController.removeListener(_validateForm); + _passwordController.removeListener(_validateForm); + _phoneNumberController.dispose(); + _passwordController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return BlocConsumer( + listenWhen: (previous, current) => previous.status != current.status, + listener: (context, state) { + if (state.status.isLoaded()) { + context.go(Routes.main); + } + }, + builder: (context, state) { + return Form( + key: _formKey, + autovalidateMode: AutovalidateMode.onUserInteraction, + child: WLayout( + top: false, + left: false, + right: false, + child: Scaffold( + body: Stack( + children: [ + SizedBox( + width: context.w, + child: SvgPicture.asset( + AppIcons.icLogin, + fit: BoxFit.fitWidth, + ), + ), + Positioned( + child: Material( + color: AppColors.cTransparent, + child: SingleChildScrollView( + keyboardDismissBehavior: + ScrollViewKeyboardDismissBehavior.onDrag, + child: + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + 30.verticalSpace, + //WBackButton(), + 60.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( + prefixIcon: Text("+ 998"), + controller: _phoneNumberController, + hintText: context.loc.enter_email_or_phone, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + Formatters.phoneFormatter, + LengthLimitingTextInputFormatter(12), + ], + validator: (value) { + return Validators.validatePhoneNumber( + _phoneNumberController.text.trim(), + ); + }, + ), + 20.verticalSpace, + Text( + context.loc.password, + style: + context.appThemeTextStyles.size16Medium, + ), + 10.verticalSpace, + AppTextFormField( + obscureText: true, + controller: _passwordController, + hintText: context.loc.enter_password, + validator: (value) { + return Validators.validatePassword( + _passwordController.text.trim(), + ); + }, + ), + 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, + isActive: _isValidForm, + isLoading: state.status.isLoading(), + onPressed: () { + if (_formKey.currentState?.validate() ?? + false) { + context.read().add( + LoginEvent.login( + LoginParams( + password: _passwordController.text + .trim(), + phoneNumber: + "+998${_phoneNumberController.text.trim().replaceAll(" ", "")}", + ), + ), + ); + } + }, + ), + 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.symmetric( + horizontal: 4, + ), + ), + ), + 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, + ), + ), + ), + ), + ], + ), + ), + ), + ); + }, + ); + } +} diff --git a/lib/feature/auth/presentation/login_page/widgets/welcome_text.dart b/lib/feature/auth/presentation/pages/login_page/widgets/welcome_text.dart similarity index 96% rename from lib/feature/auth/presentation/login_page/widgets/welcome_text.dart rename to lib/feature/auth/presentation/pages/login_page/widgets/welcome_text.dart index 2789bc4..03bfea9 100644 --- a/lib/feature/auth/presentation/login_page/widgets/welcome_text.dart +++ b/lib/feature/auth/presentation/pages/login_page/widgets/welcome_text.dart @@ -1,4 +1,5 @@ -import '../../../../../food_delivery_client.dart'; + +import '../../../../../../food_delivery_client.dart'; class WelcomeText extends StatelessWidget { final String text; diff --git a/lib/feature/cart/presentation/pages/cart_page/cart_page.dart b/lib/feature/cart/presentation/pages/cart_page/cart_page.dart new file mode 100644 index 0000000..5e72435 --- /dev/null +++ b/lib/feature/cart/presentation/pages/cart_page/cart_page.dart @@ -0,0 +1,10 @@ +import '../../../../../food_delivery_client.dart'; + +class CartPage extends StatelessWidget { + const CartPage({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold(body: Column(children: [Center(child: Text("Cart"))])); + } +} diff --git a/lib/feature/common/presentation/widgets/app_switch_button.dart b/lib/feature/common/presentation/widgets/app_switch_button.dart new file mode 100644 index 0000000..33ce364 --- /dev/null +++ b/lib/feature/common/presentation/widgets/app_switch_button.dart @@ -0,0 +1,94 @@ +import 'package:flutter/material.dart'; +import 'package:food_delivery_client/core/core.dart'; + +class GradientSwitch extends StatefulWidget { + final bool value; + final ValueChanged onChanged; + final double width; + final double height; + final Duration duration; + + const GradientSwitch({ + super.key, + required this.value, + required this.onChanged, + this.width = 48, + this.height = 26, + this.duration = const Duration(milliseconds: 250), + }); + + @override + State createState() => _GradientSwitchState(); +} + +class _GradientSwitchState extends State + with SingleTickerProviderStateMixin { + late bool _isOn; + + @override + void initState() { + super.initState(); + _isOn = widget.value; + } + + @override + void didUpdateWidget(covariant GradientSwitch oldWidget) { + super.didUpdateWidget(oldWidget); + if (oldWidget.value != widget.value) { + _isOn = widget.value; + } + } + + void _toggle() { + setState(() => _isOn = !_isOn); + widget.onChanged(_isOn); + } + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: _toggle, + child: AnimatedContainer( + duration: widget.duration, + width: widget.width, + height: widget.height, + padding: const EdgeInsets.all(3), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(widget.height / 2), + gradient: _isOn + ? LinearGradient( + colors: [AppColors.cFF6F00, AppColors.cFFAB40], + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + ) + : null, + color: _isOn ? null : context.appThemeColors.inActiveColor2, + ), + child: Stack( + children: [ + AnimatedAlign( + duration: widget.duration, + alignment: _isOn ? Alignment.centerRight : Alignment.centerLeft, + curve: Curves.easeInOut, + child: Container( + width: widget.height - 4, + height: widget.height - 4, + decoration: BoxDecoration( + color: AppColors.cFFFFFF, + borderRadius: BorderRadius.circular(widget.height / 2), + boxShadow: [ + BoxShadow( + color: AppColors.c292F3D.newWithOpacity(.25), + blurRadius: 4, + offset: const Offset(0, 10), + ), + ], + ), + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/feature/common/presentation/widgets/widgets.dart b/lib/feature/common/presentation/widgets/widgets.dart index 4e67f74..5a1bcf8 100644 --- a/lib/feature/common/presentation/widgets/widgets.dart +++ b/lib/feature/common/presentation/widgets/widgets.dart @@ -6,3 +6,4 @@ export 'w_custom_modal_bottom_sheet.dart'; export 'app_button.dart'; export 'app_list_tile.dart'; export 'w_back_button.dart'; +export 'app_switch_button.dart'; diff --git a/lib/feature/discover/presentation/pages/descover_page/discover_page.dart b/lib/feature/discover/presentation/pages/descover_page/discover_page.dart new file mode 100644 index 0000000..295b562 --- /dev/null +++ b/lib/feature/discover/presentation/pages/descover_page/discover_page.dart @@ -0,0 +1,10 @@ +import '../../../../../food_delivery_client.dart'; + +class DiscoverPage extends StatelessWidget { + const DiscoverPage({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold(body: Column(children: [Center(child: Text("Discover"))])); + } +} diff --git a/lib/feature/home/presentation/pages/home_page/home_page.dart b/lib/feature/home/presentation/pages/home_page/home_page.dart new file mode 100644 index 0000000..5aa630b --- /dev/null +++ b/lib/feature/home/presentation/pages/home_page/home_page.dart @@ -0,0 +1,10 @@ +import '../../../../../food_delivery_client.dart'; + +class HomePage extends StatelessWidget { + const HomePage({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold(body: Column(children: [Center(child: Text("Home"))])); + } +} diff --git a/lib/feature/main/presentation/mixins/main_page_mixin.dart b/lib/feature/main/presentation/mixins/main_page_mixin.dart index e69de29..ef9d0fa 100644 --- a/lib/feature/main/presentation/mixins/main_page_mixin.dart +++ b/lib/feature/main/presentation/mixins/main_page_mixin.dart @@ -0,0 +1,26 @@ +import 'package:flutter/widgets.dart'; +import 'package:food_delivery_client/core/core.dart'; +import 'package:food_delivery_client/feature/discover/presentation/pages/descover_page/discover_page.dart'; +import 'package:food_delivery_client/feature/home/presentation/pages/home_page/home_page.dart'; +import 'package:food_delivery_client/feature/profile/presentation/pages/profile_page.dart'; +import 'package:food_delivery_client/feature/transactions/presentation/pages/transactions_page/transactions_page.dart'; + +import '../../../cart/presentation/pages/cart_page/cart_page.dart'; + +mixin MainPageMixins { + final List pages = [ + HomePage(), + DiscoverPage(), + CartPage(), + TransactionsPage(), + ProfilePage(), + ]; + + final List activeIcons = [ + AppIcons.icHome, + AppIcons.icDiscover, + AppIcons.icCart1, + AppIcons.icTransactions, + AppIcons.icProfile, + ]; +} diff --git a/lib/feature/main/presentation/pages/main_page/main_page.dart b/lib/feature/main/presentation/pages/main_page/main_page.dart index e69de29..e4d24f6 100644 --- a/lib/feature/main/presentation/pages/main_page/main_page.dart +++ b/lib/feature/main/presentation/pages/main_page/main_page.dart @@ -0,0 +1,68 @@ +import 'package:food_delivery_client/feature/main/presentation/pages/main_page/widgtes/w_bottom_navbar_item.dart'; + +import '../../../../../food_delivery_client.dart'; + +class MainPage extends StatelessWidget with MainPageMixins { + MainPage({super.key}); + + @override + Widget build(BuildContext context) { + final List inActiveIcons = [ + context.appThemeIcons.icHome, + context.appThemeIcons.icDiscover, + context.appThemeIcons.icCart1, + context.appThemeIcons.icTransactions, + context.appThemeIcons.icProfile, + ]; + final List titles = [ + context.loc.home, + context.loc.discover, + context.loc.cart, + context.loc.transactions, + context.loc.profile, + ]; + + return BlocProvider( + create: (context) => sl(), + child: BlocBuilder( + builder: (context, state) { + return Scaffold( + body: IndexedStack(index: state.currentIndex, children: pages), + bottomNavigationBar: DecoratedBox( + decoration: BoxDecoration( + color: context.appThemeColors.iconColor, + boxShadow: [ + BoxShadow( + blurStyle: BlurStyle.inner, + spreadRadius: 0, + color: AppColors.cA7AEC1.newWithOpacity(.15), + blurRadius: 80, + offset: const Offset(0, 4), + ), + ], + ), + child: BottomNavigationBar( + onTap: (value) { + context.read().add(MainEvent.loaded(value)); + }, + currentIndex: state.currentIndex, + items: List.generate(titles.length, (index) { + return BottomNavigationBarItem( + label: titles[index], + tooltip: "", + icon: WBottomNavbarItem( + iconPath: inActiveIcons[index], + activeIconPath: activeIcons[index], + title: titles[index], + isActive: index == state.currentIndex, + ), + ); + }), + ), + ), + ); + }, + ), + ); + } +} diff --git a/lib/feature/main/presentation/pages/main_page/widgtes/w_bottom_navbar_item.dart b/lib/feature/main/presentation/pages/main_page/widgtes/w_bottom_navbar_item.dart new file mode 100644 index 0000000..0790b70 --- /dev/null +++ b/lib/feature/main/presentation/pages/main_page/widgtes/w_bottom_navbar_item.dart @@ -0,0 +1,56 @@ +import '../../../../../../food_delivery_client.dart'; + +class WBottomNavbarItem extends StatelessWidget { + const WBottomNavbarItem({ + super.key, + required this.iconPath, + required this.activeIconPath, + required this.title, + required this.isActive, + }); + + final String iconPath; + final String activeIconPath; + final String title; + final bool isActive; + + @override + Widget build(BuildContext context) { + return Column( + children: [ + SizedBox( + height: 24, + width: 24, + child: SvgPicture.asset( + isActive ? activeIconPath : iconPath, + fit: BoxFit.cover, + ), + ), + 8.verticalSpace, + if (!isActive) + Text( + title, + style: AppTextStyles.size12Medium.copyWith( + height: 1.3, + color: context.appThemeColors.inActiveColor1, + ), + ), + if (isActive) + ShaderMask( + shaderCallback: (bounds) => AppUtils.kGradient.createShader( + Rect.fromLTWH(0, 0, bounds.width, bounds.height), + ), + child: Text( + title, + style: AppTextStyles.size12Medium.copyWith( + height: 1.3, + color: isActive + ? AppColors.cFFFFFF + : context.appThemeColors.inActiveColor1, + ), + ), + ), + ], + ); + } +} diff --git a/lib/feature/onboarding/presentation/blocs/splash_bloc/splash_bloc.dart b/lib/feature/onboarding/presentation/blocs/splash_bloc/splash_bloc.dart index f6a201b..03921cf 100644 --- a/lib/feature/onboarding/presentation/blocs/splash_bloc/splash_bloc.dart +++ b/lib/feature/onboarding/presentation/blocs/splash_bloc/splash_bloc.dart @@ -19,7 +19,7 @@ class SplashBloc extends Bloc { final token = _storageService.getString(key: AppLocaleKeys.token); log("Token:$token"); if (token != null) { - emit(state.copyWith(status: RequestStatus.error)); + emit(state.copyWith(status: RequestStatus.loaded)); } else { emit(state.copyWith(status: RequestStatus.error)); } diff --git a/lib/feature/onboarding/presentation/pages/splash_page/splash_page.dart b/lib/feature/onboarding/presentation/pages/splash_page/splash_page.dart index 1d4d2eb..8270c44 100644 --- a/lib/feature/onboarding/presentation/pages/splash_page/splash_page.dart +++ b/lib/feature/onboarding/presentation/pages/splash_page/splash_page.dart @@ -14,6 +14,10 @@ class SplashPage extends StatelessWidget { if (state.status.isError()) { context.go(Routes.onBoarding); } + + if (state.status.isLoaded()) { + context.go(Routes.main); + } }, child: WLayout( bottom: false, diff --git a/lib/feature/profile/presentation/pages/profile_page.dart b/lib/feature/profile/presentation/pages/profile_page.dart new file mode 100644 index 0000000..c0d9d32 --- /dev/null +++ b/lib/feature/profile/presentation/pages/profile_page.dart @@ -0,0 +1,21 @@ +import '../../../../../food_delivery_client.dart'; + +class ProfilePage extends StatelessWidget { + const ProfilePage({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text("Home"), + GradientSwitch(value:false, onChanged: (value) { + print(value); + }), + ], + ), + ); + } +} diff --git a/lib/feature/transactions/presentation/pages/transactions_page/transactions_page.dart b/lib/feature/transactions/presentation/pages/transactions_page/transactions_page.dart new file mode 100644 index 0000000..05222e3 --- /dev/null +++ b/lib/feature/transactions/presentation/pages/transactions_page/transactions_page.dart @@ -0,0 +1,12 @@ +import '../../../../../food_delivery_client.dart'; + +class TransactionsPage extends StatelessWidget { + const TransactionsPage({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Column(children: [Center(child: Text("transactions"))]), + ); + } +}