diff --git a/assets/language/ar.json b/assets/language/ar.json index cefa218..92a4dc0 100644 --- a/assets/language/ar.json +++ b/assets/language/ar.json @@ -11,7 +11,7 @@ "signUpText": "اشتراك", "welcomeText": "مرحبا بعودتك!", "pleaseEnterLoginDetails": "يرجى إدخال تفاصيل تسجيل الدخول الخاصة بك للبدء", - "toGetYourAccountPleaseSetYourInfo": "للحصول على حسابك، يرجى تحديد معلوماتك", + "toGetYourAccountPleaseSetYourInfo": "للحصول على حسابك، يرجى تحديد معلوماتك", "countryOfResidence": "بلد الإقامة", "chooseCountry": "اختر الدولة", "phoneNumber": "رقم الهاتف", @@ -245,6 +245,14 @@ "tryAgainText": "حاول مرة اخرى", "investmentConfirmationText": "تأكيد الاستثمار", "enterAmountText": "أدخل المبلغ", - "pleaseEnterAmountText": "الرجاء إدخال المبلغ" + "pleaseEnterAmountText": "الرجاء إدخال المبلغ", + "authenticationFailedText" : "المصادقة فشلت", + "pleaseAuthenticateToAccessTheApp" : "يرجى المصادقة للوصول إلى التطبيق", + "masterPinAddedSucessfullyText" : "تمت إضافة الدبوس الرئيسي بنجاح", + "passwordChangedSucessfully" : "تم تغيير الرقم السري بنجاح!", + "passwordResetSucessful" : "تمت إعادة تعيين كلمة المرور بنجاح!", + "otpSendSuccessfulText" : "تم إرسال OTP بنجاح!", + "successfulText" : "ناجح !", + "portfolioBottomText" : "مَلَفّ" } \ No newline at end of file diff --git a/assets/language/en.json b/assets/language/en.json index 1630cae..5e32c29 100644 --- a/assets/language/en.json +++ b/assets/language/en.json @@ -79,7 +79,7 @@ "resendSms": "Resend SMS", "otpVerifiedSucessfully": "OTP Verified Successfully!", "otpVerifiedFailed": "OTP Verification Failed:", - "pinCode": "Pin Code", + "pinCode": "Pin Code", "createPinCode": "Create Pin Code", "changePinCode": "Change Pin Code", "confirmPinCode": "Confirm Pin Code", @@ -245,6 +245,14 @@ "tryAgainText": "Try again", "investmentConfirmationText": "Investment confirmation", "enterAmountText": "Enter Amount", - "pleaseEnterAmountText": "Please Enter Amount" + "pleaseEnterAmountText": "Please Enter Amount", + "authenticationFailedText" : "Authentication failed", + "pleaseAuthenticateToAccessTheApp" : "Please authenticate to access the app", + "masterPinAddedSucessfullyText" : "Master pin added sucessfully", + "passwordChangedSucessfully" : "Password changed successfully!", + "passwordResetSucessful" : "Password reset successful!", + "otpSendSuccessfulText" : "OTP send successful !", + "successfulText" : "successful !", + "portfolioBottomText" : "Portfolio" } \ No newline at end of file diff --git a/lib/core/styles/app_text.dart b/lib/core/styles/app_text.dart index 2f7a5aa..b4da19c 100644 --- a/lib/core/styles/app_text.dart +++ b/lib/core/styles/app_text.dart @@ -37,6 +37,9 @@ class AppText { "Password must contain at least one digit."; static const String passwordSpecialCharacter = "Password must contain at least one special character (!@#\$%&*()-+=^)."; + static const String authenticationFailedText = "authenticationFailedText"; + static const String pleaseAuthenticateToAccessTheApp = + "pleaseAuthenticateToAccessTheApp"; //Register static const String getStartedToday = "getStartedToday"; @@ -73,6 +76,7 @@ class AppText { static const String termsAndCondition = "termsAndCondition"; static const String andThe = "andThe"; static const String privacyPolicy = "privacyPolicy"; + static const String successfulText = "successfulText"; //Country Name static const String bahrainCountryText = "Bahrain"; @@ -91,6 +95,7 @@ class AppText { static const String totalreturn = "totalreturn"; static const String disttodate = "disttodate"; static const String includeddocs = "includeddocs"; + static const String portfolioBottomText = "portfolioBottomText"; //Academy static const String videosTitle = "videosTitle"; @@ -118,6 +123,7 @@ class AppText { static const String resendSms = "resendSms"; static const String otpVerifiedSucessfully = "otpVerifiedSucessfully"; static const String otpVerifiedFailed = "otpVerifiedFailed"; + static const String otpSendSuccessfulText = "otpSendSuccessfulText"; //Pin Code static const String pinCode = "pinCode"; @@ -135,17 +141,19 @@ class AppText { "toRestorePinYouWillBeLoggedOut"; static const String allowText = "allowText"; static const String declineText = "declineText"; + static const String masterPinAddedSucessfullyText = + "masterPinAddedSucessfullyText"; //Forgot Password static const String almostHere = "almostHere"; static const String completeAcc = "completeAcc"; - - //Forgot Password static const String restorePasswordText = "restorePasswordText"; static const String toRestorePasswordPleaseEnterPhoneNumber = "toRestorePasswordPleaseEnterPhoneNumber"; static const String createNewPasswordText = "createNewPasswordText"; static const String submitText = "submitText"; + static const String passwordChangedSucessfully = "passwordChangedSucessfully"; + static const String passwordResetSucessful = "passwordResetSucessful"; //Wallet static const String walletTitle = "walletTitle"; diff --git a/lib/core/utils/phone_number_hint_generator/phone_number_hint_generator.dart b/lib/core/utils/phone_number_hint_generator/phone_number_hint_generator.dart index 1bd49a7..c032963 100644 --- a/lib/core/utils/phone_number_hint_generator/phone_number_hint_generator.dart +++ b/lib/core/utils/phone_number_hint_generator/phone_number_hint_generator.dart @@ -26,5 +26,6 @@ class PhoneNumberHintGenerator { "+974": 8, // Qatar "+966": 9, // Saudi Arabia "+971": 9, // United Arab Emirates + "+91": 10, }; } diff --git a/lib/features/biometric/domain/repository/biometric_api.dart b/lib/features/biometric/domain/repository/biometric_api.dart new file mode 100644 index 0000000..822633d --- /dev/null +++ b/lib/features/biometric/domain/repository/biometric_api.dart @@ -0,0 +1,12 @@ +import '../../../../Api_Helper/base_manager.dart'; +import '../../../../shared/api/api_endpoints.dart'; +import '../../../../shared/api/network_api_services.dart'; + +class BiometricAPIServices { + BiometricAPIServices(); + Future biometricLoginApi(Map data) async { + String url = ApiEndpoints.biometricLoginapi; + final response = await NetworkApiService().post(url, data); + return response; + } +} diff --git a/lib/features/biometric/presentation/bloc/biometric_bloc.dart b/lib/features/biometric/presentation/bloc/biometric_bloc.dart index ac8deef..10f9fab 100644 --- a/lib/features/biometric/presentation/bloc/biometric_bloc.dart +++ b/lib/features/biometric/presentation/bloc/biometric_bloc.dart @@ -2,14 +2,19 @@ import 'dart:io'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:local_auth/local_auth.dart'; +import 'package:tanami_app/core/utils/secure/secure_storage_service.dart'; +import 'package:tanami_app/features/biometric/domain/repository/biometric_api.dart'; +import '../../../../Api_Helper/base_manager.dart'; import 'biometric_event.dart'; import 'biometric_state.dart'; class BiometricBloc extends Bloc { final LocalAuthentication localAuthentication; + final SecureStorageService secureStorageService; - BiometricBloc(this.localAuthentication) : super(BiometricInitial()) { + BiometricBloc(this.localAuthentication, this.secureStorageService) + : super(BiometricInitial()) { on(_onCheckBiometric); on(_onAuthenticateBiometric); } @@ -46,7 +51,21 @@ class BiometricBloc extends Bloc { } if (authenticated) { - emit(BiometricAuthenticated()); + Map biometricLoginData = { + "token": await secureStorageService.read("temp_token"), + }; + + ResponseData response = + await BiometricAPIServices().biometricLoginApi(biometricLoginData); + if (response.status == ResponseStatus.SUCCESS) { + await secureStorageService.write( + 'accesstoken', response.data["data"]["accessToken"]); + await secureStorageService.write( + 'refreshtoken', response.data["data"]["refreshToken"]); + emit(BiometricAuthenticated()); + } else { + emit(BiometricFailed('Authentication failed')); + } } else { emit(BiometricFailed('Authentication failed')); } diff --git a/lib/features/biometric/presentation/pages/biometric_layout.dart b/lib/features/biometric/presentation/pages/biometric_layout.dart index 8f94d74..f882ada 100644 --- a/lib/features/biometric/presentation/pages/biometric_layout.dart +++ b/lib/features/biometric/presentation/pages/biometric_layout.dart @@ -36,7 +36,6 @@ class BiometricLayout extends StatelessWidget { deviceLockedDialog(context); } else if (state is BiometricAuthenticated) { await secureStorageService.write('isLoginedIn', "true"); - // successToastMessage(context, "Authentication Successful"); goRouter.goNamed(RouteName.mainScreen); } }, diff --git a/lib/features/changePassword/presentation/widgets/change_password_bottom_section.dart b/lib/features/changePassword/presentation/widgets/change_password_bottom_section.dart index f537bd4..b20bf0c 100644 --- a/lib/features/changePassword/presentation/widgets/change_password_bottom_section.dart +++ b/lib/features/changePassword/presentation/widgets/change_password_bottom_section.dart @@ -30,7 +30,8 @@ class RestorePasswordBottomSection extends StatelessWidget { if (state is ChangePasswordLoading) { Loader.loader(context); } else if (state is ChangePasswordSuccess) { - successToastMessage(context, "Password changed successful !"); + successToastMessage(context, + localizations.translate(AppText.passwordChangedSucessfully)); goRouter.pop(); goRouter.pop(); } else if (state is ChangePasswordFailure) { diff --git a/lib/features/countrySelection/presentation/pages/choose_country_layout.dart b/lib/features/countrySelection/presentation/pages/choose_country_layout.dart index a37d19b..86eeb7b 100644 --- a/lib/features/countrySelection/presentation/pages/choose_country_layout.dart +++ b/lib/features/countrySelection/presentation/pages/choose_country_layout.dart @@ -27,7 +27,6 @@ class ChooseCountryLayout extends StatelessWidget { child: ButtonWidget().elevatedBtn( txtClr: AppColor.plainWhite, function: () { - print("//"); goRouter.pop(); }, text: localizations.translate(AppText.confirmSelectionText), diff --git a/lib/features/forgotPassword/presentation/widgets/restore_password_bottom_section.dart b/lib/features/forgotPassword/presentation/widgets/restore_password_bottom_section.dart index 4d98022..c0423b7 100644 --- a/lib/features/forgotPassword/presentation/widgets/restore_password_bottom_section.dart +++ b/lib/features/forgotPassword/presentation/widgets/restore_password_bottom_section.dart @@ -33,7 +33,8 @@ class RestorePasswordBottomSection extends StatelessWidget { if (state is RestorePasswordLoading) { Loader.loader(context); } else if (state is RestorePasswordSuccess) { - successToastMessage(context, "Password resetted successful !"); + successToastMessage(context, + localizations.translate(AppText.passwordResetSucessful)); goRouter.pop(); radioBloc.resetSelection(); goRouter.goNamed(RouteName.loginScreen, pathParameters: { diff --git a/lib/features/forgotPassword/presentation/widgets/restore_password_form.dart b/lib/features/forgotPassword/presentation/widgets/restore_password_form.dart index 92566fe..d6cbe3c 100644 --- a/lib/features/forgotPassword/presentation/widgets/restore_password_form.dart +++ b/lib/features/forgotPassword/presentation/widgets/restore_password_form.dart @@ -35,7 +35,7 @@ class RestorePasswordForm extends StatelessWidget { create: (_) => PasswordVisibilityBloc(), child: FormLabelTextField( hintText: localizations.translate(AppText.enterPassword), - title: "New Password", + title: localizations.translate(AppText.newPasswordText), type: AppText.password.toLowerCase(), textEditingController: restorePasswordBloc.passwordTextField, ), diff --git a/lib/features/forgotPassword/presentation/widgets/restore_password_phone_verification_bottom_section.dart b/lib/features/forgotPassword/presentation/widgets/restore_password_phone_verification_bottom_section.dart index 39e4209..ba1f62d 100644 --- a/lib/features/forgotPassword/presentation/widgets/restore_password_phone_verification_bottom_section.dart +++ b/lib/features/forgotPassword/presentation/widgets/restore_password_phone_verification_bottom_section.dart @@ -36,7 +36,8 @@ class RestorePasswordPhoneVerificationBottomSection extends StatelessWidget { if (state is RestorePasswordPhoneVerificationLoading) { Loader.loader(context); } else if (state is RestorePasswordPhoneVerificationSuccess) { - successToastMessage(context, "OTP send successful !"); + successToastMessage(context, + localizations.translate(AppText.otpSendSuccessfulText)); goRouter.pop(); radioBloc.resetSelection(); goRouter.pushNamed(RouteName.otpScreen, diff --git a/lib/features/login/presentation/bloc/login_bloc.dart b/lib/features/login/presentation/bloc/login_bloc.dart index 8277b87..2829012 100644 --- a/lib/features/login/presentation/bloc/login_bloc.dart +++ b/lib/features/login/presentation/bloc/login_bloc.dart @@ -54,6 +54,8 @@ class LoginBloc extends Bloc { await secureStorageService.write( 'temp_token', response.data['data']['user']); emit(LoginMasterPinPending()); + } else { + emit(LoginFailure(response.message.toString())); } } else { emit(const LoginFailure( diff --git a/lib/features/otpVerification/bloc/otp_bloc.dart b/lib/features/otpVerification/bloc/otp_bloc.dart index 021cb28..949c763 100644 --- a/lib/features/otpVerification/bloc/otp_bloc.dart +++ b/lib/features/otpVerification/bloc/otp_bloc.dart @@ -21,27 +21,8 @@ class OTPBloc extends Bloc { } else { emit(OTPFailed("Oops something went wrong")); } - print("//"); } catch (e) { emit(OTPError("Oops something went wrong")); } } - - /* Future VerifyOTPCall( - GetCountry event, Emitter emit) async { - if (event is GetCountry) { - emit(CountryLoading()); - try { - ResponseData response = await GetCountryAPI().getcountryAPI(); - if (response.status == ResponseStatus.SUCCESS) { - GetCountryModel countryModel = - GetCountryModel.fromJson(response.data); - emit(CountryLoaded(countryModel)); - } - print("//"); - } catch (e) { - emit(CountryError("Oops Something went wrong")); - } - } - } */ } diff --git a/lib/features/otpVerification/presentation/widgets/resend_otp_section.dart b/lib/features/otpVerification/presentation/widgets/resend_otp_section.dart index 742e8bd..07f921a 100644 --- a/lib/features/otpVerification/presentation/widgets/resend_otp_section.dart +++ b/lib/features/otpVerification/presentation/widgets/resend_otp_section.dart @@ -33,21 +33,19 @@ class ResendOtpSection extends StatelessWidget { loginBloc.phoneNumberTextField.text = Globalconst.phonenumber; loginBloc.countrySelectionTextField.text = Globalconst.name; var localizations = AppLocalizations.of(context); - final SecureStorageService secureStorageService = SecureStorageService(); return BlocBuilder( - builder: (context, state) { + builder: (context, timerState) { return Padding( padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ TextWidget().text14W500( - state.formattedDuration, + timerState.formattedDuration, clr: AppColor.plainBlack, ), BlocConsumer( listener: (context, state) { - print(loginBloc.state); if (state is RegisterLoading) { Loader.loader(context); } else if (state is RegisterSuccess) { @@ -72,12 +70,14 @@ class ResendOtpSection extends StatelessWidget { } return GestureDetector( onTap: () { - loginBloc.add( - Resendotp(token), - ); - print("///"); - - // successToastMessage(context, "OTP Resend Sucessfully !"); + if (timerState is TimerRunComplete) { + loginBloc.add( + Resendotp(token), + ); + } else { + errorToastMessage(context, + "Please wait ${timerState.formattedDuration} Minutes before resending OTP"); + } }, child: TextWidget().text14W500( localizations.translate(AppText.resendSms), @@ -89,24 +89,6 @@ class ResendOtpSection extends StatelessWidget { ); }, ), - /* GestureDetector( - onTap: () { - regbloc.add( - RegisterSubmitted( - loginBloc.phoneNumberTextField.text, - loginBloc.countrySelectionTextField.text, - loginBloc.isdcode - ), - ); - print("///"); - // successToastMessage(context, "OTP Resend Sucessfully !"); - }, - child: TextWidget().text14W500( - localizations.translate(AppText.resendSms), - clr: AppColor.plainBlack, - textDecoration: TextDecoration.underline, - ), - ) */ ], ), ); diff --git a/lib/features/register/presentation/bloc/register_bloc.dart b/lib/features/register/presentation/bloc/register_bloc.dart index c3b0c7f..221f04d 100644 --- a/lib/features/register/presentation/bloc/register_bloc.dart +++ b/lib/features/register/presentation/bloc/register_bloc.dart @@ -53,7 +53,7 @@ class RegisterBloc extends Bloc { emit(RegisterLoading()); try { Map requestdata = { - "token": secureStorageService.read('temp_token'), + "token": await secureStorageService.read('temp_token'), }; ResponseData response = await OTPAPI().resendOTPRequest(requestdata); if (response.status == ResponseStatus.SUCCESS) { diff --git a/lib/features/register/presentation/widgets/register_bottom_section.dart b/lib/features/register/presentation/widgets/register_bottom_section.dart index 7c684ea..4f12cf0 100644 --- a/lib/features/register/presentation/widgets/register_bottom_section.dart +++ b/lib/features/register/presentation/widgets/register_bottom_section.dart @@ -39,11 +39,11 @@ class RegisterBottomSection extends StatelessWidget { const Gap(36), BlocConsumer( listener: (context, state) { - print(loginBloc.state); if (state is RegisterLoading) { Loader.loader(context); } else if (state is RegisterSuccess) { - successToastMessage(context, "successful !"); + successToastMessage( + context, localizations.translate(AppText.successfulText)); goRouter.pop(); goRouter.pushNamed(RouteName.otpScreen, diff --git a/lib/features/securePin/presentation/bloc/pin_bloc.dart b/lib/features/securePin/presentation/bloc/pin_bloc.dart index 367d884..bb50deb 100644 --- a/lib/features/securePin/presentation/bloc/pin_bloc.dart +++ b/lib/features/securePin/presentation/bloc/pin_bloc.dart @@ -3,6 +3,7 @@ import 'package:equatable/equatable.dart'; import 'package:tanami_app/Api_Helper/base_manager.dart'; import 'package:tanami_app/core/styles/app_text.dart'; +import '../../../../core/routes/routes.dart'; import '../../../../core/utils/secure/secure_storage_service.dart'; import '../../Repository/PinAPIServices.dart'; @@ -71,6 +72,7 @@ class PinBloc extends Bloc { }); on((event, emit) async { + emit(const PinLoading()); final storedPin = await secureStorageService.read('pin_code'); Map pindata = { "token": await secureStorageService.read("temp_token"), @@ -82,8 +84,13 @@ class PinBloc extends Bloc { await secureStorageService.write('userMPIN', storedPin.toString()); } - emit(state.copyWith(isVerified: true, error: '', verifiedOnce: true)); + emit(state.copyWith( + isVerified: true, + error: '', + verifiedOnce: true, + pinComplete: true)); } else { + goRouter.pop(); emit(state.copyWith( isVerified: false, error: AppText.incorrectPinCode, @@ -93,6 +100,7 @@ class PinBloc extends Bloc { }); on((event, emit) async { + emit(const PinLoading()); Map pindata = { "token": await secureStorageService.read("temp_token"), "masterPin": event.pin @@ -100,6 +108,10 @@ class PinBloc extends Bloc { ResponseData response = await PinAPIServices().Verifypin(pindata); if (response.status == ResponseStatus.SUCCESS) { + await secureStorageService.write( + 'accesstoken', response.data["data"]["accessToken"]); + await secureStorageService.write( + 'refreshtoken', response.data["data"]["refreshToken"]); emit(state.copyWith( pinComplete: true, pin: state.pin, @@ -107,6 +119,7 @@ class PinBloc extends Bloc { error: '', verifiedOnce: false)); } else { + goRouter.pop(); emit(state.copyWith( pinComplete: true, pin: state.pin, diff --git a/lib/features/securePin/presentation/bloc/pin_state.dart b/lib/features/securePin/presentation/bloc/pin_state.dart index 549d5fb..aa864a0 100644 --- a/lib/features/securePin/presentation/bloc/pin_state.dart +++ b/lib/features/securePin/presentation/bloc/pin_state.dart @@ -34,3 +34,13 @@ class PinState extends Equatable { @override List get props => [pin, pinComplete, isVerified, error, verifiedOnce]; } + +class PinLoading extends PinState { + const PinLoading() + : super( + pin: '', + pinComplete: false, + isVerified: false, + error: '', + verifiedOnce: false); +} diff --git a/lib/features/securePin/presentation/widgets/confirm_pin_keypad_section.dart b/lib/features/securePin/presentation/widgets/confirm_pin_keypad_section.dart index a1d8936..fbf0fc7 100644 --- a/lib/features/securePin/presentation/widgets/confirm_pin_keypad_section.dart +++ b/lib/features/securePin/presentation/widgets/confirm_pin_keypad_section.dart @@ -4,9 +4,13 @@ import 'package:gap/gap.dart'; import 'package:tanami_app/core/routes/route_name.dart'; import 'package:tanami_app/core/routes/routes.dart'; import 'package:tanami_app/core/styles/app_color.dart'; +import 'package:tanami_app/core/styles/app_text.dart'; import 'package:tanami_app/core/utils/secure/secure_storage_service.dart'; import 'package:tanami_app/shared/components/text_widget.dart'; +import 'package:tanami_app/shared/components/toast_message.dart'; +import '../../../../core/utils/language/localizations_delegate.dart'; +import '../../../../shared/components/loader.dart'; import '../bloc/pin_bloc.dart'; class ConfirmPinKey extends StatelessWidget { @@ -14,13 +18,22 @@ class ConfirmPinKey extends StatelessWidget { @override Widget build(BuildContext context) { + var localizations = AppLocalizations.of(context); final SecureStorageService secureStorageService = SecureStorageService(); return Column( children: [ const Gap(20), BlocConsumer( listener: (context, state) async { + if (state is PinLoading) { + Loader.loader(context); + } if (state.pinComplete && state.isVerified) { + goRouter.pop(); + successToastMessage( + context, + localizations + .translate(AppText.masterPinAddedSucessfullyText)); await secureStorageService.write('isLoginedIn', "true"); goRouter.goNamed(RouteName.mainScreen); } diff --git a/lib/features/securePin/presentation/widgets/pin_keypad_section.dart b/lib/features/securePin/presentation/widgets/pin_keypad_section.dart index eaa3524..5798bc3 100644 --- a/lib/features/securePin/presentation/widgets/pin_keypad_section.dart +++ b/lib/features/securePin/presentation/widgets/pin_keypad_section.dart @@ -10,6 +10,7 @@ import 'package:tanami_app/shared/components/text_widget.dart'; import '../../../../core/routes/route_name.dart'; import '../../../../core/routes/routes.dart'; import '../../../../core/utils/language/localizations_delegate.dart'; +import '../../../../shared/components/loader.dart'; import '../../../../shared/components/toast_message.dart'; import '../../../login/presentation/bloc/login_bloc.dart'; import '../bloc/pin_bloc.dart'; @@ -32,10 +33,14 @@ class PinKey extends StatelessWidget { const Gap(20), BlocConsumer( listener: (context, state) { + if (state is PinLoading) { + Loader.loader(context); + } if (state.pinComplete && state.error.isEmpty && !state.verifiedOnce) { if (fromScreen == "login" || fromScreen == "LoginedInUser") { + goRouter.pop(); loginBloc.resetFields(); radioBloc.resetSelection(); successToastMessage(context, @@ -46,10 +51,12 @@ class PinKey extends StatelessWidget { context, localizations.translate(AppText.pinUpdatedSucess)); goRouter.pop(); } else { + goRouter.pop(); context.read().add(SavePinPressed()); goRouter.pushNamed(RouteName.confirmPinScreen); } } else { + // goRouter.pop(); if (state.pinComplete) { errorToastMessage( context, diff --git a/lib/features/welcome/presentation/pages/weclome_screen.dart b/lib/features/welcome/presentation/pages/weclome_screen.dart index 82aafa3..b9505fd 100644 --- a/lib/features/welcome/presentation/pages/weclome_screen.dart +++ b/lib/features/welcome/presentation/pages/weclome_screen.dart @@ -3,6 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:tanami_app/features/welcome/presentation/pages/welcome_layout.dart'; import '../../../../core/styles/app_color.dart'; +import '../../../../shared/components/exit_app_dialog.dart'; import '../bloc/onboarding_bloc.dart'; class WelcomeScreen extends StatelessWidget { @@ -10,17 +11,23 @@ class WelcomeScreen extends StatelessWidget { @override Widget build(BuildContext context) { - return Scaffold( - backgroundColor: AppColor.plainWhite, - body: MultiBlocProvider( - // Define the providers for the OnboardingBloc and other blocs - providers: [ - BlocProvider( - // Create an instance of the OnboardingBloc - create: (_) => OnboardingBloc(), - ), - ], - child: WelcomeLayout(), + return WillPopScope( + onWillPop: () async { + exitAppDialog(context); + return false; + }, + child: Scaffold( + backgroundColor: AppColor.plainWhite, + body: MultiBlocProvider( + // Define the providers for the OnboardingBloc and other blocs + providers: [ + BlocProvider( + // Create an instance of the OnboardingBloc + create: (_) => OnboardingBloc(), + ), + ], + child: WelcomeLayout(), + ), ), ); } diff --git a/lib/main.dart b/lib/main.dart index 76f4805..1639670 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -107,8 +107,10 @@ class _MyAppState extends State with WidgetsBindingObserver { create: (_) => LoginBloc(secureStorageService: secureStorageService), ), BlocProvider( - create: (_) => - BiometricBloc(LocalAuthentication())..add(CheckBiometricEvent()), + create: (_) => BiometricBloc( + LocalAuthentication(), + secureStorageService, + )..add(CheckBiometricEvent()), ), BlocProvider( create: (_) => LocalizationBloc(), diff --git a/lib/shared/api/api_endpoints.dart b/lib/shared/api/api_endpoints.dart index b1a9d9c..c7cf4d8 100644 --- a/lib/shared/api/api_endpoints.dart +++ b/lib/shared/api/api_endpoints.dart @@ -16,6 +16,7 @@ class ApiEndpoints { //Biometric static const biometricUpdateapi = "${baseurl}auth/public/biometric-update"; + static const biometricLoginapi = "${baseurl}auth/public/biometric-login"; //PIN static const confirmpinapi = "${baseurl}auth/public/masterPin"; diff --git a/lib/shared/api/network_api_services.dart b/lib/shared/api/network_api_services.dart index f12b3b8..2d1423b 100644 --- a/lib/shared/api/network_api_services.dart +++ b/lib/shared/api/network_api_services.dart @@ -76,6 +76,10 @@ class NetworkApiService { response.data['error']['message'], ResponseStatus.PRIVATE, data: response.data); } + } else if (response.statusCode == 401) { + return ResponseData( + response.data['error']['message'], ResponseStatus.PRIVATE, + data: response.data); } else { try { return ResponseData( diff --git a/lib/shared/components/common_bottom_navigation.dart b/lib/shared/components/common_bottom_navigation.dart index 7d3f6e4..728350e 100644 --- a/lib/shared/components/common_bottom_navigation.dart +++ b/lib/shared/components/common_bottom_navigation.dart @@ -3,6 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:tanami_app/core/styles/app_color.dart'; +import 'package:tanami_app/core/styles/app_text.dart'; import '../../core/utils/language/localizations_delegate.dart'; import 'bloc/bottom_nav_bar/bottom_navigation_bloc.dart'; @@ -45,7 +46,7 @@ Widget bottomnavigationbar( height: 30.h, width: 30.w, ), - label: localizations.translate('Wallet'), + label: localizations.translate(AppText.walletText), ), BottomNavigationBarItem( icon: Image.asset( @@ -58,7 +59,7 @@ Widget bottomnavigationbar( height: 30.h, width: 30.w, ), - label: localizations.translate('Portfolio'), + label: localizations.translate(AppText.portfolioBottomText), ), BottomNavigationBarItem( icon: Image.asset( @@ -71,7 +72,7 @@ Widget bottomnavigationbar( height: 28.h, width: 28.w, ), - label: localizations.translate('Invest'), + label: localizations.translate(AppText.investText), ), BottomNavigationBarItem( icon: Image.asset( @@ -84,7 +85,7 @@ Widget bottomnavigationbar( height: 30.h, width: 30.w, ), - label: localizations.translate('Academy'), + label: localizations.translate(AppText.academyText), ), BottomNavigationBarItem( icon: Image.asset( @@ -97,7 +98,7 @@ Widget bottomnavigationbar( height: 30.h, width: 30.w, ), - label: localizations.translate('Settings'), + label: localizations.translate(AppText.settingsText), ), ], ); diff --git a/lib/shared/components/form_label_textfield.dart b/lib/shared/components/form_label_textfield.dart index 3f978ea..593cacc 100644 --- a/lib/shared/components/form_label_textfield.dart +++ b/lib/shared/components/form_label_textfield.dart @@ -44,6 +44,7 @@ class FormLabelTextField extends StatelessWidget { "+974": 8, // Qatar "+966": 9, // Saudi Arabia "+971": 9, // United Arab Emirates + "+91": 10, }; var registerBloc = context.read(); var loginBloc = context.read(); diff --git a/lib/shared/components/language_change_bottom_sheet.dart b/lib/shared/components/language_change_bottom_sheet.dart index c57081f..c8d464d 100644 --- a/lib/shared/components/language_change_bottom_sheet.dart +++ b/lib/shared/components/language_change_bottom_sheet.dart @@ -1,11 +1,18 @@ import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:gap/gap.dart'; import 'package:tanami_app/core/routes/routes.dart'; import 'package:tanami_app/core/styles/app_color.dart'; +import 'package:tanami_app/core/utils/secure/secure_storage_service.dart'; +import 'package:tanami_app/features/welcome/presentation/pages/weclome_screen.dart'; import 'package:tanami_app/shared/components/text_widget.dart'; +import 'bloc/language/lng_bloc.dart'; +import 'bloc/language/lng_event.dart'; + void showLanguageBottomSheet(BuildContext context) { + final SecureStorageService secureStorageService = SecureStorageService(); showModalBottomSheet( backgroundColor: Colors.transparent, context: context, @@ -34,8 +41,16 @@ void showLanguageBottomSheet(BuildContext context) { ), const Gap(10), InkWell( - onTap: () { + onTap: () async { + context + .read() + .add(const ChangeLanguage(Locale('en'))); + + await secureStorageService.write( + 'languageSelected', "en"); goRouter.pop(); + Navigator.of(context).push(MaterialPageRoute( + builder: (_) => const WelcomeScreen())); }, child: Center( child: @@ -48,8 +63,16 @@ void showLanguageBottomSheet(BuildContext context) { ), const Gap(10), InkWell( - onTap: () { + onTap: () async { + context + .read() + .add(const ChangeLanguage(Locale('ar'))); + + await secureStorageService.write( + 'languageSelected', "ar"); goRouter.pop(); + Navigator.of(context).push(MaterialPageRoute( + builder: (_) => const WelcomeScreen())); }, child: Center( child: TextWidget().text15W700("عربي", clr: Colors.white), diff --git a/lib/shared/components/permission_dialog.dart b/lib/shared/components/permission_dialog.dart index f71e77d..3cce34d 100644 --- a/lib/shared/components/permission_dialog.dart +++ b/lib/shared/components/permission_dialog.dart @@ -3,6 +3,7 @@ import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:gap/gap.dart'; import 'package:tanami_app/Api_Helper/base_manager.dart'; import 'package:tanami_app/core/styles/app_color.dart'; +import 'package:tanami_app/shared/components/loader.dart'; import '../../core/routes/route_name.dart'; import '../../core/routes/routes.dart'; @@ -109,6 +110,7 @@ permissionDialog( ), GestureDetector( onTap: () async { + Loader.loader(context); Map biometricdata = { "token": await secureStorageService.read("temp_token"), @@ -118,16 +120,19 @@ permissionDialog( ResponseData response = await RegisterAPIService() .BiometricUpdate(biometricdata); if (response.status == ResponseStatus.SUCCESS) { - await secureStorageService.write("biometric", 'on'); - } - successToastMessage( - context, "Biometric/Face Id Enabled Sucessfully !"); - // successToastMessage(context, "successful !"); - goRouter.pop(); + goRouter.pop(); - goRouter.goNamed(RouteName.pinScreen, pathParameters: { - "fromScreen": "register", - }); + await secureStorageService.write("biometric", 'on'); + successToastMessage(context, + "Biometric/Face Id Enabled Sucessfully !"); + // successToastMessage(context, "successful !"); + goRouter.pop(); + + goRouter + .goNamed(RouteName.pinScreen, pathParameters: { + "fromScreen": "register", + }); + } }, child: SizedBox( height: 48.h,