From acf7f8980f8f04f81fa3fe40d63f0c20c33ffe36 Mon Sep 17 00:00:00 2001 From: poojapandeyx Date: Thu, 11 Jul 2024 19:36:40 +0530 Subject: [PATCH] otp flow --- lib/Globalconst.dart | 6 + .../utils/constant/country_flag_data.dart | 12 ++ lib/features/OTP/Repository/OTP_API.dart | 23 ++++ lib/features/OTP/bloc/OTPStateEvent.dart | 37 ++++++ lib/features/OTP/bloc/OTP_bloc.dart | 48 ++++++++ .../pages/choose_country_layout.dart | 1 + .../widgets/country_selection_list.dart | 31 ++++- .../presentation/bloc/otp_bloc.dart | 12 +- .../presentation/pages/otp_screen.dart | 9 +- .../widgets/resend_otp_section.dart | 71 +++++++++++- .../presentation/bloc/register_bloc.dart | 43 +++++-- .../presentation/bloc/register_event.dart | 16 ++- .../presentation/bloc/register_state.dart | 9 +- .../widgets/register_bottom_section.dart | 18 ++- .../presentation/widgets/register_form.dart | 108 ++++++++++++++++-- lib/main.dart | 10 ++ lib/shared/api/api_endpoints.dart | 4 + lib/shared/api/network_api_services.dart | 25 +++- 18 files changed, 447 insertions(+), 36 deletions(-) create mode 100644 lib/Globalconst.dart create mode 100644 lib/features/OTP/Repository/OTP_API.dart create mode 100644 lib/features/OTP/bloc/OTPStateEvent.dart create mode 100644 lib/features/OTP/bloc/OTP_bloc.dart 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/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/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 6330367..9887941 100644 --- a/lib/features/countrySelection/presentation/widgets/country_selection_list.dart +++ b/lib/features/countrySelection/presentation/widgets/country_selection_list.dart @@ -1,5 +1,7 @@ +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'; @@ -7,6 +9,7 @@ import 'package:tanami_app/features/countrySelection/bloc/GetCountry/getcountry_ import 'package:tanami_app/features/countrySelection/bloc/GetCountry/getcountryevent_bloc.dart'; import 'package:tanami_app/shared/components/text_widget.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'; @@ -46,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/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/widgets/register_bottom_section.dart b/lib/features/register/presentation/widgets/register_bottom_section.dart index a678fd4..c88b474 100644 --- a/lib/features/register/presentation/widgets/register_bottom_section.dart +++ b/lib/features/register/presentation/widgets/register_bottom_section.dart @@ -7,6 +7,7 @@ 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'; @@ -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 e93007a..5af77bb 100644 --- a/lib/features/register/presentation/widgets/register_form.dart +++ b/lib/features/register/presentation/widgets/register_form.dart @@ -1,11 +1,16 @@ +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/bloc/GetCountry/getcountry_bloc.dart'; import '../../../countrySelection/bloc/choose_country_bloc.dart'; import '../../../countrySelection/bloc/choose_country_state.dart'; import '../bloc/register_bloc.dart'; @@ -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/main.dart b/lib/main.dart index f486a07..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/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); } }