diff --git a/lib/Globalconst.dart b/lib/Globalconst.dart new file mode 100644 index 0000000..6a8a72d --- /dev/null +++ b/lib/Globalconst.dart @@ -0,0 +1,6 @@ +class Globalconst { + static String token = ""; + static String name = ""; + static String phonenumber = ""; + static String isdcode = ""; +} diff --git a/lib/core/utils/constant/country_flag_data.dart b/lib/core/utils/constant/country_flag_data.dart index 4623908..1f313e2 100644 --- a/lib/core/utils/constant/country_flag_data.dart +++ b/lib/core/utils/constant/country_flag_data.dart @@ -27,3 +27,15 @@ List isoCountryCode = [ "+966", "+971", ]; + +/* List countryFlag = [ + AppImages.bahrainFlag, + // AppImages.kuwaitFlag, + // AppImages.omanFlag, + AppImages.qatarFlag, + AppImages.bahrainFlag, + AppImages.qatarFlag, + + // AppImages.saudiArabiaflag, + // AppImages.unitedArabEmiratesFlag, +]; */ \ No newline at end of file diff --git a/lib/features/MainScreens/Invest/presentation/widgets/payment/invest_pay_bottom_section.dart b/lib/features/MainScreens/Invest/presentation/widgets/payment/invest_pay_bottom_section.dart index 346ff99..8bc6639 100644 --- a/lib/features/MainScreens/Invest/presentation/widgets/payment/invest_pay_bottom_section.dart +++ b/lib/features/MainScreens/Invest/presentation/widgets/payment/invest_pay_bottom_section.dart @@ -12,8 +12,8 @@ import '../../../../../../core/styles/app_images.dart'; import '../../../../../../core/styles/app_text.dart'; import '../../../../../../core/utils/language/localizations_delegate.dart'; import '../../../../../../shared/components/button_widget.dart'; -import '../../../../../countrySelection/presentation/bloc/choose_country_bloc.dart'; -import '../../../../../countrySelection/presentation/bloc/choose_country_state.dart'; +import '../../../../../countrySelection/bloc/choose_country_bloc.dart'; +import '../../../../../countrySelection/bloc/choose_country_state.dart'; import '../../bloc/payment/invest_payment_bloc.dart'; import '../../bloc/payment/invest_payment_state.dart'; diff --git a/lib/features/MainScreens/Invest/presentation/widgets/payment/invest_pay_method_section.dart b/lib/features/MainScreens/Invest/presentation/widgets/payment/invest_pay_method_section.dart index 85bc65d..1e9d482 100644 --- a/lib/features/MainScreens/Invest/presentation/widgets/payment/invest_pay_method_section.dart +++ b/lib/features/MainScreens/Invest/presentation/widgets/payment/invest_pay_method_section.dart @@ -9,9 +9,9 @@ import 'package:tanami_app/shared/components/text_widget.dart'; import '../../../../../../core/styles/app_color.dart'; import '../../../../../../core/utils/language/localizations_delegate.dart'; -import '../../../../../countrySelection/presentation/bloc/choose_country_bloc.dart'; -import '../../../../../countrySelection/presentation/bloc/choose_country_event.dart'; -import '../../../../../countrySelection/presentation/bloc/choose_country_state.dart'; +import '../../../../../countrySelection/bloc/choose_country_bloc.dart'; +import '../../../../../countrySelection/bloc/choose_country_event.dart'; +import '../../../../../countrySelection/bloc/choose_country_state.dart'; class InvestPayMethodSection extends StatelessWidget { const InvestPayMethodSection({super.key}); diff --git a/lib/features/MainScreens/Invest/presentation/widgets/payment/invest_pay_top_section.dart b/lib/features/MainScreens/Invest/presentation/widgets/payment/invest_pay_top_section.dart index f2e9b1c..cc305b7 100644 --- a/lib/features/MainScreens/Invest/presentation/widgets/payment/invest_pay_top_section.dart +++ b/lib/features/MainScreens/Invest/presentation/widgets/payment/invest_pay_top_section.dart @@ -10,8 +10,8 @@ import 'package:tanami_app/shared/components/text_widget.dart'; import '../../../../../../core/utils/language/localizations_delegate.dart'; import '../../../../../../core/utils/text_formatter/comma_input_text_formatter.dart'; import '../../../../../../shared/components/text_from_field_widget.dart'; -import '../../../../../countrySelection/presentation/bloc/choose_country_bloc.dart'; -import '../../../../../countrySelection/presentation/bloc/choose_country_state.dart'; +import '../../../../../countrySelection/bloc/choose_country_bloc.dart'; +import '../../../../../countrySelection/bloc/choose_country_state.dart'; import '../../bloc/payment/invest_payment_bloc.dart'; import '../../bloc/payment/invest_payment_event.dart'; import '../../bloc/payment/invest_payment_state.dart'; diff --git a/lib/features/MainScreens/Wallet/presentation/pages/deposit/deposit_layout.dart b/lib/features/MainScreens/Wallet/presentation/pages/deposit/deposit_layout.dart index 9824250..83788bf 100644 --- a/lib/features/MainScreens/Wallet/presentation/pages/deposit/deposit_layout.dart +++ b/lib/features/MainScreens/Wallet/presentation/pages/deposit/deposit_layout.dart @@ -14,8 +14,8 @@ import '../../../../../../core/styles/app_images.dart'; import '../../../../../../core/styles/app_text.dart'; import '../../../../../../core/utils/language/localizations_delegate.dart'; import '../../../../../../core/utils/text_formatter/comma_input_text_formatter.dart'; -import '../../../../../countrySelection/presentation/bloc/choose_country_bloc.dart'; -import '../../../../../countrySelection/presentation/bloc/choose_country_state.dart'; +import '../../../../../countrySelection/bloc/choose_country_bloc.dart'; +import '../../../../../countrySelection/bloc/choose_country_state.dart'; import '../../bloc/deposit/deposit_payment_bloc.dart'; import '../../bloc/deposit/deposit_payment_event.dart'; import '../../bloc/deposit/deposit_payment_state.dart'; diff --git a/lib/features/MainScreens/Wallet/presentation/widgets/deposit_pay_method_section.dart b/lib/features/MainScreens/Wallet/presentation/widgets/deposit_pay_method_section.dart index f454d57..8c97d6b 100644 --- a/lib/features/MainScreens/Wallet/presentation/widgets/deposit_pay_method_section.dart +++ b/lib/features/MainScreens/Wallet/presentation/widgets/deposit_pay_method_section.dart @@ -8,9 +8,9 @@ import 'package:tanami_app/shared/components/text_widget.dart'; import '../../../../../../core/styles/app_color.dart'; import '../../../../../core/utils/language/localizations_delegate.dart'; -import '../../../../countrySelection/presentation/bloc/choose_country_bloc.dart'; -import '../../../../countrySelection/presentation/bloc/choose_country_event.dart'; -import '../../../../countrySelection/presentation/bloc/choose_country_state.dart'; +import '../../../../countrySelection/bloc/choose_country_bloc.dart'; +import '../../../../countrySelection/bloc/choose_country_event.dart'; +import '../../../../countrySelection/bloc/choose_country_state.dart'; class DepositPayMethodSection extends StatelessWidget { const DepositPayMethodSection({super.key}); diff --git a/lib/features/OTP/Repository/OTP_API.dart b/lib/features/OTP/Repository/OTP_API.dart new file mode 100644 index 0000000..e0560c2 --- /dev/null +++ b/lib/features/OTP/Repository/OTP_API.dart @@ -0,0 +1,23 @@ +import '../../../../Api_Helper/base_manager.dart'; +import '../../../../shared/api/api_endpoints.dart'; +import '../../../../shared/api/network_api_services.dart'; + +class OTPAPI { + OTPAPI(); + Future RequestOTP(Map data) async { + String url = ApiEndpoints.requestotpapi; + final response = await NetworkApiService().post(url, data); + return response; + } + Future ResendOTPRequest(Map data) async { + String url = ApiEndpoints.requestresendotp; + final response = await NetworkApiService().post(url, data); + return response; + } + + Future VerifyOTP(Map data) async { + String url = ApiEndpoints.verifyotp; + final response = await NetworkApiService().post(url, data); + return response; + } +} diff --git a/lib/features/OTP/bloc/OTPStateEvent.dart b/lib/features/OTP/bloc/OTPStateEvent.dart new file mode 100644 index 0000000..53b7f73 --- /dev/null +++ b/lib/features/OTP/bloc/OTPStateEvent.dart @@ -0,0 +1,37 @@ + +abstract class OTPEvent { + const OTPEvent(); + + List get props => []; +} + +class RequestOTP extends OTPEvent { + final Map OTPRequestData; + RequestOTP(this.OTPRequestData); + + @override + List get props => [OTPRequestData]; + +} +class VerifyOTP extends OTPEvent { + VerifyOTP(); + + +} +abstract class OTPState{} +class OTPInitial extends OTPState {} + +class OTPLoading extends OTPState {} + +class OTPLoaded extends OTPState {} + +class OTPFailed extends OTPState { + final String failedmessage; + + OTPFailed(this.failedmessage); +} +class OTPError extends OTPState { + final String errormessage; + + OTPError(this.errormessage); +} diff --git a/lib/features/OTP/bloc/OTP_bloc.dart b/lib/features/OTP/bloc/OTP_bloc.dart new file mode 100644 index 0000000..ede3651 --- /dev/null +++ b/lib/features/OTP/bloc/OTP_bloc.dart @@ -0,0 +1,48 @@ +import 'package:bloc/bloc.dart'; +import 'package:tanami_app/features/OTP/bloc/OTPStateEvent.dart'; + +import '../../../Api_Helper/base_manager.dart'; +import '../Repository/OTP_API.dart'; + +class OTPBloc extends Bloc { + OTPBloc() : super (OTPInitial()) { + on(RequestOTPCall); + // on(VerifyOTPCall); + } + Future RequestOTPCall(RequestOTP event, Emitter emit) async { + if (event is RequestOTP) { + emit(OTPLoading()); + final otprequestdata = event.OTPRequestData; + + try { + ResponseData response = await OTPAPI().RequestOTP(otprequestdata); + if (response.status == ResponseStatus.SUCCESS) { + emit(OTPLoaded()); + } 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/countrySelection/presentation/bloc/GetCountry/GetCountryAPI.dart b/lib/features/countrySelection/bloc/GetCountry/GetCountryAPI.dart similarity index 57% rename from lib/features/countrySelection/presentation/bloc/GetCountry/GetCountryAPI.dart rename to lib/features/countrySelection/bloc/GetCountry/GetCountryAPI.dart index 7cc0a8b..bf736bf 100644 --- a/lib/features/countrySelection/presentation/bloc/GetCountry/GetCountryAPI.dart +++ b/lib/features/countrySelection/bloc/GetCountry/GetCountryAPI.dart @@ -1,7 +1,7 @@ -import '../../../../../Api_Helper/base_manager.dart'; -import '../../../../../shared/api/api_endpoints.dart'; -import '../../../../../shared/api/network_api_services.dart'; +import '../../../../Api_Helper/base_manager.dart'; +import '../../../../shared/api/api_endpoints.dart'; +import '../../../../shared/api/network_api_services.dart'; class GetCountryAPI { GetCountryAPI(); diff --git a/lib/features/countrySelection/presentation/bloc/GetCountry/getcountry_bloc.dart b/lib/features/countrySelection/bloc/GetCountry/getcountry_bloc.dart similarity index 77% rename from lib/features/countrySelection/presentation/bloc/GetCountry/getcountry_bloc.dart rename to lib/features/countrySelection/bloc/GetCountry/getcountry_bloc.dart index 564c41c..7584cd5 100644 --- a/lib/features/countrySelection/presentation/bloc/GetCountry/getcountry_bloc.dart +++ b/lib/features/countrySelection/bloc/GetCountry/getcountry_bloc.dart @@ -1,8 +1,8 @@ import 'package:bloc/bloc.dart'; -import 'package:tanami_app/features/countrySelection/presentation/bloc/GetCountry/getcountryevent_bloc.dart'; +import 'package:tanami_app/features/countrySelection/bloc/GetCountry/getcountryevent_bloc.dart'; -import '../../../../../Api_Helper/base_manager.dart'; -import '../../../../../domain/model/GetCountry_model.dart'; +import '../../../../Api_Helper/base_manager.dart'; +import '../../domain/model/GetCountry_model.dart'; import 'GetCountryAPI.dart'; diff --git a/lib/features/countrySelection/presentation/bloc/GetCountry/getcountryevent_bloc.dart b/lib/features/countrySelection/bloc/GetCountry/getcountryevent_bloc.dart similarity index 90% rename from lib/features/countrySelection/presentation/bloc/GetCountry/getcountryevent_bloc.dart rename to lib/features/countrySelection/bloc/GetCountry/getcountryevent_bloc.dart index bc6bb65..01b4751 100644 --- a/lib/features/countrySelection/presentation/bloc/GetCountry/getcountryevent_bloc.dart +++ b/lib/features/countrySelection/bloc/GetCountry/getcountryevent_bloc.dart @@ -1,4 +1,4 @@ -import '../../../../../domain/model/GetCountry_model.dart'; +import '../../domain/model/GetCountry_model.dart'; abstract class GetCountryEvent { const GetCountryEvent(); diff --git a/lib/features/countrySelection/presentation/bloc/choose_country_bloc.dart b/lib/features/countrySelection/bloc/choose_country_bloc.dart similarity index 100% rename from lib/features/countrySelection/presentation/bloc/choose_country_bloc.dart rename to lib/features/countrySelection/bloc/choose_country_bloc.dart diff --git a/lib/features/countrySelection/presentation/bloc/choose_country_event.dart b/lib/features/countrySelection/bloc/choose_country_event.dart similarity index 100% rename from lib/features/countrySelection/presentation/bloc/choose_country_event.dart rename to lib/features/countrySelection/bloc/choose_country_event.dart diff --git a/lib/features/countrySelection/presentation/bloc/choose_country_state.dart b/lib/features/countrySelection/bloc/choose_country_state.dart similarity index 100% rename from lib/features/countrySelection/presentation/bloc/choose_country_state.dart rename to lib/features/countrySelection/bloc/choose_country_state.dart diff --git a/lib/domain/model/GetCountry_model.dart b/lib/features/countrySelection/domain/model/GetCountry_model.dart similarity index 100% rename from lib/domain/model/GetCountry_model.dart rename to lib/features/countrySelection/domain/model/GetCountry_model.dart diff --git a/lib/features/countrySelection/presentation/pages/choose_country_layout.dart b/lib/features/countrySelection/presentation/pages/choose_country_layout.dart index 86eeb7b..a37d19b 100644 --- a/lib/features/countrySelection/presentation/pages/choose_country_layout.dart +++ b/lib/features/countrySelection/presentation/pages/choose_country_layout.dart @@ -27,6 +27,7 @@ class ChooseCountryLayout extends StatelessWidget { child: ButtonWidget().elevatedBtn( txtClr: AppColor.plainWhite, function: () { + print("//"); goRouter.pop(); }, text: localizations.translate(AppText.confirmSelectionText), diff --git a/lib/features/countrySelection/presentation/widgets/country_selection_list.dart b/lib/features/countrySelection/presentation/widgets/country_selection_list.dart index db26358..9887941 100644 --- a/lib/features/countrySelection/presentation/widgets/country_selection_list.dart +++ b/lib/features/countrySelection/presentation/widgets/country_selection_list.dart @@ -1,15 +1,18 @@ +import 'package:cached_network_image/cached_network_image.dart'; 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/styles/app_color.dart'; import 'package:tanami_app/core/utils/constant/country_flag_data.dart'; -import 'package:tanami_app/features/countrySelection/presentation/bloc/GetCountry/getcountry_bloc.dart'; -import 'package:tanami_app/features/countrySelection/presentation/bloc/GetCountry/getcountryevent_bloc.dart'; +import 'package:tanami_app/features/countrySelection/bloc/GetCountry/getcountry_bloc.dart'; +import 'package:tanami_app/features/countrySelection/bloc/GetCountry/getcountryevent_bloc.dart'; import 'package:tanami_app/shared/components/text_widget.dart'; -import '../bloc/choose_country_bloc.dart'; -import '../bloc/choose_country_event.dart'; -import '../bloc/choose_country_state.dart'; +import '../../../../shared/api/api_endpoints.dart'; +import '../../bloc/choose_country_bloc.dart'; +import '../../bloc/choose_country_event.dart'; +import '../../bloc/choose_country_state.dart'; class CountrySelectionList extends StatelessWidget { const CountrySelectionList({super.key}); @@ -17,55 +20,6 @@ class CountrySelectionList extends StatelessWidget { @override Widget build(BuildContext context) { final radioBloc = context.read(); - /* return BlocConsumer( - listener: (context, state) { - /* if (state == GetCountryState.success) { - const SnackBar(content: Text("Successfully fetch")); - } else if (state == GetCountryState.error) { - const SnackBar(content: Text(" error")); - } else { - const SnackBar(content: Text(" not fetch")); - } */ - }, builder: (context, state) { - print(state); - if (state is CountryLoading) { - return Center(child: CircularProgressIndicator()); - } else if (state is CountryLoaded) { - return ListView.builder( - itemCount: state.countryModel.data?.length ?? 0, - itemBuilder: (context, index) { - var country = state.countryModel.data![index]; - return ListTile( - title: Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - // Adjust according to how you handle flags - Image.asset( - countryFlag[index], - width: 24, - height: 24, - ), - const SizedBox(width: 10), - Text(country.countryName ?? ''), - ], - ), - leading: Radio( - activeColor: Colors.blue, - value: index, - groupValue: -1, // You can update this to manage selected index - onChanged: (int? value) { - // Handle radio button change - }, - ), - ); - }, - ); - } else if (state is CountryError) { - return Center(child: Text(state.message)); - } else { - return Center(child: Text('Press button to fetch country data')); - } - }); */ return BlocBuilder( builder: (context, state) { @@ -95,15 +49,39 @@ class CountrySelectionList extends StatelessWidget { itemCount: state.countryModel.data?.length ?? 0, itemBuilder: (context, index) { var country = state.countryModel.data![index]; + print("${ApiEndpoints.base}${country.flagIcon}"); return ListTile( title: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ - Image.asset( + Container( + height: 24.h, + width: 24.w, + child: ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(100)), + child: CachedNetworkImage( + maxHeightDiskCache: 200, + maxWidthDiskCache: 200, + cacheKey: country.countryName, + key: UniqueKey(), + imageUrl: "${ApiEndpoints.base}${country.flagIcon}", + height: 24.h, + width: 24.w, + placeholder: (context, url) => Container( + height: 24.h, + width: 24.w, + child: CircularProgressIndicator(), + ), + errorWidget: (context, url, error) => + Icon(Icons.error), + fit: BoxFit.cover), + ), + ), + /* Image.asset( countryFlag[index], width: 24, height: 24, - ), + ), */ const Gap(10), TextWidget().text14W500(country.countryName.toString(), clr: AppColor.charcoalColor), 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 0545c8b..4d98022 100644 --- a/lib/features/forgotPassword/presentation/widgets/restore_password_bottom_section.dart +++ b/lib/features/forgotPassword/presentation/widgets/restore_password_bottom_section.dart @@ -12,7 +12,7 @@ import '../../../../core/styles/app_text.dart'; import '../../../../core/utils/language/localizations_delegate.dart'; import '../../../../shared/components/button_widget.dart'; import '../../../../shared/components/text_widget.dart'; -import '../../../countrySelection/presentation/bloc/choose_country_bloc.dart'; +import '../../../countrySelection/bloc/choose_country_bloc.dart'; import '../bloc/restore_password_bloc.dart'; import '../bloc/restore_password_event.dart'; import '../bloc/restore_password_state.dart'; 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 4fe8021..e682d2e 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 @@ -12,7 +12,7 @@ import '../../../../core/styles/app_text.dart'; import '../../../../core/utils/language/localizations_delegate.dart'; import '../../../../shared/components/button_widget.dart'; import '../../../../shared/components/text_widget.dart'; -import '../../../countrySelection/presentation/bloc/choose_country_bloc.dart'; +import '../../../countrySelection/bloc/choose_country_bloc.dart'; import '../bloc/restore_password_phone_verification_bloc.dart'; import '../bloc/restore_password_phone_verification_event.dart'; import '../bloc/restore_password_phone_verification_state.dart'; diff --git a/lib/features/forgotPassword/presentation/widgets/restore_password_phone_verification_form.dart b/lib/features/forgotPassword/presentation/widgets/restore_password_phone_verification_form.dart index 11c6963..127f8ad 100644 --- a/lib/features/forgotPassword/presentation/widgets/restore_password_phone_verification_form.dart +++ b/lib/features/forgotPassword/presentation/widgets/restore_password_phone_verification_form.dart @@ -6,8 +6,8 @@ import 'package:tanami_app/core/utils/constant/country_flag_data.dart'; import '../../../../core/utils/language/localizations_delegate.dart'; import '../../../../shared/components/form_label_textfield.dart'; -import '../../../countrySelection/presentation/bloc/choose_country_bloc.dart'; -import '../../../countrySelection/presentation/bloc/choose_country_state.dart'; +import '../../../countrySelection/bloc/choose_country_bloc.dart'; +import '../../../countrySelection/bloc/choose_country_state.dart'; import '../bloc/restore_password_phone_verification_bloc.dart'; class RestorePasswordPhoneVerificationForm extends StatelessWidget { diff --git a/lib/features/login/presentation/pages/login_screen.dart b/lib/features/login/presentation/pages/login_screen.dart index 3ff586e..9a89c17 100644 --- a/lib/features/login/presentation/pages/login_screen.dart +++ b/lib/features/login/presentation/pages/login_screen.dart @@ -3,7 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import '../../../../core/styles/app_color.dart'; import '../../../../shared/components/exit_app_dialog.dart'; -import '../../../countrySelection/presentation/bloc/choose_country_bloc.dart'; +import '../../../countrySelection/bloc/choose_country_bloc.dart'; import '../bloc/login_bloc.dart'; import 'login_layout.dart'; diff --git a/lib/features/login/presentation/widgets/bottom_section.dart b/lib/features/login/presentation/widgets/bottom_section.dart index 5e7726c..3c943df 100644 --- a/lib/features/login/presentation/widgets/bottom_section.dart +++ b/lib/features/login/presentation/widgets/bottom_section.dart @@ -13,7 +13,7 @@ import '../../../../core/styles/app_text.dart'; import '../../../../core/utils/language/localizations_delegate.dart'; import '../../../../shared/components/button_widget.dart'; import '../../../../shared/components/text_widget.dart'; -import '../../../countrySelection/presentation/bloc/choose_country_bloc.dart'; +import '../../../countrySelection/bloc/choose_country_bloc.dart'; import '../bloc/login_bloc.dart'; import '../bloc/login_event.dart'; import '../bloc/login_state.dart'; diff --git a/lib/features/login/presentation/widgets/login_form.dart b/lib/features/login/presentation/widgets/login_form.dart index 0cbbcb3..6c29693 100644 --- a/lib/features/login/presentation/widgets/login_form.dart +++ b/lib/features/login/presentation/widgets/login_form.dart @@ -7,8 +7,8 @@ import 'package:tanami_app/core/utils/constant/country_flag_data.dart'; import '../../../../core/utils/language/localizations_delegate.dart'; import '../../../../shared/components/bloc/password_field/password_visibility_bloc.dart'; import '../../../../shared/components/form_label_textfield.dart'; -import '../../../countrySelection/presentation/bloc/choose_country_bloc.dart'; -import '../../../countrySelection/presentation/bloc/choose_country_state.dart'; +import '../../../countrySelection/bloc/choose_country_bloc.dart'; +import '../../../countrySelection/bloc/choose_country_state.dart'; import '../bloc/login_bloc.dart'; class LoginForm extends StatelessWidget { diff --git a/lib/features/otpVerification/presentation/bloc/otp_bloc.dart b/lib/features/otpVerification/presentation/bloc/otp_bloc.dart index 021580b..c26a9dd 100644 --- a/lib/features/otpVerification/presentation/bloc/otp_bloc.dart +++ b/lib/features/otpVerification/presentation/bloc/otp_bloc.dart @@ -2,6 +2,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:sms_autofill/sms_autofill.dart'; +import 'package:tanami_app/Api_Helper/base_manager.dart'; +import 'package:tanami_app/Globalconst.dart'; +import '../../../OTP/Repository/OTP_API.dart'; import 'otp_event.dart'; import 'otp_state.dart'; @@ -28,9 +31,14 @@ class OtpBloc extends Bloc { void _onOtpSubmit(OtpSubmit event, Emitter emit) async { emit(OtpSubmitting()); try { + Map otpdata= { + "token":Globalconst.token, + "otp":otpController.text + }; + ResponseData response= await OTPAPI().VerifyOTP(otpdata); // Add your OTP verification logic here - await Future.delayed(const Duration(seconds: 2)); - if (otpController.text == "123456") { + // await Future.delayed(const Duration(seconds: 2)); + if (response.status==ResponseStatus.SUCCESS) { emit(OtpSubmissionSuccess()); } else { emit(const OtpSubmissionFailure("Otp Invalid !")); diff --git a/lib/features/otpVerification/presentation/pages/otp_screen.dart b/lib/features/otpVerification/presentation/pages/otp_screen.dart index de03fb2..bb89f72 100644 --- a/lib/features/otpVerification/presentation/pages/otp_screen.dart +++ b/lib/features/otpVerification/presentation/pages/otp_screen.dart @@ -4,12 +4,14 @@ import 'package:tanami_app/features/otpVerification/presentation/bloc/otp_bloc.d import 'package:tanami_app/features/otpVerification/presentation/pages/otp_layout.dart'; import '../../../../core/styles/app_color.dart'; +import '../../../register/presentation/bloc/register_bloc.dart'; import '../bloc/otp_event.dart'; import '../bloc/timer/timer_bloc.dart'; import '../bloc/timer/timer_event.dart'; class OtpScreen extends StatelessWidget { final String fromScreen; + const OtpScreen({ super.key, required this.fromScreen, @@ -20,7 +22,7 @@ class OtpScreen extends StatelessWidget { return Scaffold( backgroundColor: AppColor.plainWhite, resizeToAvoidBottomInset: true, - body: MultiBlocProvider( + body: MultiBlocProvider( providers: [ BlocProvider( // Create an instance of the OnboardingBloc @@ -30,6 +32,11 @@ class OtpScreen extends StatelessWidget { create: (context) => TimerBloc()..add(StartTimer()), // Start the timer here ), + //RegisterBloc + BlocProvider( + create: (context) => + RegisterBloc(), // Start the timer here + ), ], child: OtpLayout(fromScreen: fromScreen), ), diff --git a/lib/features/otpVerification/presentation/widgets/resend_otp_section.dart b/lib/features/otpVerification/presentation/widgets/resend_otp_section.dart index 4a50174..fe6b195 100644 --- a/lib/features/otpVerification/presentation/widgets/resend_otp_section.dart +++ b/lib/features/otpVerification/presentation/widgets/resend_otp_section.dart @@ -1,11 +1,19 @@ + import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:tanami_app/core/styles/app_color.dart'; import 'package:tanami_app/core/styles/app_text.dart'; import 'package:tanami_app/shared/components/text_widget.dart'; import 'package:tanami_app/shared/components/toast_message.dart'; +import '../../../../Globalconst.dart'; +import '../../../../core/routes/routes.dart'; import '../../../../core/utils/language/localizations_delegate.dart'; +import '../../../../shared/components/loader.dart'; +import '../../../register/presentation/bloc/register_bloc.dart'; +import '../../../register/presentation/bloc/register_event.dart'; +import '../../../register/presentation/bloc/register_state.dart'; import '../bloc/timer/timer_bloc.dart'; import '../bloc/timer/timer_state.dart'; @@ -14,6 +22,11 @@ class ResendOtpSection extends StatelessWidget { @override Widget build(BuildContext context) { + String token = ""; + var loginBloc = context.read(); + loginBloc.isdcode=Globalconst.isdcode; + loginBloc.phoneNumberTextField.text=Globalconst.phonenumber; + loginBloc.countrySelectionTextField.text=Globalconst.name; var localizations = AppLocalizations.of(context); return BlocBuilder( builder: (context, state) { @@ -26,16 +39,68 @@ class ResendOtpSection extends StatelessWidget { state.formattedDuration, clr: AppColor.plainBlack, ), - GestureDetector( + BlocConsumer( + listener: (context, state) { + print(loginBloc.state); + if (state is RegisterLoading) { + Loader.loader(context); + } else if (state is RegisterSuccess) { + successToastMessage(context, "OTP Resend Sucessfully !"); + goRouter.pop(); + } else if (state is RegisterFailure) { + goRouter.pop(); + errorToastMessage( + context, + state.error, + ); + } + }, + builder: (context, state) { + bool isButtonEnabled = false; + + if (state is RegisterFieldsState) { + isButtonEnabled = state.areFieldsFilled; + } else if (state is RegisterSuccess || + state is RegisterFailure) { + isButtonEnabled = true; + } + return GestureDetector( + onTap: () { + loginBloc.add( + Resendotp(Globalconst.token), + ); + print("///"); + + // successToastMessage(context, "OTP Resend Sucessfully !"); + }, + child: TextWidget().text14W500( + localizations.translate(AppText.resendSms), + clr: isButtonEnabled + ? AppColor.plainBlack + : AppColor.indicatorInactiveColor, + textDecoration: TextDecoration.underline, + ), + ); + }, + ), + /* GestureDetector( onTap: () { - successToastMessage(context, "OTP Resend Sucessfully !"); + 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 7811fe6..82f63bb 100644 --- a/lib/features/register/presentation/bloc/register_bloc.dart +++ b/lib/features/register/presentation/bloc/register_bloc.dart @@ -1,5 +1,8 @@ import 'package:bloc/bloc.dart'; import 'package:flutter/material.dart'; +import '../../../../Api_Helper/base_manager.dart'; +import '../../../../Globalconst.dart'; +import '../../../OTP/Repository/OTP_API.dart'; import 'register_event.dart'; import 'register_state.dart'; @@ -7,6 +10,7 @@ class RegisterBloc extends Bloc { final GlobalKey formKey = GlobalKey(); final TextEditingController countrySelectionTextField = TextEditingController(); + String isdcode=""; final TextEditingController phoneNumberTextField = TextEditingController(); GlobalKey getFormKey() { @@ -15,7 +19,6 @@ class RegisterBloc extends Bloc { RegisterBloc() : super(RegisterInitial()) { phoneNumberTextField.addListener(_onFormFieldChanged); - countrySelectionTextField.addListener(_onFormFieldChanged); on(_onLoginFormChanged); on((event, emit) async { @@ -24,16 +27,40 @@ class RegisterBloc extends Bloc { } emit(RegisterLoading()); try { - // Simulate API call - await Future.delayed(const Duration(seconds: 2)); - // Replace the next line with actual API call - final isSuccess = - await _mockLoginApi(event.phoneNumber, event.countryResidence); - if (isSuccess) { - emit(RegisterSuccess()); + Map requestdata={ + "isdCode":event.isdcode, + "phoneNumber":event.phoneNumber + }; + ResponseData response = await OTPAPI().RequestOTP(requestdata); + if (response.status == ResponseStatus.SUCCESS) { + print("///////success"); + var data=response.data["data"]; + String token=data["token"]; + Globalconst.token=token; + emit(RegisterSuccess(token));//emit(OTPLoaded()); } else { emit(const RegisterFailure( "Register failed. Please check your credentials.")); + //emit(OTPFailed("Oops something went wrong")); + } + } catch (e) { + emit(RegisterFailure(e.toString())); + } + }); + + on((event, emit) async { + emit(RegisterLoading()); + try { + Map requestdata={ + "token":Globalconst.token, + }; + ResponseData response = await OTPAPI().ResendOTPRequest(requestdata); + if (response.status == ResponseStatus.SUCCESS) { + emit(RegisterSuccess(event.token));//emit(OTPLoaded()); + } else { + emit(const RegisterFailure( + "Register failed. Please check your credentials.")); + //emit(OTPFailed("Oops something went wrong")); } } catch (e) { emit(RegisterFailure(e.toString())); diff --git a/lib/features/register/presentation/bloc/register_event.dart b/lib/features/register/presentation/bloc/register_event.dart index 2481914..a826600 100644 --- a/lib/features/register/presentation/bloc/register_event.dart +++ b/lib/features/register/presentation/bloc/register_event.dart @@ -9,18 +9,32 @@ abstract class RegisterEvent extends Equatable { class RegisterSubmitted extends RegisterEvent { final String phoneNumber; - final String countryResidence; + final String isdcode; const RegisterSubmitted( this.phoneNumber, this.countryResidence, + this.isdcode ); @override List get props => [phoneNumber, countryResidence]; } +class Resendotp extends RegisterEvent { + final String token; + + + const Resendotp( + this.token, + + ); + + @override + List get props => [token]; +} + class RegisterFormChanged extends RegisterEvent { final String phoneNumber; final String country; diff --git a/lib/features/register/presentation/bloc/register_state.dart b/lib/features/register/presentation/bloc/register_state.dart index 8f23bcb..04ab37a 100644 --- a/lib/features/register/presentation/bloc/register_state.dart +++ b/lib/features/register/presentation/bloc/register_state.dart @@ -11,7 +11,14 @@ class RegisterInitial extends RegisterState {} class RegisterLoading extends RegisterState {} -class RegisterSuccess extends RegisterState {} +class RegisterSuccess extends RegisterState { + final String token; + + const RegisterSuccess(this.token); + @override + List get props => [token]; + +} class RegisterFailure extends RegisterState { final String error; diff --git a/lib/features/register/presentation/pages/register_screen.dart b/lib/features/register/presentation/pages/register_screen.dart index 02bafe3..1edc0c2 100644 --- a/lib/features/register/presentation/pages/register_screen.dart +++ b/lib/features/register/presentation/pages/register_screen.dart @@ -3,7 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:tanami_app/features/register/presentation/bloc/register_bloc.dart'; import '../../../../core/styles/app_color.dart'; -import '../../../countrySelection/presentation/bloc/choose_country_bloc.dart'; +import '../../../countrySelection/bloc/choose_country_bloc.dart'; import 'register_layout.dart'; class RegisterScreen extends StatelessWidget { diff --git a/lib/features/register/presentation/widgets/register_bottom_section.dart b/lib/features/register/presentation/widgets/register_bottom_section.dart index c29da35..c88b474 100644 --- a/lib/features/register/presentation/widgets/register_bottom_section.dart +++ b/lib/features/register/presentation/widgets/register_bottom_section.dart @@ -7,13 +7,14 @@ import 'package:tanami_app/core/styles/app_images.dart'; import 'package:tanami_app/shared/components/loader.dart'; import 'package:tanami_app/shared/components/toast_message.dart'; +import '../../../../Globalconst.dart'; import '../../../../core/routes/route_name.dart'; import '../../../../core/routes/routes.dart'; import '../../../../core/styles/app_color.dart'; import '../../../../core/styles/app_text.dart'; import '../../../../core/utils/language/localizations_delegate.dart'; import '../../../../shared/components/button_widget.dart'; -import '../../../countrySelection/presentation/bloc/choose_country_bloc.dart'; +import '../../../countrySelection/bloc/choose_country_bloc.dart'; import '../bloc/register_bloc.dart'; import '../bloc/register_event.dart'; import '../bloc/register_state.dart'; @@ -25,6 +26,8 @@ class RegisterBottomSection extends StatelessWidget { Widget build(BuildContext context) { var localizations = AppLocalizations.of(context); final radioBloc = context.read(); + final loginBloc = context.read(); + return Column( children: [ const Gap(90), @@ -34,8 +37,9 @@ class RegisterBottomSection extends StatelessWidget { height: 12, ), const Gap(36), - BlocConsumer( + BlocConsumer( listener: (context, state) { + print(loginBloc.state); if (state is RegisterLoading) { Loader.loader(context); } else if (state is RegisterSuccess) { @@ -44,6 +48,7 @@ class RegisterBottomSection extends StatelessWidget { goRouter.pushNamed(RouteName.otpScreen, pathParameters: {"fromScreen": "register"}); + } else if (state is RegisterFailure) { goRouter.pop(); errorToastMessage( @@ -70,14 +75,15 @@ class RegisterBottomSection extends StatelessWidget { ? AppColor.plainWhite : AppColor.inactiveBtnTxtColor, function: () { + Globalconst.phonenumber=loginBloc.phoneNumberTextField.text; + isButtonEnabled ? context.read().add( RegisterSubmitted( - context - .read() - .phoneNumberTextField - .text, - ""), + loginBloc.phoneNumberTextField.text, + loginBloc.countrySelectionTextField.text, + loginBloc.isdcode + ), ) : null; }, diff --git a/lib/features/register/presentation/widgets/register_form.dart b/lib/features/register/presentation/widgets/register_form.dart index a29c542..5af77bb 100644 --- a/lib/features/register/presentation/widgets/register_form.dart +++ b/lib/features/register/presentation/widgets/register_form.dart @@ -1,13 +1,18 @@ +import 'package:cached_network_image/cached_network_image.dart'; 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/styles/app_text.dart'; -import 'package:tanami_app/core/utils/constant/country_flag_data.dart'; +import 'package:tanami_app/features/countrySelection/bloc/GetCountry/getcountryevent_bloc.dart'; +import '../../../../Globalconst.dart'; import '../../../../core/utils/language/localizations_delegate.dart'; +import '../../../../shared/api/api_endpoints.dart'; import '../../../../shared/components/form_label_textfield.dart'; -import '../../../countrySelection/presentation/bloc/choose_country_bloc.dart'; -import '../../../countrySelection/presentation/bloc/choose_country_state.dart'; +import '../../../countrySelection/bloc/GetCountry/getcountry_bloc.dart'; +import '../../../countrySelection/bloc/choose_country_bloc.dart'; +import '../../../countrySelection/bloc/choose_country_state.dart'; import '../bloc/register_bloc.dart'; class RegisterForm extends StatelessWidget { @@ -17,13 +22,29 @@ class RegisterForm extends StatelessWidget { Widget build(BuildContext context) { var localizations = AppLocalizations.of(context); final loginBloc = context.read(); + final countrydata = context.read(); int selectedCountry = -1; + String flag = ""; return BlocConsumer(listener: (context, state) { if (state is RadioSelectionChanged) { selectedCountry = state.selectedIndex; - loginBloc.countrySelectionTextField.text = countryName[selectedCountry]; - loginBloc.phoneNumberTextField.text = - "${isoCountryCode[selectedCountry]} "; + final countryState = countrydata.state; + if (countryState is CountryLoaded) { + loginBloc.countrySelectionTextField.text = countryState + .countryModel.data![selectedCountry].countryName + .toString(); + loginBloc.phoneNumberTextField.text = + "${countryState.countryModel.data![selectedCountry].isdCode}"; + loginBloc.isdcode="${countryState.countryModel.data![selectedCountry].isdCode}"; + flag = + "${ApiEndpoints.base}${countryState.countryModel.data![selectedCountry].flagIcon}"; + Globalconst.phonenumber=loginBloc.phoneNumberTextField.text; + + Globalconst.name=countryState + .countryModel.data![selectedCountry].countryName + .toString(); + Globalconst.isdcode="${countryState.countryModel.data![selectedCountry].isdCode}"; + } } }, builder: (context, state) { if (state is RadioSelectionChanged) { @@ -46,11 +67,46 @@ class RegisterForm extends StatelessWidget { FormLabelTextField( prefixWidget: selectedCountry == -1 ? null - : Image.asset( + : Padding( + padding: EdgeInsets.only(left: 12.w), + child: SizedBox( + height: 50.h, + width: 30.w, + child: Align( + alignment: Alignment.centerLeft, + child: SizedBox( + height: 30.h, + width: 30.w, + child: ClipRRect( + borderRadius: + BorderRadius.all(Radius.circular(100)), + child: CachedNetworkImage( + maxHeightDiskCache: 200, + maxWidthDiskCache: 200, + cacheKey: loginBloc + .countrySelectionTextField.text, + key: UniqueKey(), + imageUrl: flag, + height: 30.h, + width: 30.w, + placeholder: (context, url) => Container( + height: 30.h, + width: 30.w, + child: CircularProgressIndicator(), + ), + errorWidget: (context, url, error) => + Icon(Icons.error), + fit: BoxFit.cover), + ), + ), + ), + ), + ), + /* Image.asset( countryFlag[selectedCountry], width: 20, height: 20, - ), + ), */ hintText: localizations.translate(AppText.chooseCountry), title: localizations.translate(AppText.countryOfResidence), type: "country selection", @@ -58,13 +114,47 @@ class RegisterForm extends StatelessWidget { ), const Gap(20), FormLabelTextField( - prefixWidget: selectedCountry == -1 + prefixWidget: selectedCountry == -1 ||flag.isEmpty ? null - : Image.asset( + : Padding( + padding: EdgeInsets.only(left: 12.w), + child: SizedBox( + height: 50.h, + width: 30.w, + child: Align( + alignment: Alignment.centerLeft, + child: SizedBox( + height: 30.h, + width: 30.w, + child: ClipRRect( + borderRadius: + BorderRadius.all(Radius.circular(100)), + child: CachedNetworkImage( + maxHeightDiskCache: 200, + maxWidthDiskCache: 200, + cacheKey: loginBloc + .countrySelectionTextField.text, + key: UniqueKey(), + imageUrl: flag, + height: 30.h, + width: 30.w, + placeholder: (context, url) => Container( + height: 30.h, + width: 30.w, + child: CircularProgressIndicator(), + ), + errorWidget: (context, url, error) => + Icon(Icons.error), + fit: BoxFit.cover), + ), + ), + ), + ), + ),/* Image.asset( countryFlag[selectedCountry], width: 20, height: 20, - ), + ), */ hintText: "+0 (000) 000 00 00", title: localizations.translate(AppText.phoneNumber), type: "phone number", diff --git a/lib/features/welcome/presentation/widgets/login_signup_button.dart b/lib/features/welcome/presentation/widgets/login_signup_button.dart index 7770381..bf41f12 100644 --- a/lib/features/welcome/presentation/widgets/login_signup_button.dart +++ b/lib/features/welcome/presentation/widgets/login_signup_button.dart @@ -5,8 +5,8 @@ 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/features/countrySelection/presentation/bloc/GetCountry/getcountry_bloc.dart'; -import 'package:tanami_app/features/countrySelection/presentation/bloc/GetCountry/getcountryevent_bloc.dart'; +import 'package:tanami_app/features/countrySelection/bloc/GetCountry/getcountry_bloc.dart'; +import 'package:tanami_app/features/countrySelection/bloc/GetCountry/getcountryevent_bloc.dart'; import 'package:tanami_app/shared/components/button_widget.dart'; import '../../../../core/styles/app_text.dart'; diff --git a/lib/main.dart b/lib/main.dart index 0bfa343..9818507 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -9,10 +9,16 @@ import 'core/routes/routes.dart'; import 'core/utils/connectivity/network_connectivity.dart'; import 'core/utils/language/localizations_delegate.dart'; import 'core/utils/secure/secure_storage_service.dart'; +import 'features/OTP/bloc/OTP_bloc.dart'; import 'features/biometric/presentation/bloc/biometric_bloc.dart'; import 'features/biometric/presentation/bloc/biometric_event.dart'; -import 'features/countrySelection/presentation/bloc/GetCountry/getcountry_bloc.dart'; -import 'features/countrySelection/presentation/bloc/choose_country_bloc.dart'; +import 'features/countrySelection/bloc/GetCountry/getcountry_bloc.dart'; +import 'features/countrySelection/bloc/choose_country_bloc.dart'; +import 'features/otpVerification/presentation/bloc/otp_bloc.dart'; +import 'features/otpVerification/presentation/bloc/otp_event.dart'; +import 'features/otpVerification/presentation/bloc/timer/timer_bloc.dart'; +import 'features/otpVerification/presentation/bloc/timer/timer_event.dart'; +import 'features/register/presentation/bloc/register_bloc.dart'; import 'shared/components/bloc/bottom_nav_bar/bottom_navigation_bloc.dart'; import 'shared/components/bloc/language/lng_bloc.dart'; import 'shared/components/bloc/language/lng_event.dart'; @@ -105,6 +111,10 @@ class _MyAppState extends State with WidgetsBindingObserver { BlocProvider( create: (_) => GetCountryBlock(), ), + BlocProvider( + create: (_) => OTPBloc(), + ), + ], child: ScreenUtilInit( builder: (BuildContext context, Widget? child) => diff --git a/lib/shared/api/api_endpoints.dart b/lib/shared/api/api_endpoints.dart index 800a206..bca8cc1 100644 --- a/lib/shared/api/api_endpoints.dart +++ b/lib/shared/api/api_endpoints.dart @@ -1,6 +1,10 @@ class ApiEndpoints { + static const base="https://tanami.betadelivery.com/"; static const baseurl = "https://tanami.betadelivery.com/api/development/v1/"; //App Base url static const getcountryurl = baseurl + "country/getAllCountry"; + static const requestotpapi=baseurl +"auth/public/register"; + static const requestresendotp=baseurl+"auth/public/resend-otp"; + static const verifyotp=baseurl+"auth/public/verify-otp"; } diff --git a/lib/shared/api/network_api_services.dart b/lib/shared/api/network_api_services.dart index b3a486a..7382fc3 100644 --- a/lib/shared/api/network_api_services.dart +++ b/lib/shared/api/network_api_services.dart @@ -37,11 +37,30 @@ class NetworkApiService { } // Common function for POST requests - Future post(String url, dynamic data) async { + Future post(String url, dynamic data) async { + if (kDebugMode) { + print("data >>> $data"); + print("api url is >>> $url"); + } try { - return await _dio.post(url, data: data); + var response= await _dio.post(url, data: data); + if (response.statusCode == 201 || response.statusCode == 200) { + return ResponseData("success", ResponseStatus.SUCCESS, + data: response.data); + }else { + try { + return ResponseData( + response.data['message'].toString(), ResponseStatus.FAILED); + } catch (_) { + return ResponseData( + data: response.data, + response.statusMessage!, + ResponseStatus.FAILED); + }} } catch (e) { - throw _handleError(e); + return ResponseData( + "Oops something went wrong", + ResponseStatus.FAILED); } }