From 2b9afe5b588dacb68139ebb80d3f8c4bb4cec733 Mon Sep 17 00:00:00 2001 From: "mirza.shafique" Date: Thu, 24 Nov 2022 15:47:33 +0300 Subject: [PATCH] 1st login flow completed --- android/app/src/main/AndroidManifest.xml | 3 + .../com/example/untitled1/MainActivity.kt | 15 +- assets/langs/ar-SA.json | 3 +- assets/langs/en-US.json | 3 +- lib/classes/enums.dart | 19 +- lib/classes/utils.dart | 15 +- lib/config/app_state.dart | 27 +- lib/config/routes.dart | 2 +- lib/generated/codegen_loader.g.dart | 6 +- lib/main.dart | 52 +- lib/model/base/generic_response_model.dart | 14 +- lib/model/base/generic_response_model2.dart | 911 ++++++++++++++++++ lib/model/base/post_params_model.dart | 4 + lib/model/login/doctor_profile_model.dart | 195 ++++ .../login/list_doctors_clinic_model.dart | 35 + lib/model/login/member_information_model.dart | 92 ++ lib/model/login/member_login_model.dart | 245 +++++ lib/provider/login_provider_model.dart | 164 +++- lib/services/api_repo/login_api_repo.dart | 99 +- lib/ui/login/login_method_page.dart | 206 ++-- lib/ui/login/login_page.dart | 204 ++-- lib/ui/login/login_vm.dart | 42 +- .../widgets/verification_method_card.dart | 110 ++- lib/widgets/cupertino_picker.dart | 4 +- lib/widgets/dialogs/otp_dialog.dart | 73 +- lib/widgets/input_widget.dart | 42 +- pubspec.lock | 30 +- pubspec.yaml | 3 +- 28 files changed, 2230 insertions(+), 388 deletions(-) create mode 100644 lib/model/base/generic_response_model2.dart create mode 100644 lib/model/login/doctor_profile_model.dart create mode 100644 lib/model/login/list_doctors_clinic_model.dart create mode 100644 lib/model/login/member_information_model.dart create mode 100644 lib/model/login/member_login_model.dart diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 41cb775..3309a2e 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,5 +1,8 @@ + + + LoadingDialog(), ).then((value) { @@ -69,12 +69,17 @@ class Utils { }); } - static void hideLoading(BuildContext context) { - if (_isLoadingVisible) { + static void hideLoading() { + try{ + if (_isLoadingVisible) { + _isLoadingVisible = false; + Navigator.of(navigatorKey.currentContext!).pop(); + } _isLoadingVisible = false; - Navigator.of(context).pop(); + }catch(e){ + print("exp_while_hide_dialog: "+e.toString()); } - _isLoadingVisible = false; + } static Future getStringFromPrefs(String key) async { diff --git a/lib/config/app_state.dart b/lib/config/app_state.dart index 219254e..138c5e9 100644 --- a/lib/config/app_state.dart +++ b/lib/config/app_state.dart @@ -2,6 +2,8 @@ import 'dart:io'; import 'package:easy_localization/easy_localization.dart'; import 'package:hmg_nurses/model/base/post_params_model.dart'; +import 'package:hmg_nurses/model/login/list_doctors_clinic_model.dart'; +import 'package:hmg_nurses/model/login/member_login_model.dart'; class AppState { // static final AppState _instance = AppState._internal(); @@ -10,6 +12,15 @@ class AppState { // // factory AppState() => _instance; + //Tokens + String? imei, logInTokenID, vidaAuthTokenID, vidaRefreshTokenID, authenticationTokenID; + + int projectID = 0; + int clinicId = 0; + + List? listDoctorsClinic; + String? password; + bool isAuthenticated = false; set setIsAuthenticated(v) => isAuthenticated = v; @@ -32,7 +43,7 @@ class AppState { String? get getForgetPasswordTokenID => forgetPasswordTokenID; - final PostParamsModel _postParamsInitConfig = PostParamsModel( + PostParamsModel _postParamsInitConfig = PostParamsModel( tokenID: "@dm!n", languageID: 2, stamp: "", @@ -45,6 +56,7 @@ class AppState { vidaAuthTokenID: null, vidaRefreshTokenID: null, deviceTypeID: 1, + generalID: 'Cs2020@2016\$2958', ); void setPostParamsInitConfig() { @@ -58,8 +70,11 @@ class AppState { PostParamsModel? get postParamsObject => _postParams; // Map get postParamsJson => isLogged ? (_postParams?.toJsonAfterLogin() ?? {}) : (_postParams?.toJson() ?? {}); - Map get postParamsJson{ - _postParams!.stamp=DateTime.now().toIso8601String(); + Map get postParamsJson { + _postParams!.stamp = DateTime.now().toIso8601String(); + _postParams?.vidaAuthTokenID = vidaAuthTokenID; + _postParams?.vidaRefreshTokenID = vidaRefreshTokenID; + _postParams?.imei = imei; return _postParams?.toJson() ?? {}; } @@ -76,4 +91,10 @@ class AppState { set setUserName(v) => _username = v; String? get getUserName => _username; + + MemberLoginModel? _memberBeforeLogin; + + MemberLoginModel? get memberBeforeLogin => _memberBeforeLogin; + + set setMemberBeforeLogin(MemberLoginModel? _memberBeforeLogin) => this._memberBeforeLogin = _memberBeforeLogin; } diff --git a/lib/config/routes.dart b/lib/config/routes.dart index d8a9abc..b820e3a 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -16,7 +16,7 @@ class AppRoutes { static final Map routes = { //Login splash: (BuildContext context) => SplashPage(), - login: (BuildContext context) => const LoginPage(), + login: (BuildContext context) => LoginPage(), loginMethodsPage: (BuildContext context) => const LoginMethodsPage(), }; diff --git a/lib/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart index 7d7ca5b..372810d 100644 --- a/lib/generated/codegen_loader.g.dart +++ b/lib/generated/codegen_loader.g.dart @@ -63,7 +63,8 @@ class CodegenLoader extends AssetLoader{ "verification": "تَحَقّق", "resend": "إعادة إرسال", "codeExpire": "انتهت صلاحية رمز التحقق", - "moreVerificationOpts": "المزيد من خيارات التحقق" + "moreVerificationOpts": "المزيد من خيارات التحقق", + "select": "Select" }; static const Map en_US = { "mohemm": "Mohemm", @@ -114,7 +115,8 @@ static const Map en_US = { "verification": "Verification", "resend": "Resend", "codeExpire": "The verification code has been expired", - "moreVerificationOpts": "More verification options" + "moreVerificationOpts": "More verification options", + "select": "Select" }; static const Map> mapLocales = {"ar_SA": ar_SA, "en_US": en_US}; } diff --git a/lib/main.dart b/lib/main.dart index 698ab60..77bbf8a 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -3,12 +3,14 @@ import 'dart:io'; import 'package:easy_localization/easy_localization.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/material.dart'; +import 'package:hmg_nurses/classes/size_config.dart'; import 'package:hmg_nurses/config/app_state.dart'; import 'package:hmg_nurses/config/dependencies.dart'; import 'package:hmg_nurses/config/routes.dart'; import 'package:hmg_nurses/provider/dashboard_provider_model.dart'; import 'package:hmg_nurses/provider/login_provider_model.dart'; import 'package:hmg_nurses/theme/app_theme.dart'; +import 'package:hmg_nurses/ui/login/login_vm.dart'; import 'package:injector/injector.dart'; import 'package:logger/logger.dart'; import 'package:provider/provider.dart'; @@ -19,7 +21,8 @@ import 'generated/codegen_loader.g.dart'; late AppState appState; -GlobalKey navigatorKey = GlobalKey(); +// GlobalKey navigatorKey = GlobalKey(); +final navigatorKey = GlobalKey(); Logger logger = Logger( // filter: null, // Use the default LogFilter (-> only log in debug mode) @@ -57,6 +60,9 @@ Future main() async { ), ChangeNotifierProvider( create: (_) => LoginProviderModel(), + ), + ChangeNotifierProvider( + create: (_) => LoginViewModel(), ) ], child: MyApp(), @@ -80,26 +86,32 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { - return Sizer( - builder: ( - BuildContext context, - Orientation orientation, - DeviceType deviceType, - ) { - List> delegates = context.localizationDelegates; - return MaterialApp( - key: navigatorKey, - theme: AppTheme.getTheme( - EasyLocalization.of(context)?.locale.languageCode == "ar", - ), - debugShowCheckedModeBanner: false, - localizationsDelegates: delegates, - supportedLocales: context.supportedLocales, - locale: context.locale, - initialRoute: AppRoutes.initialPage, - routes: AppRoutes.routes, + return LayoutBuilder( + builder: (context, constraints) { + return Sizer( + builder: ( + BuildContext context, + Orientation orientation, + DeviceType deviceType, + ) { + SizeConfig().init(constraints, orientation); + List> delegates = context.localizationDelegates; + return MaterialApp( + // key: navigatorKey, + navigatorKey: navigatorKey, + theme: AppTheme.getTheme( + EasyLocalization.of(context)?.locale.languageCode == "ar", + ), + debugShowCheckedModeBanner: false, + localizationsDelegates: delegates, + supportedLocales: context.supportedLocales, + locale: context.locale, + initialRoute: AppRoutes.initialPage, + routes: AppRoutes.routes, + ); + }, ); - }, + } ); } } diff --git a/lib/model/base/generic_response_model.dart b/lib/model/base/generic_response_model.dart index d7d14f2..bda03b2 100644 --- a/lib/model/base/generic_response_model.dart +++ b/lib/model/base/generic_response_model.dart @@ -5,6 +5,8 @@ import 'dart:convert'; import 'package:hmg_nurses/model/login/imei_details_model.dart'; +import 'package:hmg_nurses/model/login/list_doctors_clinic_model.dart'; +import 'package:hmg_nurses/model/login/member_information_model.dart'; import '../login/project_info_model.dart'; @@ -275,7 +277,7 @@ class GenericResponseModel { final List? listDoctorDeviceDetails; final dynamic listDoctorProfile; final dynamic listDoctorProgressNote; - final dynamic listDoctorsClinic; + final List? listDoctorsClinic; final dynamic listDoctorsAll; final dynamic listDrugToDrugTherapy; final dynamic listGetLabNormal; @@ -369,7 +371,7 @@ class GenericResponseModel { final dynamic listKeywords; final dynamic listProcedureCategories; final dynamic listProcedureResult; - final dynamic memberInformation; + final MemberInformation? memberInformation; final dynamic patientArrivalList; final dynamic requisitionList; final dynamic requisitionScheduleList; @@ -457,7 +459,7 @@ class GenericResponseModel { listDoctorDeviceDetails: json["List_DoctorDeviceDetails"] == null ? null : List.from(json["List_DoctorDeviceDetails"].map((x) => x)), listDoctorProfile: json["List_DoctorProfile"], listDoctorProgressNote: json["List_DoctorProgressNote"], - listDoctorsClinic: json["List_DoctorsClinic"], + listDoctorsClinic: json["List_DoctorsClinic"] == null ? null : List.from(json["List_DoctorsClinic"].map((x) => ListDoctorsClinicModel.fromJson(x))), listDoctorsAll: json["List_Doctors_All"], listDrugToDrugTherapy: json["List_DrugToDrugTherapy"], listGetLabNormal: json["List_GetLabNormal"], @@ -551,7 +553,7 @@ class GenericResponseModel { listKeywords: json["listKeywords"], listProcedureCategories: json["listProcedureCategories"], listProcedureResult: json["listProcedureResult"], - memberInformation: json["memberInformation"], + memberInformation: json["memberInformation"] == null ? null : MemberInformation.fromJson(json["memberInformation"]), patientArrivalList: json["patientArrivalList"], requisitionList: json["requisitionList"], requisitionScheduleList: json["requisitionScheduleList"], @@ -640,7 +642,7 @@ class GenericResponseModel { "List_DoctorDeviceDetails": listDoctorDeviceDetails == null ? null : List.from(listDoctorDeviceDetails!.map((x) => x)), "List_DoctorProfile": listDoctorProfile, "List_DoctorProgressNote": listDoctorProgressNote, - "List_DoctorsClinic": listDoctorsClinic, + "List_DoctorsClinic": listDoctorsClinic == null ? null : List.from(listDoctorsClinic!.map((x) => x.toJson())), "List_Doctors_All": listDoctorsAll, "List_DrugToDrugTherapy": listDrugToDrugTherapy, "List_GetLabNormal": listGetLabNormal, @@ -734,7 +736,7 @@ class GenericResponseModel { "listKeywords": listKeywords, "listProcedureCategories": listProcedureCategories, "listProcedureResult": listProcedureResult, - "memberInformation": memberInformation, + "memberInformation": memberInformation == null ? null : memberInformation!.toJson(), "patientArrivalList": patientArrivalList, "requisitionList": requisitionList, "requisitionScheduleList": requisitionScheduleList, diff --git a/lib/model/base/generic_response_model2.dart b/lib/model/base/generic_response_model2.dart new file mode 100644 index 0000000..40e7d46 --- /dev/null +++ b/lib/model/base/generic_response_model2.dart @@ -0,0 +1,911 @@ +// To parse this JSON data, do +// +// final genericResponseModel2 = genericResponseModel2FromJson(jsonString); + +import 'dart:convert'; + +import 'package:hmg_nurses/model/login/doctor_profile_model.dart'; + +GenericResponseModel2 genericResponseModel2FromJson(String str) => GenericResponseModel2.fromJson(json.decode(str)); + +String genericResponseModel2ToJson(GenericResponseModel2 data) => json.encode(data.toJson()); + +class GenericResponseModel2 { + GenericResponseModel2({ + this.date, + this.languageId, + this.serviceName, + this.time, + this.androidLink, + this.authenticationTokenId, + this.data, + this.dataw, + this.dietType, + this.dietTypeId, + this.errorCode, + this.errorEndUserMessage, + this.errorEndUserMessageN, + this.errorMessage, + this.errorType, + this.foodCategory, + this.iosLink, + this.isAuthenticated, + this.mealOrderStatus, + this.mealType, + this.messageStatus, + this.numberOfResultRecords, + this.patientBlodType, + this.successMsg, + this.successMsgN, + this.vidaUpdatedResponse, + this.ageError, + this.allowedBooking, + this.ancillaryOrderInvoiceList, + this.ancillaryOrderList, + this.ancillaryOrderListCount, + this.ancillaryOrderProcList, + this.appoimentAllHistoryResultList, + this.appoimentAllResultList, + this.appointmentActiveNumber, + this.appointmentNo, + this.appointmentQr, + this.avgDoctorRatingList, + this.covid19AppointmentResponse, + this.covid19FreeTimeSlots, + this.covid19InvoiceResponse, + this.covid19PatientShare, + this.covid19TestProceduresList, + this.clinicCategoryList, + this.clinicInsertedId, + this.clinicsHaveScheduleList, + this.continueBookAppointment, + this.dappTemplateGetList, + this.decimalDoctorRate, + this.dentalProcedure, + this.dentalProcedureName, + this.diseasesByClinicList, + this.doctorBasicScheduleList, + this.doctorByClinicIdList, + this.doctorByDiseaseList, + this.doctorCalenderList, + this.doctorInformationAsHtml, + this.doctorInformationRaw, + this.doctorList, + this.doctorPrePostImagesList, + this.doctorProfileList, + this.doctorRate, + this.doctorRatingDetailsList, + this.doctorScheduleMappingInsert, + this.doctorSchedulesByClinicList, + this.doctorscheduleslotInsert, + this.doctorscheduleslotSelectList, + this.erAppointmentFeesObject, + this.erAdvancePaymentResponse, + this.erOnlinePaymentDetailsResponse, + this.erPatientShare, + this.erTriageQuestionsList, + this.errCode, + this.errorSearchMsg, + this.formId, + this.freeTimeSlots, + this.genderError, + this.getDoctorMobileNo, + this.getPatientInfoByPatientIdList, + this.getPatientMedicalStatus, + this.hisGetAllAppoimentHistoryList, + this.hisGetDoctorOffDaysList, + this.hisObgyneUltrasoundDoctorsList, + this.hisProcedureTemplateDetailsList, + this.hisProcedureTemplateList, + this.hisWaitingCheckDoctorAvailableForWaitingAppointmentList, + this.hisObGyneProcedureGetResponse, + this.hisPrmGetApprovalRemarkList, + this.hoursDiff, + this.isDentalplan, + this.isMobileAppDentalAllow, + this.initialSlotDuration, + this.isAllowToBookWaitingAppointment, + this.isAllowVClinic, + this.isAllowWaitList, + this.isAppointmentAllowed, + this.isClinicEnabledForIcdCodes, + this.isDoctorExist, + this.isInsertOrUpdate, + this.isLastAppoitmentRatedList, + this.isShowInsuranceUpdateModule, + this.isSlotAvailable, + this.lcGetClinicScheduleList, + this.listHoursDiff, + this.listReqTypes, + this.listAllClinicRate, + this.listAllDoctorRate, + this.listAllProjectRate, + this.listCovid19DoctorsByClinicAndProject, + this.listCovid19ProjectDriveThroughTestingCenter, + this.listCalculationTable, + this.listDdAdminMembers, + this.listDentalChiefComplain, + this.listDentalDdDetails, + this.listDentalDoctorChiefComplaintMapping, + this.listDentalPediatricDoctor, + this.listDoctorAll, + this.listDoctorByIpAddressCheckIn, + this.listDoctorByProjectClinicAr, + this.listDoctorByProjectClinicEn, + this.listDoctorCases, + this.listDoctorClinics, + this.listDoctorDetailsList, + this.listDoctorDetailsListAr, + this.listDoctorLanguages, + this.listDoctorMappinsgs, + this.listDoctorPatientVitalSign, + this.listDoctorProcedureMapping, + this.listDoctorProfileImage, + this.listDoctorProject, + this.listDoctorQualifications, + this.listDoctorSlotFirstVisit, + this.listDoctorSpeciality, + this.listDoctorSpecializations, + this.listDoctorWorkingHoursTable, + this.listDoctorblacklistModel, + this.listDoctorinfo, + this.listEnglish, + this.listGetAllCancelAppointmentReasons, + this.listGetAllClinicsRoomNo, + this.listGetAllDoctorsOnProject, + this.listGetAllDoctorsbyProject, + this.listGetAppForCancel, + this.listGetClinicsInfobyProject, + this.listGetClinicsbyProject, + this.listGetDoctorsbyProject, + this.listGetIpAddressForDd, + this.listGetIpAddressForDentalDd, + this.listGetInfoForDentalClinicsDd, + this.listGetLoginDetails, + this.listGetPatientCancelAppointment, + this.listHisDoctorProject, + this.listHisGetContactLensPerscription, + this.listHisGetGlassPerscription, + this.listHmgPartTimeDoctor, + this.listInvoiceDetails, + this.listIsPatientHasOnGoingEstimation, + this.listLaserDoctors, + this.listLaserProcedures, + this.listMedicalReportByAppointment, + this.listNonAdminProjectMapping, + this.listPatientErAdminServiceModel, + this.listPatientErDoctorBlackListModel, + this.listPhysioDoctors, + this.listProjectErpMapping, + this.listRecordByIpAddress, + this.listRecordByIpAddressNew, + this.listRecordByIpAddressNewCheckIn, + this.listRecordByIpAddressNewForDubai, + this.listRescahdualOnlineModel, + this.message, + this.notesDoctorRatingForCocList, + this.notesDoctorRatingList, + this.onlineCheckInAppointments, + this.onlineCheckinBeforeHour, + this.prmAdmissionInfoList, + this.prmDentalEstimationDetailList, + this.prmDentalEstimationList, + this.prmDoctorsForRadiologyList, + this.prmGetErToOpdRequestStatusList, + this.prmGetDoctorRatingList, + this.prmGetProceureAndPackagesList, + this.prmHisAppointmentqueuegetList, + this.prmHisCheckDoctorIsFullyBookedList, + this.prmHisGetDentalEstimationPlanList, + this.prmHisGetDischargeInfoList, + this.prmHisGetUpcomingConfirmedAppoimentList, + this.prmHisQueueErToOpList, + this.prmQueueERreferralHistoryGetList, + this.prmSpecialClinicalCareMappingList, + this.patientDoctorAppointmentResultExit, + this.patientDoctorAppointmentResultList, + this.patientErDoctorFreeSlots, + this.patientErGetAllClinicsList, + this.patientErGetDoctorClincByServiceIdList, + this.patientErGetServiceList, + this.patientErLogininsert, + this.patientErPrescriptionLogin, + this.patientErSelectAdmin, + this.patientErSelectRole2, + this.patientErUpdateLiveCareStatus, + this.patientErInsert, + this.patientInformationList, + this.patientNumber, + this.paymentModes, + this.physioIsPatientHasApproval, + this.physiotherapyError, + this.procedureNeedeTime, + this.riskScore, + this.rowCount, + this.sameClinicApptList, + this.searchDoctorsByTimeIsVoiceCommandList, + this.slotDuration, + this.statusCode, + this.tamaraIntegrationLogsInsertResponse, + this.tamaraIntegrationLogsUpdateResponse, + this.transactionNo, + this.userDentalPlanMessage, + this.waitingAppointmentNoPerDay, + this.age, + this.erpDoctorDetails, + this.returnValue, + }); + + final dynamic date; + final int? languageId; + final int? serviceName; + final dynamic time; + final dynamic androidLink; + final dynamic authenticationTokenId; + final dynamic data; + final bool? dataw; + final int? dietType; + final int? dietTypeId; + final dynamic errorCode; + final dynamic errorEndUserMessage; + final dynamic errorEndUserMessageN; + final dynamic errorMessage; + final int? errorType; + final int? foodCategory; + final dynamic iosLink; + final bool? isAuthenticated; + final int? mealOrderStatus; + final int? mealType; + final int? messageStatus; + final int? numberOfResultRecords; + final dynamic patientBlodType; + final dynamic successMsg; + final dynamic successMsgN; + final dynamic vidaUpdatedResponse; + final bool? ageError; + final bool? allowedBooking; + final dynamic ancillaryOrderInvoiceList; + final dynamic ancillaryOrderList; + final int? ancillaryOrderListCount; + final dynamic ancillaryOrderProcList; + final dynamic appoimentAllHistoryResultList; + final dynamic appoimentAllResultList; + final int? appointmentActiveNumber; + final dynamic appointmentNo; + final dynamic appointmentQr; + final dynamic avgDoctorRatingList; + final dynamic covid19AppointmentResponse; + final dynamic covid19FreeTimeSlots; + final dynamic covid19InvoiceResponse; + final dynamic covid19PatientShare; + final dynamic covid19TestProceduresList; + final dynamic clinicCategoryList; + final int? clinicInsertedId; + final dynamic clinicsHaveScheduleList; + final bool? continueBookAppointment; + final dynamic dappTemplateGetList; + final int? decimalDoctorRate; + final dynamic dentalProcedure; + final dynamic dentalProcedureName; + final dynamic diseasesByClinicList; + final dynamic doctorBasicScheduleList; + final dynamic doctorByClinicIdList; + final dynamic doctorByDiseaseList; + final dynamic doctorCalenderList; + final dynamic doctorInformationAsHtml; + final dynamic doctorInformationRaw; + final dynamic doctorList; + final dynamic doctorPrePostImagesList; + final List? doctorProfileList; + final int? doctorRate; + final dynamic doctorRatingDetailsList; + final int? doctorScheduleMappingInsert; + final dynamic doctorSchedulesByClinicList; + final int? doctorscheduleslotInsert; + final dynamic doctorscheduleslotSelectList; + final dynamic erAppointmentFeesObject; + final dynamic erAdvancePaymentResponse; + final dynamic erOnlinePaymentDetailsResponse; + final dynamic erPatientShare; + final dynamic erTriageQuestionsList; + final dynamic errCode; + final dynamic errorSearchMsg; + final int? formId; + final dynamic freeTimeSlots; + final bool? genderError; + final dynamic getDoctorMobileNo; + final dynamic getPatientInfoByPatientIdList; + final dynamic getPatientMedicalStatus; + final dynamic hisGetAllAppoimentHistoryList; + final dynamic hisGetDoctorOffDaysList; + final dynamic hisObgyneUltrasoundDoctorsList; + final dynamic hisProcedureTemplateDetailsList; + final dynamic hisProcedureTemplateList; + final dynamic hisWaitingCheckDoctorAvailableForWaitingAppointmentList; + final dynamic hisObGyneProcedureGetResponse; + final dynamic hisPrmGetApprovalRemarkList; + final int? hoursDiff; + final bool? isDentalplan; + final bool? isMobileAppDentalAllow; + final int? initialSlotDuration; + final bool? isAllowToBookWaitingAppointment; + final bool? isAllowVClinic; + final bool? isAllowWaitList; + final bool? isAppointmentAllowed; + final bool? isClinicEnabledForIcdCodes; + final bool? isDoctorExist; + final int? isInsertOrUpdate; + final dynamic isLastAppoitmentRatedList; + final bool? isShowInsuranceUpdateModule; + final int? isSlotAvailable; + final dynamic lcGetClinicScheduleList; + final dynamic listHoursDiff; + final dynamic listReqTypes; + final dynamic listAllClinicRate; + final dynamic listAllDoctorRate; + final dynamic listAllProjectRate; + final dynamic listCovid19DoctorsByClinicAndProject; + final dynamic listCovid19ProjectDriveThroughTestingCenter; + final dynamic listCalculationTable; + final dynamic listDdAdminMembers; + final dynamic listDentalChiefComplain; + final dynamic listDentalDdDetails; + final dynamic listDentalDoctorChiefComplaintMapping; + final dynamic listDentalPediatricDoctor; + final dynamic listDoctorAll; + final dynamic listDoctorByIpAddressCheckIn; + final dynamic listDoctorByProjectClinicAr; + final dynamic listDoctorByProjectClinicEn; + final dynamic listDoctorCases; + final dynamic listDoctorClinics; + final dynamic listDoctorDetailsList; + final dynamic listDoctorDetailsListAr; + final dynamic listDoctorLanguages; + final dynamic listDoctorMappinsgs; + final dynamic listDoctorPatientVitalSign; + final dynamic listDoctorProcedureMapping; + final dynamic listDoctorProfileImage; + final dynamic listDoctorProject; + final dynamic listDoctorQualifications; + final dynamic listDoctorSlotFirstVisit; + final dynamic listDoctorSpeciality; + final dynamic listDoctorSpecializations; + final dynamic listDoctorWorkingHoursTable; + final dynamic listDoctorblacklistModel; + final dynamic listDoctorinfo; + final dynamic listEnglish; + final dynamic listGetAllCancelAppointmentReasons; + final dynamic listGetAllClinicsRoomNo; + final dynamic listGetAllDoctorsOnProject; + final dynamic listGetAllDoctorsbyProject; + final dynamic listGetAppForCancel; + final dynamic listGetClinicsInfobyProject; + final dynamic listGetClinicsbyProject; + final dynamic listGetDoctorsbyProject; + final dynamic listGetIpAddressForDd; + final dynamic listGetIpAddressForDentalDd; + final dynamic listGetInfoForDentalClinicsDd; + final dynamic listGetLoginDetails; + final dynamic listGetPatientCancelAppointment; + final dynamic listHisDoctorProject; + final dynamic listHisGetContactLensPerscription; + final dynamic listHisGetGlassPerscription; + final dynamic listHmgPartTimeDoctor; + final dynamic listInvoiceDetails; + final dynamic listIsPatientHasOnGoingEstimation; + final dynamic listLaserDoctors; + final dynamic listLaserProcedures; + final dynamic listMedicalReportByAppointment; + final dynamic listNonAdminProjectMapping; + final dynamic listPatientErAdminServiceModel; + final dynamic listPatientErDoctorBlackListModel; + final dynamic listPhysioDoctors; + final dynamic listProjectErpMapping; + final dynamic listRecordByIpAddress; + final dynamic listRecordByIpAddressNew; + final dynamic listRecordByIpAddressNewCheckIn; + final dynamic listRecordByIpAddressNewForDubai; + final dynamic listRescahdualOnlineModel; + final dynamic message; + final dynamic notesDoctorRatingForCocList; + final dynamic notesDoctorRatingList; + final dynamic onlineCheckInAppointments; + final int? onlineCheckinBeforeHour; + final dynamic prmAdmissionInfoList; + final dynamic prmDentalEstimationDetailList; + final dynamic prmDentalEstimationList; + final dynamic prmDoctorsForRadiologyList; + final dynamic prmGetErToOpdRequestStatusList; + final dynamic prmGetDoctorRatingList; + final dynamic prmGetProceureAndPackagesList; + final dynamic prmHisAppointmentqueuegetList; + final dynamic prmHisCheckDoctorIsFullyBookedList; + final dynamic prmHisGetDentalEstimationPlanList; + final dynamic prmHisGetDischargeInfoList; + final dynamic prmHisGetUpcomingConfirmedAppoimentList; + final dynamic prmHisQueueErToOpList; + final dynamic prmQueueERreferralHistoryGetList; + final dynamic prmSpecialClinicalCareMappingList; + final bool? patientDoctorAppointmentResultExit; + final dynamic patientDoctorAppointmentResultList; + final dynamic patientErDoctorFreeSlots; + final dynamic patientErGetAllClinicsList; + final dynamic patientErGetDoctorClincByServiceIdList; + final dynamic patientErGetServiceList; + final int? patientErLogininsert; + final dynamic patientErPrescriptionLogin; + final dynamic patientErSelectAdmin; + final dynamic patientErSelectRole2; + final int? patientErUpdateLiveCareStatus; + final int? patientErInsert; + final dynamic patientInformationList; + final int? patientNumber; + final dynamic paymentModes; + final bool? physioIsPatientHasApproval; + final int? physiotherapyError; + final dynamic procedureNeedeTime; + final int? riskScore; + final int? rowCount; + final dynamic sameClinicApptList; + final dynamic searchDoctorsByTimeIsVoiceCommandList; + final int? slotDuration; + final int? statusCode; + final int? tamaraIntegrationLogsInsertResponse; + final int? tamaraIntegrationLogsUpdateResponse; + final dynamic transactionNo; + final dynamic userDentalPlanMessage; + final int? waitingAppointmentNoPerDay; + final int? age; + final dynamic erpDoctorDetails; + final int? returnValue; + + factory GenericResponseModel2.fromJson(Map json) => GenericResponseModel2( + date: json["Date"], + languageId: json["LanguageID"] == null ? null : json["LanguageID"], + serviceName: json["ServiceName"] == null ? null : json["ServiceName"], + time: json["Time"], + androidLink: json["AndroidLink"], + authenticationTokenId: json["AuthenticationTokenID"], + data: json["Data"], + dataw: json["Dataw"] == null ? null : json["Dataw"], + dietType: json["DietType"] == null ? null : json["DietType"], + dietTypeId: json["DietTypeID"] == null ? null : json["DietTypeID"], + errorCode: json["ErrorCode"], + errorEndUserMessage: json["ErrorEndUserMessage"], + errorEndUserMessageN: json["ErrorEndUserMessageN"], + errorMessage: json["ErrorMessage"], + errorType: json["ErrorType"] == null ? null : json["ErrorType"], + foodCategory: json["FoodCategory"] == null ? null : json["FoodCategory"], + iosLink: json["IOSLink"], + isAuthenticated: json["IsAuthenticated"] == null ? null : json["IsAuthenticated"], + mealOrderStatus: json["MealOrderStatus"] == null ? null : json["MealOrderStatus"], + mealType: json["MealType"] == null ? null : json["MealType"], + messageStatus: json["MessageStatus"] == null ? null : json["MessageStatus"], + numberOfResultRecords: json["NumberOfResultRecords"] == null ? null : json["NumberOfResultRecords"], + patientBlodType: json["PatientBlodType"], + successMsg: json["SuccessMsg"], + successMsgN: json["SuccessMsgN"], + vidaUpdatedResponse: json["VidaUpdatedResponse"], + ageError: json["AgeError"] == null ? null : json["AgeError"], + allowedBooking: json["AllowedBooking"] == null ? null : json["AllowedBooking"], + ancillaryOrderInvoiceList: json["AncillaryOrderInvoiceList"], + ancillaryOrderList: json["AncillaryOrderList"], + ancillaryOrderListCount: json["AncillaryOrderListCount"] == null ? null : json["AncillaryOrderListCount"], + ancillaryOrderProcList: json["AncillaryOrderProcList"], + appoimentAllHistoryResultList: json["AppoimentAllHistoryResultList"], + appoimentAllResultList: json["AppoimentAllResultList"], + appointmentActiveNumber: json["AppointmentActiveNumber"] == null ? null : json["AppointmentActiveNumber"], + appointmentNo: json["AppointmentNo"], + appointmentQr: json["AppointmentQR"], + avgDoctorRatingList: json["AvgDoctorRatingList"], + covid19AppointmentResponse: json["COVID19_AppointmentResponse"], + covid19FreeTimeSlots: json["COVID19_FreeTimeSlots"], + covid19InvoiceResponse: json["COVID19_InvoiceResponse"], + covid19PatientShare: json["COVID19_PatientShare"], + covid19TestProceduresList: json["COVID19_TestProceduresList"], + clinicCategoryList: json["ClinicCategoryList"], + clinicInsertedId: json["ClinicInsertedID"] == null ? null : json["ClinicInsertedID"], + clinicsHaveScheduleList: json["ClinicsHaveScheduleList"], + continueBookAppointment: json["ContinueBookAppointment"] == null ? null : json["ContinueBookAppointment"], + dappTemplateGetList: json["DAPP_TemplateGetList"], + decimalDoctorRate: json["DecimalDoctorRate"] == null ? null : json["DecimalDoctorRate"], + dentalProcedure: json["DentalProcedure"], + dentalProcedureName: json["DentalProcedureName"], + diseasesByClinicList: json["DiseasesByClinicList"], + doctorBasicScheduleList: json["DoctorBasicScheduleList"], + doctorByClinicIdList: json["DoctorByClinicIDList"], + doctorByDiseaseList: json["DoctorByDiseaseList"], + doctorCalenderList: json["DoctorCalenderList"], + doctorInformationAsHtml: json["DoctorInformationAsHTML"], + doctorInformationRaw: json["DoctorInformationRAW"], + doctorList: json["DoctorList"], + doctorPrePostImagesList: json["DoctorPrePostImagesList"], + doctorProfileList: json["DoctorProfileList"] == null ? null : List.from(json["DoctorProfileList"].map((x) => DoctorProfileListModel.fromJson(x))), + doctorRate: json["DoctorRate"] == null ? null : json["DoctorRate"], + doctorRatingDetailsList: json["DoctorRatingDetailsList"], + doctorScheduleMappingInsert: json["DoctorScheduleMapping_Insert"] == null ? null : json["DoctorScheduleMapping_Insert"], + doctorSchedulesByClinicList: json["DoctorSchedulesByClinicList"], + doctorscheduleslotInsert: json["Doctorscheduleslot_Insert"] == null ? null : json["Doctorscheduleslot_Insert"], + doctorscheduleslotSelectList: json["Doctorscheduleslot_SelectList"], + erAppointmentFeesObject: json["ERAppointmentFeesObject"], + erAdvancePaymentResponse: json["ER_AdvancePaymentResponse"], + erOnlinePaymentDetailsResponse: json["ER_OnlinePaymentDetailsResponse"], + erPatientShare: json["ER_PatientShare"], + erTriageQuestionsList: json["ER_TriageQuestionsList"], + errCode: json["ErrCode"], + errorSearchMsg: json["ErrorSearchMsg"], + formId: json["FormID"] == null ? null : json["FormID"], + freeTimeSlots: json["FreeTimeSlots"], + genderError: json["GenderError"] == null ? null : json["GenderError"], + getDoctorMobileNo: json["GetDoctorMobileNo"], + getPatientInfoByPatientIdList: json["GetPatientInfoByPatientIDList"], + getPatientMedicalStatus: json["GetPatientMedicalStatus"], + hisGetAllAppoimentHistoryList: json["HIS_GetAllAppoimentHistoryList"], + hisGetDoctorOffDaysList: json["HIS_GetDoctorOffDaysList"], + hisObgyneUltrasoundDoctorsList: json["HIS_ObgyneUltrasoundDoctorsList"], + hisProcedureTemplateDetailsList: json["HIS_ProcedureTemplateDetailsList"], + hisProcedureTemplateList: json["HIS_ProcedureTemplateList"], + hisWaitingCheckDoctorAvailableForWaitingAppointmentList: json["HIS_Waiting_CheckDoctorAvailableForWaitingAppointment_List"], + hisObGyneProcedureGetResponse: json["His_ObGyneProcedureGet_Response"], + hisPrmGetApprovalRemarkList: json["His_PRM_GetApprovalRemarkList"], + hoursDiff: json["HoursDiff"] == null ? null : json["HoursDiff"], + isDentalplan: json["ISDentalplan"] == null ? null : json["ISDentalplan"], + isMobileAppDentalAllow: json["ISMobileAppDentalAllow"] == null ? null : json["ISMobileAppDentalAllow"], + initialSlotDuration: json["InitialSlotDuration"] == null ? null : json["InitialSlotDuration"], + isAllowToBookWaitingAppointment: json["IsAllowToBookWaitingAppointment"] == null ? null : json["IsAllowToBookWaitingAppointment"], + isAllowVClinic: json["IsAllowVClinic"] == null ? null : json["IsAllowVClinic"], + isAllowWaitList: json["IsAllowWaitList"] == null ? null : json["IsAllowWaitList"], + isAppointmentAllowed: json["IsAppointmentAllowed"] == null ? null : json["IsAppointmentAllowed"], + isClinicEnabledForIcdCodes: json["IsClinicEnabledForICDCodes"] == null ? null : json["IsClinicEnabledForICDCodes"], + isDoctorExist: json["IsDoctorExist"] == null ? null : json["IsDoctorExist"], + isInsertOrUpdate: json["IsInsertOrUpdate"] == null ? null : json["IsInsertOrUpdate"], + isLastAppoitmentRatedList: json["IsLastAppoitmentRatedList"], + isShowInsuranceUpdateModule: json["IsShowInsuranceUpdateModule"] == null ? null : json["IsShowInsuranceUpdateModule"], + isSlotAvailable: json["IsSlotAvailable"] == null ? null : json["IsSlotAvailable"], + lcGetClinicScheduleList: json["LC_GetClinicScheduleList"], + listHoursDiff: json["ListHoursDiff"], + listReqTypes: json["ListReqTypes"], + listAllClinicRate: json["List_AllClinicRate"], + listAllDoctorRate: json["List_AllDoctorRate"], + listAllProjectRate: json["List_AllProjectRate"], + listCovid19DoctorsByClinicAndProject: json["List_COVID19_DoctorsByClinicAndProject"], + listCovid19ProjectDriveThroughTestingCenter: json["List_COVID19_ProjectDriveThroughTestingCenter"], + listCalculationTable: json["List_CalculationTable"], + listDdAdminMembers: json["List_DDAdmin_Members"], + listDentalChiefComplain: json["List_DentalChiefComplain"], + listDentalDdDetails: json["List_DentalDDDetails"], + listDentalDoctorChiefComplaintMapping: json["List_DentalDoctorChiefComplaintMapping"], + listDentalPediatricDoctor: json["List_DentalPediatricDoctor"], + listDoctorAll: json["List_DoctorAll"], + listDoctorByIpAddressCheckIn: json["List_DoctorByIPAddressCheckIn"], + listDoctorByProjectClinicAr: json["List_DoctorByProjectClinicAr"], + listDoctorByProjectClinicEn: json["List_DoctorByProjectClinicEn"], + listDoctorCases: json["List_DoctorCases"], + listDoctorClinics: json["List_DoctorClinics"], + listDoctorDetailsList: json["List_DoctorDetailsList"], + listDoctorDetailsListAr: json["List_DoctorDetailsListAr"], + listDoctorLanguages: json["List_DoctorLanguages"], + listDoctorMappinsgs: json["List_DoctorMappinsgs"], + listDoctorPatientVitalSign: json["List_DoctorPatientVitalSign"], + listDoctorProcedureMapping: json["List_DoctorProcedureMapping"], + listDoctorProfileImage: json["List_DoctorProfileImage"], + listDoctorProject: json["List_DoctorProject"], + listDoctorQualifications: json["List_DoctorQualifications"], + listDoctorSlotFirstVisit: json["List_DoctorSlotFirstVisit"], + listDoctorSpeciality: json["List_DoctorSpeciality"], + listDoctorSpecializations: json["List_DoctorSpecializations"], + listDoctorWorkingHoursTable: json["List_DoctorWorkingHoursTable"], + listDoctorblacklistModel: json["List_DoctorblacklistModel"], + listDoctorinfo: json["List_Doctorinfo"], + listEnglish: json["List_English"], + listGetAllCancelAppointmentReasons: json["List_GetAllCancelAppointmentReasons"], + listGetAllClinicsRoomNo: json["List_GetAllClinicsRoomNo"], + listGetAllDoctorsOnProject: json["List_GetAllDoctorsOnProject"], + listGetAllDoctorsbyProject: json["List_GetAllDoctorsbyProject"], + listGetAppForCancel: json["List_GetAppForCancel"], + listGetClinicsInfobyProject: json["List_GetClinicsInfobyProject"], + listGetClinicsbyProject: json["List_GetClinicsbyProject"], + listGetDoctorsbyProject: json["List_GetDoctorsbyProject"], + listGetIpAddressForDd: json["List_GetIPAddressForDD"], + listGetIpAddressForDentalDd: json["List_GetIPAddressForDentalDD"], + listGetInfoForDentalClinicsDd: json["List_GetInfoForDentalClinicsDD"], + listGetLoginDetails: json["List_GetLoginDetails"], + listGetPatientCancelAppointment: json["List_GetPatientCancelAppointment"], + listHisDoctorProject: json["List_HISDoctorProject"], + listHisGetContactLensPerscription: json["List_HIS_GetContactLensPerscription"], + listHisGetGlassPerscription: json["List_HIS_GetGlassPerscription"], + listHmgPartTimeDoctor: json["List_HmgPartTimeDoctor"], + listInvoiceDetails: json["List_InvoiceDetails"], + listIsPatientHasOnGoingEstimation: json["List_IsPatientHasOnGoingEstimation"], + listLaserDoctors: json["List_LaserDoctors"], + listLaserProcedures: json["List_LaserProcedures"], + listMedicalReportByAppointment: json["List_MedicalReportByAppointment"], + listNonAdminProjectMapping: json["List_NonAdminProjectMapping"], + listPatientErAdminServiceModel: json["List_PatientER_AdminServiceModel"], + listPatientErDoctorBlackListModel: json["List_PatientER_DoctorBlackListModel"], + listPhysioDoctors: json["List_PhysioDoctors"], + listProjectErpMapping: json["List_ProjectERPMapping"], + listRecordByIpAddress: json["List_RecordByIPAddress"], + listRecordByIpAddressNew: json["List_RecordByIPAddressNew"], + listRecordByIpAddressNewCheckIn: json["List_RecordByIPAddressNewCheckIn"], + listRecordByIpAddressNewForDubai: json["List_RecordByIPAddressNewForDubai"], + listRescahdualOnlineModel: json["List_RescahdualOnlineModel"], + message: json["Message"], + notesDoctorRatingForCocList: json["NotesDoctorRatingForCOC_List"], + notesDoctorRatingList: json["NotesDoctorRatingList"], + onlineCheckInAppointments: json["OnlineCheckInAppointments"], + onlineCheckinBeforeHour: json["OnlineCheckinBeforeHour"] == null ? null : json["OnlineCheckinBeforeHour"], + prmAdmissionInfoList: json["PRM_AdmissionInfoList"], + prmDentalEstimationDetailList: json["PRM_DentalEstimationDetailList"], + prmDentalEstimationList: json["PRM_DentalEstimationList"], + prmDoctorsForRadiologyList: json["PRM_DoctorsForRadiologyList"], + prmGetErToOpdRequestStatusList: json["PRM_GET_ERToOPDRequestStatusList"], + prmGetDoctorRatingList: json["PRM_GetDoctorRatingList"], + prmGetProceureAndPackagesList: json["PRM_GetProceureAndPackagesList"], + prmHisAppointmentqueuegetList: json["PRM_HIS_AppointmentqueuegetList"], + prmHisCheckDoctorIsFullyBookedList: json["PRM_HIS_CheckDoctorIsFullyBookedList"], + prmHisGetDentalEstimationPlanList: json["PRM_HIS_GetDentalEstimationPlan_List"], + prmHisGetDischargeInfoList: json["PRM_HIS_GetDischargeInfo_List"], + prmHisGetUpcomingConfirmedAppoimentList: json["PRM_HIS_GetUpcomingConfirmedAppoimentList"], + prmHisQueueErToOpList: json["PRM_HIS_QueueERToOP_List"], + prmQueueERreferralHistoryGetList: json["PRM_QueueERreferralHistory_getList"], + prmSpecialClinicalCareMappingList: json["PRM_SpecialClinicalCareMapping_List"], + patientDoctorAppointmentResultExit: json["PatientDoctorAppointmentResultExit"] == null ? null : json["PatientDoctorAppointmentResultExit"], + patientDoctorAppointmentResultList: json["PatientDoctorAppointmentResultList"], + patientErDoctorFreeSlots: json["PatientER_DoctorFreeSlots"], + patientErGetAllClinicsList: json["PatientER_GetAllClinics_List"], + patientErGetDoctorClincByServiceIdList: json["PatientER_GetDoctorClincByServiceID_List"], + patientErGetServiceList: json["PatientER_GetServiceList"], + patientErLogininsert: json["PatientER_Logininsert"] == null ? null : json["PatientER_Logininsert"], + patientErPrescriptionLogin: json["PatientER_PrescriptionLogin"], + patientErSelectAdmin: json["PatientER_SelectAdmin"], + patientErSelectRole2: json["PatientER_SelectRole2"], + patientErUpdateLiveCareStatus: json["PatientER_UpdateLiveCareStatus"] == null ? null : json["PatientER_UpdateLiveCareStatus"], + patientErInsert: json["PatientER_insert"] == null ? null : json["PatientER_insert"], + patientInformationList: json["PatientInformationList"], + patientNumber: json["PatientNumber"] == null ? null : json["PatientNumber"], + paymentModes: json["PaymentModes"], + physioIsPatientHasApproval: json["Physio_IsPatientHasApproval"] == null ? null : json["Physio_IsPatientHasApproval"], + physiotherapyError: json["PhysiotherapyError"] == null ? null : json["PhysiotherapyError"], + procedureNeedeTime: json["ProcedureNeedeTime"], + riskScore: json["RiskScore"] == null ? null : json["RiskScore"], + rowCount: json["RowCount"] == null ? null : json["RowCount"], + sameClinicApptList: json["SameClinicApptList"], + searchDoctorsByTimeIsVoiceCommandList: json["SearchDoctorsByTime_IsVoiceCommandList"], + slotDuration: json["SlotDuration"] == null ? null : json["SlotDuration"], + statusCode: json["StatusCode"] == null ? null : json["StatusCode"], + tamaraIntegrationLogsInsertResponse: json["Tamara_IntegrationLogsInsert_Response"] == null ? null : json["Tamara_IntegrationLogsInsert_Response"], + tamaraIntegrationLogsUpdateResponse: json["Tamara_IntegrationLogsUpdate_Response"] == null ? null : json["Tamara_IntegrationLogsUpdate_Response"], + transactionNo: json["TransactionNo"], + userDentalPlanMessage: json["UserDentalPlanMessage"], + waitingAppointmentNoPerDay: json["WaitingAppointmentNoPerDay"] == null ? null : json["WaitingAppointmentNoPerDay"], + age: json["age"] == null ? null : json["age"], + erpDoctorDetails: json["erpDoctorDetails"], + returnValue: json["returnValue"] == null ? null : json["returnValue"], + ); + + Map toJson() => { + "Date": date, + "LanguageID": languageId == null ? null : languageId, + "ServiceName": serviceName == null ? null : serviceName, + "Time": time, + "AndroidLink": androidLink, + "AuthenticationTokenID": authenticationTokenId, + "Data": data, + "Dataw": dataw == null ? null : dataw, + "DietType": dietType == null ? null : dietType, + "DietTypeID": dietTypeId == null ? null : dietTypeId, + "ErrorCode": errorCode, + "ErrorEndUserMessage": errorEndUserMessage, + "ErrorEndUserMessageN": errorEndUserMessageN, + "ErrorMessage": errorMessage, + "ErrorType": errorType == null ? null : errorType, + "FoodCategory": foodCategory == null ? null : foodCategory, + "IOSLink": iosLink, + "IsAuthenticated": isAuthenticated == null ? null : isAuthenticated, + "MealOrderStatus": mealOrderStatus == null ? null : mealOrderStatus, + "MealType": mealType == null ? null : mealType, + "MessageStatus": messageStatus == null ? null : messageStatus, + "NumberOfResultRecords": numberOfResultRecords == null ? null : numberOfResultRecords, + "PatientBlodType": patientBlodType, + "SuccessMsg": successMsg, + "SuccessMsgN": successMsgN, + "VidaUpdatedResponse": vidaUpdatedResponse, + "AgeError": ageError == null ? null : ageError, + "AllowedBooking": allowedBooking == null ? null : allowedBooking, + "AncillaryOrderInvoiceList": ancillaryOrderInvoiceList, + "AncillaryOrderList": ancillaryOrderList, + "AncillaryOrderListCount": ancillaryOrderListCount == null ? null : ancillaryOrderListCount, + "AncillaryOrderProcList": ancillaryOrderProcList, + "AppoimentAllHistoryResultList": appoimentAllHistoryResultList, + "AppoimentAllResultList": appoimentAllResultList, + "AppointmentActiveNumber": appointmentActiveNumber == null ? null : appointmentActiveNumber, + "AppointmentNo": appointmentNo, + "AppointmentQR": appointmentQr, + "AvgDoctorRatingList": avgDoctorRatingList, + "COVID19_AppointmentResponse": covid19AppointmentResponse, + "COVID19_FreeTimeSlots": covid19FreeTimeSlots, + "COVID19_InvoiceResponse": covid19InvoiceResponse, + "COVID19_PatientShare": covid19PatientShare, + "COVID19_TestProceduresList": covid19TestProceduresList, + "ClinicCategoryList": clinicCategoryList, + "ClinicInsertedID": clinicInsertedId == null ? null : clinicInsertedId, + "ClinicsHaveScheduleList": clinicsHaveScheduleList, + "ContinueBookAppointment": continueBookAppointment == null ? null : continueBookAppointment, + "DAPP_TemplateGetList": dappTemplateGetList, + "DecimalDoctorRate": decimalDoctorRate == null ? null : decimalDoctorRate, + "DentalProcedure": dentalProcedure, + "DentalProcedureName": dentalProcedureName, + "DiseasesByClinicList": diseasesByClinicList, + "DoctorBasicScheduleList": doctorBasicScheduleList, + "DoctorByClinicIDList": doctorByClinicIdList, + "DoctorByDiseaseList": doctorByDiseaseList, + "DoctorCalenderList": doctorCalenderList, + "DoctorInformationAsHTML": doctorInformationAsHtml, + "DoctorInformationRAW": doctorInformationRaw, + "DoctorList": doctorList, + "DoctorPrePostImagesList": doctorPrePostImagesList, + "DoctorProfileList": doctorProfileList == null ? null : List.from(doctorProfileList!.map((x) => x.toJson())), + "DoctorRate": doctorRate == null ? null : doctorRate, + "DoctorRatingDetailsList": doctorRatingDetailsList, + "DoctorScheduleMapping_Insert": doctorScheduleMappingInsert == null ? null : doctorScheduleMappingInsert, + "DoctorSchedulesByClinicList": doctorSchedulesByClinicList, + "Doctorscheduleslot_Insert": doctorscheduleslotInsert == null ? null : doctorscheduleslotInsert, + "Doctorscheduleslot_SelectList": doctorscheduleslotSelectList, + "ERAppointmentFeesObject": erAppointmentFeesObject, + "ER_AdvancePaymentResponse": erAdvancePaymentResponse, + "ER_OnlinePaymentDetailsResponse": erOnlinePaymentDetailsResponse, + "ER_PatientShare": erPatientShare, + "ER_TriageQuestionsList": erTriageQuestionsList, + "ErrCode": errCode, + "ErrorSearchMsg": errorSearchMsg, + "FormID": formId == null ? null : formId, + "FreeTimeSlots": freeTimeSlots, + "GenderError": genderError == null ? null : genderError, + "GetDoctorMobileNo": getDoctorMobileNo, + "GetPatientInfoByPatientIDList": getPatientInfoByPatientIdList, + "GetPatientMedicalStatus": getPatientMedicalStatus, + "HIS_GetAllAppoimentHistoryList": hisGetAllAppoimentHistoryList, + "HIS_GetDoctorOffDaysList": hisGetDoctorOffDaysList, + "HIS_ObgyneUltrasoundDoctorsList": hisObgyneUltrasoundDoctorsList, + "HIS_ProcedureTemplateDetailsList": hisProcedureTemplateDetailsList, + "HIS_ProcedureTemplateList": hisProcedureTemplateList, + "HIS_Waiting_CheckDoctorAvailableForWaitingAppointment_List": hisWaitingCheckDoctorAvailableForWaitingAppointmentList, + "His_ObGyneProcedureGet_Response": hisObGyneProcedureGetResponse, + "His_PRM_GetApprovalRemarkList": hisPrmGetApprovalRemarkList, + "HoursDiff": hoursDiff == null ? null : hoursDiff, + "ISDentalplan": isDentalplan == null ? null : isDentalplan, + "ISMobileAppDentalAllow": isMobileAppDentalAllow == null ? null : isMobileAppDentalAllow, + "InitialSlotDuration": initialSlotDuration == null ? null : initialSlotDuration, + "IsAllowToBookWaitingAppointment": isAllowToBookWaitingAppointment == null ? null : isAllowToBookWaitingAppointment, + "IsAllowVClinic": isAllowVClinic == null ? null : isAllowVClinic, + "IsAllowWaitList": isAllowWaitList == null ? null : isAllowWaitList, + "IsAppointmentAllowed": isAppointmentAllowed == null ? null : isAppointmentAllowed, + "IsClinicEnabledForICDCodes": isClinicEnabledForIcdCodes == null ? null : isClinicEnabledForIcdCodes, + "IsDoctorExist": isDoctorExist == null ? null : isDoctorExist, + "IsInsertOrUpdate": isInsertOrUpdate == null ? null : isInsertOrUpdate, + "IsLastAppoitmentRatedList": isLastAppoitmentRatedList, + "IsShowInsuranceUpdateModule": isShowInsuranceUpdateModule == null ? null : isShowInsuranceUpdateModule, + "IsSlotAvailable": isSlotAvailable == null ? null : isSlotAvailable, + "LC_GetClinicScheduleList": lcGetClinicScheduleList, + "ListHoursDiff": listHoursDiff, + "ListReqTypes": listReqTypes, + "List_AllClinicRate": listAllClinicRate, + "List_AllDoctorRate": listAllDoctorRate, + "List_AllProjectRate": listAllProjectRate, + "List_COVID19_DoctorsByClinicAndProject": listCovid19DoctorsByClinicAndProject, + "List_COVID19_ProjectDriveThroughTestingCenter": listCovid19ProjectDriveThroughTestingCenter, + "List_CalculationTable": listCalculationTable, + "List_DDAdmin_Members": listDdAdminMembers, + "List_DentalChiefComplain": listDentalChiefComplain, + "List_DentalDDDetails": listDentalDdDetails, + "List_DentalDoctorChiefComplaintMapping": listDentalDoctorChiefComplaintMapping, + "List_DentalPediatricDoctor": listDentalPediatricDoctor, + "List_DoctorAll": listDoctorAll, + "List_DoctorByIPAddressCheckIn": listDoctorByIpAddressCheckIn, + "List_DoctorByProjectClinicAr": listDoctorByProjectClinicAr, + "List_DoctorByProjectClinicEn": listDoctorByProjectClinicEn, + "List_DoctorCases": listDoctorCases, + "List_DoctorClinics": listDoctorClinics, + "List_DoctorDetailsList": listDoctorDetailsList, + "List_DoctorDetailsListAr": listDoctorDetailsListAr, + "List_DoctorLanguages": listDoctorLanguages, + "List_DoctorMappinsgs": listDoctorMappinsgs, + "List_DoctorPatientVitalSign": listDoctorPatientVitalSign, + "List_DoctorProcedureMapping": listDoctorProcedureMapping, + "List_DoctorProfileImage": listDoctorProfileImage, + "List_DoctorProject": listDoctorProject, + "List_DoctorQualifications": listDoctorQualifications, + "List_DoctorSlotFirstVisit": listDoctorSlotFirstVisit, + "List_DoctorSpeciality": listDoctorSpeciality, + "List_DoctorSpecializations": listDoctorSpecializations, + "List_DoctorWorkingHoursTable": listDoctorWorkingHoursTable, + "List_DoctorblacklistModel": listDoctorblacklistModel, + "List_Doctorinfo": listDoctorinfo, + "List_English": listEnglish, + "List_GetAllCancelAppointmentReasons": listGetAllCancelAppointmentReasons, + "List_GetAllClinicsRoomNo": listGetAllClinicsRoomNo, + "List_GetAllDoctorsOnProject": listGetAllDoctorsOnProject, + "List_GetAllDoctorsbyProject": listGetAllDoctorsbyProject, + "List_GetAppForCancel": listGetAppForCancel, + "List_GetClinicsInfobyProject": listGetClinicsInfobyProject, + "List_GetClinicsbyProject": listGetClinicsbyProject, + "List_GetDoctorsbyProject": listGetDoctorsbyProject, + "List_GetIPAddressForDD": listGetIpAddressForDd, + "List_GetIPAddressForDentalDD": listGetIpAddressForDentalDd, + "List_GetInfoForDentalClinicsDD": listGetInfoForDentalClinicsDd, + "List_GetLoginDetails": listGetLoginDetails, + "List_GetPatientCancelAppointment": listGetPatientCancelAppointment, + "List_HISDoctorProject": listHisDoctorProject, + "List_HIS_GetContactLensPerscription": listHisGetContactLensPerscription, + "List_HIS_GetGlassPerscription": listHisGetGlassPerscription, + "List_HmgPartTimeDoctor": listHmgPartTimeDoctor, + "List_InvoiceDetails": listInvoiceDetails, + "List_IsPatientHasOnGoingEstimation": listIsPatientHasOnGoingEstimation, + "List_LaserDoctors": listLaserDoctors, + "List_LaserProcedures": listLaserProcedures, + "List_MedicalReportByAppointment": listMedicalReportByAppointment, + "List_NonAdminProjectMapping": listNonAdminProjectMapping, + "List_PatientER_AdminServiceModel": listPatientErAdminServiceModel, + "List_PatientER_DoctorBlackListModel": listPatientErDoctorBlackListModel, + "List_PhysioDoctors": listPhysioDoctors, + "List_ProjectERPMapping": listProjectErpMapping, + "List_RecordByIPAddress": listRecordByIpAddress, + "List_RecordByIPAddressNew": listRecordByIpAddressNew, + "List_RecordByIPAddressNewCheckIn": listRecordByIpAddressNewCheckIn, + "List_RecordByIPAddressNewForDubai": listRecordByIpAddressNewForDubai, + "List_RescahdualOnlineModel": listRescahdualOnlineModel, + "Message": message, + "NotesDoctorRatingForCOC_List": notesDoctorRatingForCocList, + "NotesDoctorRatingList": notesDoctorRatingList, + "OnlineCheckInAppointments": onlineCheckInAppointments, + "OnlineCheckinBeforeHour": onlineCheckinBeforeHour == null ? null : onlineCheckinBeforeHour, + "PRM_AdmissionInfoList": prmAdmissionInfoList, + "PRM_DentalEstimationDetailList": prmDentalEstimationDetailList, + "PRM_DentalEstimationList": prmDentalEstimationList, + "PRM_DoctorsForRadiologyList": prmDoctorsForRadiologyList, + "PRM_GET_ERToOPDRequestStatusList": prmGetErToOpdRequestStatusList, + "PRM_GetDoctorRatingList": prmGetDoctorRatingList, + "PRM_GetProceureAndPackagesList": prmGetProceureAndPackagesList, + "PRM_HIS_AppointmentqueuegetList": prmHisAppointmentqueuegetList, + "PRM_HIS_CheckDoctorIsFullyBookedList": prmHisCheckDoctorIsFullyBookedList, + "PRM_HIS_GetDentalEstimationPlan_List": prmHisGetDentalEstimationPlanList, + "PRM_HIS_GetDischargeInfo_List": prmHisGetDischargeInfoList, + "PRM_HIS_GetUpcomingConfirmedAppoimentList": prmHisGetUpcomingConfirmedAppoimentList, + "PRM_HIS_QueueERToOP_List": prmHisQueueErToOpList, + "PRM_QueueERreferralHistory_getList": prmQueueERreferralHistoryGetList, + "PRM_SpecialClinicalCareMapping_List": prmSpecialClinicalCareMappingList, + "PatientDoctorAppointmentResultExit": patientDoctorAppointmentResultExit == null ? null : patientDoctorAppointmentResultExit, + "PatientDoctorAppointmentResultList": patientDoctorAppointmentResultList, + "PatientER_DoctorFreeSlots": patientErDoctorFreeSlots, + "PatientER_GetAllClinics_List": patientErGetAllClinicsList, + "PatientER_GetDoctorClincByServiceID_List": patientErGetDoctorClincByServiceIdList, + "PatientER_GetServiceList": patientErGetServiceList, + "PatientER_Logininsert": patientErLogininsert == null ? null : patientErLogininsert, + "PatientER_PrescriptionLogin": patientErPrescriptionLogin, + "PatientER_SelectAdmin": patientErSelectAdmin, + "PatientER_SelectRole2": patientErSelectRole2, + "PatientER_UpdateLiveCareStatus": patientErUpdateLiveCareStatus == null ? null : patientErUpdateLiveCareStatus, + "PatientER_insert": patientErInsert == null ? null : patientErInsert, + "PatientInformationList": patientInformationList, + "PatientNumber": patientNumber == null ? null : patientNumber, + "PaymentModes": paymentModes, + "Physio_IsPatientHasApproval": physioIsPatientHasApproval == null ? null : physioIsPatientHasApproval, + "PhysiotherapyError": physiotherapyError == null ? null : physiotherapyError, + "ProcedureNeedeTime": procedureNeedeTime, + "RiskScore": riskScore == null ? null : riskScore, + "RowCount": rowCount == null ? null : rowCount, + "SameClinicApptList": sameClinicApptList, + "SearchDoctorsByTime_IsVoiceCommandList": searchDoctorsByTimeIsVoiceCommandList, + "SlotDuration": slotDuration == null ? null : slotDuration, + "StatusCode": statusCode == null ? null : statusCode, + "Tamara_IntegrationLogsInsert_Response": tamaraIntegrationLogsInsertResponse == null ? null : tamaraIntegrationLogsInsertResponse, + "Tamara_IntegrationLogsUpdate_Response": tamaraIntegrationLogsUpdateResponse == null ? null : tamaraIntegrationLogsUpdateResponse, + "TransactionNo": transactionNo, + "UserDentalPlanMessage": userDentalPlanMessage, + "WaitingAppointmentNoPerDay": waitingAppointmentNoPerDay == null ? null : waitingAppointmentNoPerDay, + "age": age == null ? null : age, + "erpDoctorDetails": erpDoctorDetails, + "returnValue": returnValue == null ? null : returnValue, + }; +} diff --git a/lib/model/base/post_params_model.dart b/lib/model/base/post_params_model.dart index e1844bd..3e2e4a4 100644 --- a/lib/model/base/post_params_model.dart +++ b/lib/model/base/post_params_model.dart @@ -12,6 +12,7 @@ class PostParamsModel { String? vidaAuthTokenID; String? vidaRefreshTokenID; int? deviceTypeID; + String? generalID; PostParamsModel({ this.imei, @@ -27,6 +28,7 @@ class PostParamsModel { this.vidaAuthTokenID, this.vidaRefreshTokenID, this.deviceTypeID, + this.generalID, }); PostParamsModel.fromJson(Map json) { @@ -43,6 +45,7 @@ class PostParamsModel { vidaAuthTokenID = json['VidaAuthTokenID']; vidaRefreshTokenID = json['VidaRefreshTokenID']; deviceTypeID = json['DeviceTypeID']; + deviceTypeID = json['generalid']; } Map toJson() { @@ -59,6 +62,7 @@ class PostParamsModel { data['VidaAuthTokenID'] = this.vidaAuthTokenID; data['VidaRefreshTokenID'] = this.vidaRefreshTokenID; data['DeviceTypeID'] = this.deviceTypeID; + data['generalid']=this.generalID; return data; } diff --git a/lib/model/login/doctor_profile_model.dart b/lib/model/login/doctor_profile_model.dart new file mode 100644 index 0000000..258af4e --- /dev/null +++ b/lib/model/login/doctor_profile_model.dart @@ -0,0 +1,195 @@ +class DoctorProfileListModel { + DoctorProfileListModel({ + this.doctorId, + this.doctorName, + this.doctorNameN, + this.clinicId, + this.clinicDescription, + this.clinicDescriptionN, + this.licenseExpiry, + this.employmentType, + this.setupId, + this.projectId, + this.projectName, + this.nationalityId, + this.nationalityName, + this.nationalityNameN, + this.gender, + this.genderDescription, + this.genderDescriptionN, + this.doctorTitle, + this.projectNameN, + this.isAllowWaitList, + this.titleDescription, + this.titleDescriptionN, + this.isRegistered, + this.isDoctorDummy, + this.isActive, + this.isDoctorAppointmentDisplayed, + this.doctorClinicActive, + this.isbookingAllowed, + this.doctorCases, + this.doctorPicture, + this.doctorProfileInfo, + this.specialty, + this.actualDoctorRate, + this.consultationFee, + this.decimalDoctorRate, + this.doctorImageUrl, + this.doctorMobileNumber, + this.doctorRate, + this.doctorStarsRate, + this.doctorTitleForProfile, + this.isAppointmentAllowed, + this.isDoctorHasPrePostImages, + this.nationalityFlagUrl, + this.noOfPatientsRate, + this.qr, + this.serviceId, + }); + + final int? doctorId; + final String? doctorName; + final dynamic doctorNameN; + final int? clinicId; + final String? clinicDescription; + final dynamic clinicDescriptionN; + final dynamic licenseExpiry; + final int? employmentType; + final dynamic setupId; + final int? projectId; + final String? projectName; + final String? nationalityId; + final String? nationalityName; + final dynamic nationalityNameN; + final int? gender; + final String? genderDescription; + final dynamic genderDescriptionN; + final dynamic doctorTitle; + final dynamic projectNameN; + final bool? isAllowWaitList; + final String? titleDescription; + final dynamic titleDescriptionN; + final dynamic isRegistered; + final dynamic isDoctorDummy; + final bool? isActive; + final dynamic isDoctorAppointmentDisplayed; + final bool? doctorClinicActive; + final dynamic isbookingAllowed; + final String? doctorCases; + final dynamic doctorPicture; + final String? doctorProfileInfo; + final List? specialty; + final int? actualDoctorRate; + final String? consultationFee; + final double? decimalDoctorRate; + final String? doctorImageUrl; + final String? doctorMobileNumber; + final int? doctorRate; + final int? doctorStarsRate; + final String? doctorTitleForProfile; + final bool? isAppointmentAllowed; + final bool? isDoctorHasPrePostImages; + final String? nationalityFlagUrl; + final int? noOfPatientsRate; + final String? qr; + final int? serviceId; + + factory DoctorProfileListModel.fromJson(Map json) => DoctorProfileListModel( + doctorId: json["DoctorID"] == null ? null : json["DoctorID"], + doctorName: json["DoctorName"] == null ? null : json["DoctorName"], + doctorNameN: json["DoctorNameN"], + clinicId: json["ClinicID"] == null ? null : json["ClinicID"], + clinicDescription: json["ClinicDescription"] == null ? null : json["ClinicDescription"], + clinicDescriptionN: json["ClinicDescriptionN"], + licenseExpiry: json["LicenseExpiry"], + employmentType: json["EmploymentType"] == null ? null : json["EmploymentType"], + setupId: json["SetupID"], + projectId: json["ProjectID"] == null ? null : json["ProjectID"], + projectName: json["ProjectName"] == null ? null : json["ProjectName"], + nationalityId: json["NationalityID"] == null ? null : json["NationalityID"], + nationalityName: json["NationalityName"] == null ? null : json["NationalityName"], + nationalityNameN: json["NationalityNameN"], + gender: json["Gender"] == null ? null : json["Gender"], + genderDescription: json["Gender_Description"] == null ? null : json["Gender_Description"], + genderDescriptionN: json["Gender_DescriptionN"], + doctorTitle: json["DoctorTitle"], + projectNameN: json["ProjectNameN"], + isAllowWaitList: json["IsAllowWaitList"] == null ? null : json["IsAllowWaitList"], + titleDescription: json["Title_Description"] == null ? null : json["Title_Description"], + titleDescriptionN: json["Title_DescriptionN"], + isRegistered: json["IsRegistered"], + isDoctorDummy: json["IsDoctorDummy"], + isActive: json["IsActive"] == null ? null : json["IsActive"], + isDoctorAppointmentDisplayed: json["IsDoctorAppointmentDisplayed"], + doctorClinicActive: json["DoctorClinicActive"] == null ? null : json["DoctorClinicActive"], + isbookingAllowed: json["IsbookingAllowed"], + doctorCases: json["DoctorCases"] == null ? null : json["DoctorCases"], + doctorPicture: json["DoctorPicture"], + doctorProfileInfo: json["DoctorProfileInfo"] == null ? null : json["DoctorProfileInfo"], + specialty: json["Specialty"] == null ? null : List.from(json["Specialty"].map((x) => x)), + actualDoctorRate: json["ActualDoctorRate"] == null ? null : json["ActualDoctorRate"], + consultationFee: json["ConsultationFee"] == null ? null : json["ConsultationFee"], + decimalDoctorRate: json["DecimalDoctorRate"] == null ? null : json["DecimalDoctorRate"].toDouble(), + doctorImageUrl: json["DoctorImageURL"] == null ? null : json["DoctorImageURL"], + doctorMobileNumber: json["DoctorMobileNumber"] == null ? null : json["DoctorMobileNumber"], + doctorRate: json["DoctorRate"] == null ? null : json["DoctorRate"], + doctorStarsRate: json["DoctorStarsRate"] == null ? null : json["DoctorStarsRate"], + doctorTitleForProfile: json["DoctorTitleForProfile"] == null ? null : json["DoctorTitleForProfile"], + isAppointmentAllowed: json["IsAppointmentAllowed"] == null ? null : json["IsAppointmentAllowed"], + isDoctorHasPrePostImages: json["IsDoctorHasPrePostImages"] == null ? null : json["IsDoctorHasPrePostImages"], + nationalityFlagUrl: json["NationalityFlagURL"] == null ? null : json["NationalityFlagURL"], + noOfPatientsRate: json["NoOfPatientsRate"] == null ? null : json["NoOfPatientsRate"], + qr: json["QR"] == null ? null : json["QR"], + serviceId: json["ServiceID"] == null ? null : json["ServiceID"], + ); + + Map toJson() => { + "DoctorID": doctorId == null ? null : doctorId, + "DoctorName": doctorName == null ? null : doctorName, + "DoctorNameN": doctorNameN, + "ClinicID": clinicId == null ? null : clinicId, + "ClinicDescription": clinicDescription == null ? null : clinicDescription, + "ClinicDescriptionN": clinicDescriptionN, + "LicenseExpiry": licenseExpiry, + "EmploymentType": employmentType == null ? null : employmentType, + "SetupID": setupId, + "ProjectID": projectId == null ? null : projectId, + "ProjectName": projectName == null ? null : projectName, + "NationalityID": nationalityId == null ? null : nationalityId, + "NationalityName": nationalityName == null ? null : nationalityName, + "NationalityNameN": nationalityNameN, + "Gender": gender == null ? null : gender, + "Gender_Description": genderDescription == null ? null : genderDescription, + "Gender_DescriptionN": genderDescriptionN, + "DoctorTitle": doctorTitle, + "ProjectNameN": projectNameN, + "IsAllowWaitList": isAllowWaitList == null ? null : isAllowWaitList, + "Title_Description": titleDescription == null ? null : titleDescription, + "Title_DescriptionN": titleDescriptionN, + "IsRegistered": isRegistered, + "IsDoctorDummy": isDoctorDummy, + "IsActive": isActive == null ? null : isActive, + "IsDoctorAppointmentDisplayed": isDoctorAppointmentDisplayed, + "DoctorClinicActive": doctorClinicActive == null ? null : doctorClinicActive, + "IsbookingAllowed": isbookingAllowed, + "DoctorCases": doctorCases == null ? null : doctorCases, + "DoctorPicture": doctorPicture, + "DoctorProfileInfo": doctorProfileInfo == null ? null : doctorProfileInfo, + "Specialty": specialty == null ? null : List.from(specialty!.map((x) => x)), + "ActualDoctorRate": actualDoctorRate == null ? null : actualDoctorRate, + "ConsultationFee": consultationFee == null ? null : consultationFee, + "DecimalDoctorRate": decimalDoctorRate == null ? null : decimalDoctorRate, + "DoctorImageURL": doctorImageUrl == null ? null : doctorImageUrl, + "DoctorMobileNumber": doctorMobileNumber == null ? null : doctorMobileNumber, + "DoctorRate": doctorRate == null ? null : doctorRate, + "DoctorStarsRate": doctorStarsRate == null ? null : doctorStarsRate, + "DoctorTitleForProfile": doctorTitleForProfile == null ? null : doctorTitleForProfile, + "IsAppointmentAllowed": isAppointmentAllowed == null ? null : isAppointmentAllowed, + "IsDoctorHasPrePostImages": isDoctorHasPrePostImages == null ? null : isDoctorHasPrePostImages, + "NationalityFlagURL": nationalityFlagUrl == null ? null : nationalityFlagUrl, + "NoOfPatientsRate": noOfPatientsRate == null ? null : noOfPatientsRate, + "QR": qr == null ? null : qr, + "ServiceID": serviceId == null ? null : serviceId, + }; +} diff --git a/lib/model/login/list_doctors_clinic_model.dart b/lib/model/login/list_doctors_clinic_model.dart new file mode 100644 index 0000000..96f1e80 --- /dev/null +++ b/lib/model/login/list_doctors_clinic_model.dart @@ -0,0 +1,35 @@ +class ListDoctorsClinicModel { + ListDoctorsClinicModel({ + this.setupId, + this.projectId, + this.doctorId, + this.clinicId, + this.isActive, + this.clinicName, + }); + + final dynamic setupId; + final int? projectId; + final int? doctorId; + final int? clinicId; + final bool? isActive; + final String? clinicName; + + factory ListDoctorsClinicModel.fromJson(Map json) => ListDoctorsClinicModel( + setupId: json["SetupID"], + projectId: json["ProjectID"] == null ? null : json["ProjectID"], + doctorId: json["DoctorID"] == null ? null : json["DoctorID"], + clinicId: json["ClinicID"] == null ? null : json["ClinicID"], + isActive: json["IsActive"] == null ? null : json["IsActive"], + clinicName: json["ClinicName"] == null ? null : json["ClinicName"], + ); + + Map toJson() => { + "SetupID": setupId, + "ProjectID": projectId == null ? null : projectId, + "DoctorID": doctorId == null ? null : doctorId, + "ClinicID": clinicId == null ? null : clinicId, + "IsActive": isActive == null ? null : isActive, + "ClinicName": clinicName == null ? null : clinicName, + }; +} diff --git a/lib/model/login/member_information_model.dart b/lib/model/login/member_information_model.dart new file mode 100644 index 0000000..a3f22c1 --- /dev/null +++ b/lib/model/login/member_information_model.dart @@ -0,0 +1,92 @@ +class MemberInformation { + MemberInformation({ + this.clinics, + this.doctorId, + this.email, + this.employeeId, + this.memberId, + this.memberName, + this.memberNameArabic, + this.preferredLanguage, + this.roles, + }); + + final List? clinics; + final int? doctorId; + final String? email; + final int? employeeId; + final int? memberId; + final dynamic memberName; + final dynamic memberNameArabic; + final String? preferredLanguage; + final List? roles; + + factory MemberInformation.fromJson(Map json) => MemberInformation( + clinics: json["clinics"] == null ? null : List.from(json["clinics"].map((x) => Clinic.fromJson(x))), + doctorId: json["doctorId"] == null ? null : json["doctorId"], + email: json["email"] == null ? null : json["email"], + employeeId: json["employeeId"] == null ? null : json["employeeId"], + memberId: json["memberId"] == null ? null : json["memberId"], + memberName: json["memberName"], + memberNameArabic: json["memberNameArabic"], + preferredLanguage: json["preferredLanguage"] == null ? null : json["preferredLanguage"], + roles: json["roles"] == null ? null : List.from(json["roles"].map((x) => Role.fromJson(x))), + ); + + Map toJson() => { + "clinics": clinics == null ? null : List.from(clinics!.map((x) => x.toJson())), + "doctorId": doctorId == null ? null : doctorId, + "email": email == null ? null : email, + "employeeId": employeeId == null ? null : employeeId, + "memberId": memberId == null ? null : memberId, + "memberName": memberName, + "memberNameArabic": memberNameArabic, + "preferredLanguage": preferredLanguage == null ? null : preferredLanguage, + "roles": roles == null ? null : List.from(roles!.map((x) => x.toJson())), + }; +} + + +class Clinic { + Clinic({ + this.defaultClinic, + this.id, + this.name, + }); + + final bool? defaultClinic; + final int? id; + final String? name; + + factory Clinic.fromJson(Map json) => Clinic( + defaultClinic: json["defaultClinic"] == null ? null : json["defaultClinic"], + id: json["id"] == null ? null : json["id"], + name: json["name"] == null ? null : json["name"], + ); + + Map toJson() => { + "defaultClinic": defaultClinic == null ? null : defaultClinic, + "id": id == null ? null : id, + "name": name == null ? null : name, + }; +} + +class Role { + Role({ + this.name, + this.roleId, + }); + + final String? name; + final int? roleId; + + factory Role.fromJson(Map json) => Role( + name: json["name"] == null ? null : json["name"], + roleId: json["roleId"] == null ? null : json["roleId"], + ); + + Map toJson() => { + "name": name == null ? null : name, + "roleId": roleId == null ? null : roleId, + }; +} diff --git a/lib/model/login/member_login_model.dart b/lib/model/login/member_login_model.dart new file mode 100644 index 0000000..04eeb4d --- /dev/null +++ b/lib/model/login/member_login_model.dart @@ -0,0 +1,245 @@ +// To parse this JSON data, do +// +// final memberLoginModel = memberLoginModelFromJson(jsonString); + +import 'dart:convert'; + +MemberLoginModel memberLoginModelFromJson(String str) => MemberLoginModel.fromJson(json.decode(str)); + +String memberLoginModelToJson(MemberLoginModel data) => json.encode(data.toJson()); + +class MemberLoginModel { + MemberLoginModel({ + this.date, + this.languageId, + this.serviceName, + this.time, + this.androidLink, + this.authenticationTokenId, + this.data, + this.dataw, + this.dietType, + this.dietTypeId, + this.errorCode, + this.errorEndUserMessage, + this.errorEndUserMessageN, + this.errorMessage, + this.errorType, + this.foodCategory, + this.iosLink, + this.isAuthenticated, + this.mealOrderStatus, + this.mealType, + this.messageStatus, + this.numberOfResultRecords, + this.patientBlodType, + this.successMsg, + this.successMsgN, + this.vidaUpdatedResponse, + this.doctorHaveOneClinic, + this.doctorId, + this.erpSessionId, + this.listConsentMember, + this.listConsentMemberNew, + this.listDoctorProfile, + this.listDoctorsClinic, + this.listMemberInformation, + this.listModelDbConnect, + this.logInTokenId, + this.mobileNumber, + this.selectDeviceImeIbyImeiList, + this.userId, + this.zipCode, + this.isActiveCode, + this.isSmsSent, + }); + + final dynamic date; + final int? languageId; + final int? serviceName; + final dynamic time; + final dynamic androidLink; + final dynamic authenticationTokenId; + final dynamic data; + final bool? dataw; + final int? dietType; + final int? dietTypeId; + final dynamic errorCode; + final dynamic errorEndUserMessage; + final dynamic errorEndUserMessageN; + final dynamic errorMessage; + final int? errorType; + final int? foodCategory; + final dynamic iosLink; + final bool? isAuthenticated; + final int? mealOrderStatus; + final int? mealType; + final int? messageStatus; + final int? numberOfResultRecords; + final dynamic patientBlodType; + final dynamic successMsg; + final dynamic successMsgN; + final dynamic vidaUpdatedResponse; + final bool? doctorHaveOneClinic; + final int? doctorId; + final dynamic erpSessionId; + final dynamic listConsentMember; + final dynamic listConsentMemberNew; + final dynamic listDoctorProfile; + final dynamic listDoctorsClinic; + final List? listMemberInformation; + final dynamic listModelDbConnect; + final String? logInTokenId; + final String? mobileNumber; + final dynamic selectDeviceImeIbyImeiList; + final int? userId; + final String? zipCode; + final bool? isActiveCode; + final bool? isSmsSent; + + factory MemberLoginModel.fromJson(Map json) => MemberLoginModel( + date: json["Date"], + languageId: json["LanguageID"] == null ? null : json["LanguageID"], + serviceName: json["ServiceName"] == null ? null : json["ServiceName"], + time: json["Time"], + androidLink: json["AndroidLink"], + authenticationTokenId: json["AuthenticationTokenID"], + data: json["Data"], + dataw: json["Dataw"] == null ? null : json["Dataw"], + dietType: json["DietType"] == null ? null : json["DietType"], + dietTypeId: json["DietTypeID"] == null ? null : json["DietTypeID"], + errorCode: json["ErrorCode"], + errorEndUserMessage: json["ErrorEndUserMessage"], + errorEndUserMessageN: json["ErrorEndUserMessageN"], + errorMessage: json["ErrorMessage"], + errorType: json["ErrorType"] == null ? null : json["ErrorType"], + foodCategory: json["FoodCategory"] == null ? null : json["FoodCategory"], + iosLink: json["IOSLink"], + isAuthenticated: json["IsAuthenticated"] == null ? null : json["IsAuthenticated"], + mealOrderStatus: json["MealOrderStatus"] == null ? null : json["MealOrderStatus"], + mealType: json["MealType"] == null ? null : json["MealType"], + messageStatus: json["MessageStatus"] == null ? null : json["MessageStatus"], + numberOfResultRecords: json["NumberOfResultRecords"] == null ? null : json["NumberOfResultRecords"], + patientBlodType: json["PatientBlodType"], + successMsg: json["SuccessMsg"], + successMsgN: json["SuccessMsgN"], + vidaUpdatedResponse: json["VidaUpdatedResponse"], + doctorHaveOneClinic: json["DoctorHaveOneClinic"] == null ? null : json["DoctorHaveOneClinic"], + doctorId: json["DoctorID"] == null ? null : json["DoctorID"], + erpSessionId: json["ERP_SessionID"], + listConsentMember: json["List_Consent_Member"], + listConsentMemberNew: json["List_Consent_MemberNew"], + listDoctorProfile: json["List_DoctorProfile"], + listDoctorsClinic: json["List_DoctorsClinic"], + listMemberInformation: json["List_MemberInformation"] == null ? null : List.from(json["List_MemberInformation"].map((x) => ListMemberInformation.fromJson(x))), + listModelDbConnect: json["List_Model_DB_Connect"], + logInTokenId: json["LogInTokenID"] == null ? null : json["LogInTokenID"], + mobileNumber: json["MobileNumber"] == null ? null : json["MobileNumber"], + selectDeviceImeIbyImeiList: json["SELECTDeviceIMEIbyIMEI_List"], + userId: json["UserID"] == null ? null : json["UserID"], + zipCode: json["ZipCode"] == null ? null : json["ZipCode"], + isActiveCode: json["isActiveCode"] == null ? null : json["isActiveCode"], + isSmsSent: json["isSMSSent"] == null ? null : json["isSMSSent"], + ); + + Map toJson() => { + "Date": date, + "LanguageID": languageId == null ? null : languageId, + "ServiceName": serviceName == null ? null : serviceName, + "Time": time, + "AndroidLink": androidLink, + "AuthenticationTokenID": authenticationTokenId, + "Data": data, + "Dataw": dataw == null ? null : dataw, + "DietType": dietType == null ? null : dietType, + "DietTypeID": dietTypeId == null ? null : dietTypeId, + "ErrorCode": errorCode, + "ErrorEndUserMessage": errorEndUserMessage, + "ErrorEndUserMessageN": errorEndUserMessageN, + "ErrorMessage": errorMessage, + "ErrorType": errorType == null ? null : errorType, + "FoodCategory": foodCategory == null ? null : foodCategory, + "IOSLink": iosLink, + "IsAuthenticated": isAuthenticated == null ? null : isAuthenticated, + "MealOrderStatus": mealOrderStatus == null ? null : mealOrderStatus, + "MealType": mealType == null ? null : mealType, + "MessageStatus": messageStatus == null ? null : messageStatus, + "NumberOfResultRecords": numberOfResultRecords == null ? null : numberOfResultRecords, + "PatientBlodType": patientBlodType, + "SuccessMsg": successMsg, + "SuccessMsgN": successMsgN, + "VidaUpdatedResponse": vidaUpdatedResponse, + "DoctorHaveOneClinic": doctorHaveOneClinic == null ? null : doctorHaveOneClinic, + "DoctorID": doctorId == null ? null : doctorId, + "ERP_SessionID": erpSessionId, + "List_Consent_Member": listConsentMember, + "List_Consent_MemberNew": listConsentMemberNew, + "List_DoctorProfile": listDoctorProfile, + "List_DoctorsClinic": listDoctorsClinic, + "List_MemberInformation": listMemberInformation == null ? null : List.from(listMemberInformation!.map((x) => x.toJson())), + "List_Model_DB_Connect": listModelDbConnect, + "LogInTokenID": logInTokenId == null ? null : logInTokenId, + "MobileNumber": mobileNumber == null ? null : mobileNumber, + "SELECTDeviceIMEIbyIMEI_List": selectDeviceImeIbyImeiList, + "UserID": userId == null ? null : userId, + "ZipCode": zipCode == null ? null : zipCode, + "isActiveCode": isActiveCode == null ? null : isActiveCode, + "isSMSSent": isSmsSent == null ? null : isSmsSent, + }; +} + +class ListMemberInformation { + ListMemberInformation({ + this.setupId, + this.memberId, + this.memberName, + this.memberNameN, + this.preferredLang, + this.pin, + this.saltHash, + this.referenceId, + this.employeeId, + this.roleId, + this.projectid, + }); + + final dynamic setupId; + final int? memberId; + final String? memberName; + final dynamic memberNameN; + final String? preferredLang; + final dynamic pin; + final dynamic saltHash; + final int? referenceId; + final int? employeeId; + final int? roleId; + final int? projectid; + + factory ListMemberInformation.fromJson(Map json) => ListMemberInformation( + setupId: json["SetupID"], + memberId: json["MemberID"] == null ? null : json["MemberID"], + memberName: json["MemberName"] == null ? null : json["MemberName"], + memberNameN: json["MemberNameN"], + preferredLang: json["PreferredLang"] == null ? null : json["PreferredLang"], + pin: json["PIN"], + saltHash: json["SaltHash"], + referenceId: json["ReferenceID"] == null ? null : json["ReferenceID"], + employeeId: json["EmployeeID"] == null ? null : json["EmployeeID"], + roleId: json["RoleID"] == null ? null : json["RoleID"], + projectid: json["projectid"] == null ? null : json["projectid"], + ); + + Map toJson() => { + "SetupID": setupId, + "MemberID": memberId == null ? null : memberId, + "MemberName": memberName == null ? null : memberName, + "MemberNameN": memberNameN, + "PreferredLang": preferredLang == null ? null : preferredLang, + "PIN": pin, + "SaltHash": saltHash, + "ReferenceID": referenceId == null ? null : referenceId, + "EmployeeID": employeeId == null ? null : employeeId, + "RoleID": roleId == null ? null : roleId, + "projectid": projectid == null ? null : projectid, + }; +} diff --git a/lib/provider/login_provider_model.dart b/lib/provider/login_provider_model.dart index ec9fb99..81ce17e 100644 --- a/lib/provider/login_provider_model.dart +++ b/lib/provider/login_provider_model.dart @@ -1,17 +1,107 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:hmg_nurses/classes/enums.dart'; +import 'package:hmg_nurses/classes/utils.dart'; +import 'package:hmg_nurses/config/routes.dart'; +import 'package:hmg_nurses/main.dart'; +import 'package:hmg_nurses/model/base/generic_response_model.dart'; +import 'package:hmg_nurses/model/login/imei_details_model.dart'; +import 'package:hmg_nurses/model/login/member_login_model.dart'; import 'package:hmg_nurses/model/login/project_info_model.dart'; import 'package:hmg_nurses/provider/base_vm.dart'; import 'package:hmg_nurses/services/api_repo/login_api_repo.dart'; +import 'package:hmg_nurses/widgets/dialogs/otp_dialog.dart'; import 'package:injector/injector.dart'; +import 'package:local_auth/auth_strings.dart'; +import 'package:local_auth/local_auth.dart'; class LoginProviderModel extends BaseViewModel { + //UI variables + late LocalAuthentication auth; + late bool isFaceBioAvailable, isFingerBioAvailable; + late List _availableBiometrics; + + //API's variables + late List assignedBranches; + final ILoginApiRepo _loginApiRepo = Injector.appInstance.get(); + LoginProviderModel() { setOnlyState(ViewState.hide); + checkBiosAvailblity(); } - final ILoginApiRepo _loginApiRepo = Injector.appInstance.get(); + checkBiosAvailblity() async { + auth = LocalAuthentication(); + await _getAvailableBiometrics(); + isFaceBioAvailable = checkBiometricIsAvailable(BiometricType.face); + isFingerBioAvailable = checkBiometricIsAvailable(BiometricType.fingerprint); + } - late List assignedBranches; + /// check specific biometric if it available or not + bool checkBiometricIsAvailable(BiometricType biometricType) { + bool isAvailable = false; + for (int i = 0; i < _availableBiometrics.length; i++) { + if (biometricType == _availableBiometrics[i]) { + isAvailable = true; + break; + } + } + return isAvailable; + } + + /// get all available biometric on the device for local Auth service + Future _getAvailableBiometrics() async { + try { + _availableBiometrics = await auth.getAvailableBiometrics(); + print(_availableBiometrics); + } on PlatformException catch (e) { + // AppToast.showErrorToast(message: e.message); + print("_getAvailableBiometrics"); + print(e); + } + } + + Future loginWithFaceIDAndBiometrics() async { + IOSAuthMessages iosStrings = + const IOSAuthMessages(cancelButton: 'cancel', goToSettingsButton: 'settings', goToSettingsDescription: 'Please set up your Touch ID.', lockOut: 'Please reenable your Touch ID'); + bool authenticated = false; + try { + authenticated = await auth.authenticate(localizedReason: 'Scan your fingerprint to authenticate', useErrorDialogs: true, stickyAuth: true, biometricOnly: true, iOSAuthStrings: iosStrings); + } on PlatformException catch (e) { + print(e); + Utils.hideLoading(); + Utils.showToast("Please enable your Touch or Face ID"); + } + return authenticated; + } + + int getLoginMethodId(AuthMethodTypes authMethodTypes) { + switch (authMethodTypes) { + case AuthMethodTypes.sms: + return 1; + case AuthMethodTypes.whatsApp: + return 2; + case AuthMethodTypes.fingerPrint: + return 3; + case AuthMethodTypes.faceID: + return 4; + default: + return 1; + } + } + + //API Calls + checkLastSession() async { + try { + Utils.showLoading(); + List deviceInfo = await _loginApiRepo.getDeviceInfoByIMEI(); + Utils.showToast(deviceInfo.length.toString()); + Utils.hideLoading(); + } catch (e) { + Utils.hideLoading(); + } + } getAssignedBranches(String userId) async { setState(ViewState.busy); @@ -19,4 +109,74 @@ class LoginProviderModel extends BaseViewModel { print(assignedBranches.length); setState(ViewState.idle); } + + performLogin(String userID, String password, int branchId) async { + try { + Utils.showLoading(); + MemberLoginModel memberLogin = await _loginApiRepo.memberLogin(userID, password, branchId); + // Utils.showToast(deviceInfo.length.toString()); + appState.setMemberBeforeLogin = memberLogin; + appState.projectID = branchId; + appState.logInTokenID = memberLogin.logInTokenId; + Utils.hideLoading(); + Navigator.pushNamed(navigatorKey.currentContext!, AppRoutes.loginMethodsPage, arguments: LoginType.FROM_LOGIN); + } catch (e) { + Utils.hideLoading(); + Utils.handleException(e, navigatorKey.currentContext!, (msg) { + Utils.confirmDialog(navigatorKey.currentContext!, msg); + }); + } + } + + Future sendActivationCode(MemberLoginModel memberLoginModel, int facilityID, int sendOtpType,bool isFromSilentLogin) async { + try { + Utils.showLoading(); + GenericResponseModel memberLogin = await _loginApiRepo.sendActivationCode(memberLoginModel, facilityID, sendOtpType); + // Utils.showToast(deviceInfo.length.toString()); + Utils.hideLoading(); + // Navigator.pushNamed(navigatorKey.currentContext!, AppRoutes.loginMethodsPage, arguments: LoginType.FROM_LOGIN); + + startSMSService(sendOtpType,isFromSilentLogin); + return memberLogin; + } catch (e) { + Utils.hideLoading(); + Utils.handleException(e, navigatorKey.currentContext!, (msg) { + Utils.confirmDialog(navigatorKey.currentContext!, msg); + }); + } + } + + Future checkActivationCode(String activationCode, int sendOtpType, bool isFromSilentLogin) async { + try { + Utils.showLoading(); + GenericResponseModel memberLogin = await _loginApiRepo.checkActivationCode(activationCode, sendOtpType, isFromSilentLogin); + + // Utils.showToast(deviceInfo.length.toString()); + _loginApiRepo.getDoctorProfile(); + Utils.hideLoading(); + + return memberLogin; + } catch (e) { + Utils.hideLoading(); + Utils.handleException(e, navigatorKey.currentContext!, (msg) { + Utils.confirmDialog(navigatorKey.currentContext!, msg); + }); + } + return null; + } + + startSMSService(int sendOtpType, bool isFromSilentLogin) { + OtpDialog( + type: sendOtpType, + mobileNo: appState.memberBeforeLogin!.mobileNumber, + onSuccess: (String otpCode, TextEditingController pinPut) { + Navigator.pop(navigatorKey.currentContext!); + Utils.showLoading(); + checkActivationCode(otpCode, sendOtpType, isFromSilentLogin); + Utils.hideLoading(); + }, + onFailure: () => Navigator.pop(navigatorKey.currentContext!), + onResendCode: () {}, + ).displayDialog(navigatorKey.currentContext!); + } } diff --git a/lib/services/api_repo/login_api_repo.dart b/lib/services/api_repo/login_api_repo.dart index 88b6d9a..cbaad24 100644 --- a/lib/services/api_repo/login_api_repo.dart +++ b/lib/services/api_repo/login_api_repo.dart @@ -1,5 +1,9 @@ +import 'dart:convert'; + import 'package:hmg_nurses/exceptions/api_exception.dart'; import 'package:hmg_nurses/main.dart'; +import 'package:hmg_nurses/model/base/generic_response_model2.dart'; +import 'package:hmg_nurses/model/login/member_login_model.dart'; import 'package:hmg_nurses/model/login/project_info_model.dart'; import 'package:hmg_nurses/services/api_client.dart'; import 'package:hmg_nurses/classes/consts.dart'; @@ -8,14 +12,18 @@ import 'package:hmg_nurses/model/login/imei_details_model.dart'; import 'package:hmg_nurses/services/firebase_service.dart'; import 'package:injector/injector.dart'; - - abstract class ILoginApiRepo { Future> getDeviceInfoByIMEI(); Future> getProjectInfo(String userId); - Future memberLogin(String userId, String password, int projectId); + Future memberLogin(String userId, String password, int projectId); + + Future sendActivationCode(MemberLoginModel memberLoginModel, int facilityID, int sendOtpType); + + Future checkActivationCode(String activationCode, int sendOtpType, bool isFromSilentLogin); + + getDoctorProfile(); } class LoginApiRepo implements ILoginApiRepo { @@ -26,6 +34,7 @@ class LoginApiRepo implements ILoginApiRepo { String url = "${ApiConsts.baseUrlServices}DoctorApplication.svc/REST/DoctorApp_GetDeviceDetailsByIMEI"; String token = await _firebaseService.getFirebaseToke(); logger.d("firebase_token: " + token); + appState.imei = token; Map postParams = {}; postParams.addAll(appState.postParamsJson); @@ -57,7 +66,7 @@ class LoginApiRepo implements ILoginApiRepo { } @override - Future memberLogin(String userId, String password, int projectId) async { + Future memberLogin(String userId, String password, int projectId) async { String url = "${ApiConsts.baseUrlServices}Sentry.svc/REST/MemberLogIN_New"; Map postParams = {}; @@ -65,12 +74,94 @@ class LoginApiRepo implements ILoginApiRepo { postParams["UserID"] = userId; postParams["Password"] = password; postParams["ProjectID"] = projectId; + MemberLoginModel response; + try { + response = await Injector.appInstance.get().postJsonForObject((json) => MemberLoginModel.fromJson(json), url, postParams); + } catch (e) { + rethrow; + } + return response; + } + + @override + Future sendActivationCode(MemberLoginModel memberLoginModel, int facilityID, int sendOtpType) async { + String url = "${ApiConsts.baseUrlServices}DoctorApplication.svc/REST/SendActivationCodeForDoctorApp"; + Map postParams = {}; + + postParams.addAll(appState.postParamsJson); + postParams["MemberID"] = memberLoginModel.listMemberInformation!.first.memberId; + postParams["facilityId"] = facilityID; + postParams["OTP_SendType"] = sendOtpType.toString(); + postParams["LoginDoctorID"] = memberLoginModel.doctorId; + postParams["DoctorID"] = memberLoginModel.doctorId; + postParams["TokenID"] = appState.logInTokenID; + GenericResponseModel response; + print(jsonEncode(postParams)); + // return GenericResponseModel(); + try { + response = await Injector.appInstance.get().postJsonForObject((json) => GenericResponseModel.fromJson(json), url, postParams); + appState.logInTokenID = response.logInTokenId.toString(); + } catch (e) { + rethrow; + } + return response; + } + + @override + Future checkActivationCode(String activationCode, int sendOtpType, bool isFromSilentLogin) async { + String url = "${ApiConsts.baseUrlServices}DoctorApplication.svc/REST/CheckActivationCodeForDoctorApp"; + Map postParams = {}; + MemberLoginModel memberLoginModel = appState.memberBeforeLogin ?? MemberLoginModel(); + postParams.addAll(appState.postParamsJson); + postParams["MobileNumber"] = memberLoginModel.mobileNumber; + postParams["ProjectID"] = appState.projectID; + postParams["LogInTokenID"] = appState.logInTokenID; + postParams["activationCode"] = activationCode; + postParams["OTP_SendType"] = sendOtpType; + postParams["facilityId"] = appState.projectID; + postParams["MemberID"] = appState.memberBeforeLogin!.listMemberInformation!.first.memberId; + postParams["Password"] = appState.password; + postParams["IsForSilentLogin"] = isFromSilentLogin; + postParams["LoginDoctorID"] = appState.memberBeforeLogin?.doctorId; + postParams["DoctorID"] = appState.memberBeforeLogin?.doctorId; + postParams["IMEI"] = appState.imei; + postParams["ZipCode"] = appState.memberBeforeLogin?.zipCode; + postParams["TokenID"] = appState.logInTokenID; + GenericResponseModel response; try { response = await Injector.appInstance.get().postJsonForObject((json) => GenericResponseModel.fromJson(json), url, postParams); + appState.vidaAuthTokenID = response.vidaAuthTokenId; + appState.vidaRefreshTokenID = response.vidaRefreshTokenId; + appState.authenticationTokenID = response.authenticationTokenId; + appState.listDoctorsClinic = response.listDoctorsClinic; + appState.projectID = response.listDoctorsClinic!.first.projectId!; + appState.clinicId = response.listDoctorsClinic!.first.clinicId!; } catch (e) { rethrow; } return response; } + + @override + getDoctorProfile() async { + String url = "${ApiConsts.baseUrlServices}Doctors.svc/REST/GetDocProfiles"; + Map postParams = {}; + postParams.addAll(appState.postParamsJson); + postParams["ProjectID"] = appState.projectID; + postParams["ClinicID"] = appState.clinicId; + postParams["doctorID"] = appState.memberBeforeLogin!.doctorId; + postParams["IsRegistered"] = true; + postParams["License"] = true; + postParams["TokenID"] = appState.authenticationTokenID; + postParams["DoctorID"] = appState.memberBeforeLogin!.doctorId; + postParams["PatientOutSA"] = false; + + GenericResponseModel2 response; + try { + response = await Injector.appInstance.get().postJsonForObject((json) => GenericResponseModel2.fromJson(json), url, postParams); + } catch (e) { + rethrow; + } + } } diff --git a/lib/ui/login/login_method_page.dart b/lib/ui/login/login_method_page.dart index 224674e..a3cf133 100644 --- a/lib/ui/login/login_method_page.dart +++ b/lib/ui/login/login_method_page.dart @@ -3,13 +3,17 @@ import 'package:flutter/material.dart'; import 'package:hexcolor/hexcolor.dart'; import 'package:hmg_nurses/classes/colors.dart'; import 'package:hmg_nurses/classes/enums.dart'; +import 'package:hmg_nurses/extensions/int_extensions.dart'; import 'package:hmg_nurses/extensions/string_extensions.dart'; import 'package:hmg_nurses/extensions/util_extensions.dart'; import 'package:hmg_nurses/extensions/widget_extensions.dart'; import 'package:hmg_nurses/generated/locale_keys.g.dart'; +import 'package:hmg_nurses/main.dart'; +import 'package:hmg_nurses/provider/login_provider_model.dart'; import 'package:hmg_nurses/ui/login/login_vm.dart'; import 'package:hmg_nurses/ui/login/widgets/verification_method_card.dart'; import 'package:hmg_nurses/widgets/button/default_button.dart'; +import 'package:local_auth/local_auth.dart'; import 'package:provider/provider.dart'; import 'package:sizer/sizer.dart'; @@ -31,10 +35,126 @@ class LoginMethodsPageState extends State { late AuthMethodTypes fingerPrintBefore; late AuthMethodTypes selectedOption; late LoginViewModel loginViewModel; + LoginType? loginType; + late LoginProviderModel loginProviderModel; @override Widget build(BuildContext context) { + if (loginType == null) { + loginType = ModalRoute.of(context)!.settings.arguments as LoginType; + } loginViewModel = context.read(); + loginProviderModel = context.read(); + return Scaffold( + appBar: AppBar( + backgroundColor: Colors.transparent, + leading: IconButton( + icon: const Icon(Icons.arrow_back_ios, color: MyColors.darkIconColor), + onPressed: () => Navigator.pop(context), + ), + // actions: [Center(child: "Employee Digital ID".toText12(color: MyColors.textMixColor, isUnderLine: true).onPress(() {})), 21.width], + ), + body: Container( + width: double.infinity, + height: double.infinity, + padding: const EdgeInsets.all(21), + child: Column( + children: [ + Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (loginType == LoginType.FROM_LOGIN || loginType == LoginType.REGISTER_NEW_BIO) + Column( + children: [ + LocaleKeys.pleaseVerifyForBio.tr().toText14(), + 21.height, + ], + ), + if (loginType == LoginType.FROM_LOGIN || loginType == LoginType.DIRECT_LOGIN) + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Expanded( + child: VerificationMethodsList( + authMethodType: AuthMethodTypes.faceID, + isBioAvailable: loginProviderModel.isFaceBioAvailable, + authenticateUser: (AuthMethodTypes authMethodType, isActive) async { + // loginViewModel.startSMSService(authMethodType, context: context); + // appState.setMemberBeforeLogin + bool isAuthenticated = await loginProviderModel.loginWithFaceIDAndBiometrics(); + if (isAuthenticated) { + if (loginType == LoginType.FROM_LOGIN) { + print("Authentacted"); + print(loginType); + loginType = LoginType.REGISTER_NEW_BIO; + setState(() {}); + } + } else { + print("Authentaction Failded"); + } + }, + ), + ), + 21.width, + Expanded( + child: VerificationMethodsList( + authMethodType: AuthMethodTypes.fingerPrint, + isBioAvailable: loginProviderModel.isFingerBioAvailable, + onShowMore: () async { + bool isAuthenticated = await loginProviderModel.loginWithFaceIDAndBiometrics(); + if (isAuthenticated) { + if (loginType == LoginType.FROM_LOGIN) { + print("Authentacted"); + print(loginType); + loginType = LoginType.REGISTER_NEW_BIO; + setState(() {}); + } + } else { + print("Authentaction Failded"); + } + }, + ), + ), + ], + ), + 21.height, + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Expanded( + child: VerificationMethodsList( + authMethodType: AuthMethodTypes.sms, + authenticateUser: (AuthMethodTypes authMethodType, isActive) { + // loginViewModel.startSMSService(authMethodType, context: context); + loginProviderModel.sendActivationCode( + appState.memberBeforeLogin!, + appState.projectID, + loginProviderModel.getLoginMethodId(AuthMethodTypes.sms), + false, + ); + }, + ), + ), + 21.width, + Expanded( + child: VerificationMethodsList( + authMethodType: AuthMethodTypes.whatsApp, + onShowMore: () { + setState(() { + isMoreOption = true; + }); + }, + ), + ), + ], + ), + ], + ), + ], + ), + ), + ); return Scaffold( appBar: AppBar( backgroundColor: Colors.transparent, @@ -55,16 +175,19 @@ class LoginMethodsPageState extends State { heightSpacer1per(), if (loginViewModel.isFromLogin) InkWell( - onTap: () { - loginViewModel.setUnverified(false, isFromLogin: false); - loginViewModel.setAppStatus(APPSTATUS.unAuthenticated); - }, - child: const Icon(Icons.arrow_back_ios, color: MyColors.darkTextColor)), + onTap: () { + // loginViewModel.setUnverified(false, isFromLogin: false); + // loginViewModel.setAppStatus(APPSTATUS.unAuthenticated); + }, + child: const Icon( + Icons.arrow_back_ios, + color: MyColors.darkTextColor, + ), + ), Column( children: [ heightSpacer1per(), - - isMoreOption != null && isMoreOption == false + isMoreOption == false ? Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.start, @@ -98,62 +221,13 @@ class LoginMethodsPageState extends State { "${loginViewModel.getType(1)}".toText11(isBold: true), ], ), - // child: RichText( - // text: TextSpan( - // text: "${LocaleKeys.verificationType.tr()} ", - // style: TextStyle( - // color: const Color(0xFF575757), - // fontSize: SizeConfig.getTextMultiplierBasedOnWidth() * 3.5, - // fontFamily: 'Poppins', - // fontWeight: FontWeight.w600, - // letterSpacing: -0.4), - // children: [ - // TextSpan( - // text: loginViewModel.getType(1), - // style: TextStyle( - // color: MyColors.darkTextColor, - // fontSize: SizeConfig.getTextMultiplierBasedOnWidth() * 3.5, - // fontFamily: 'Poppins', - // fontWeight: FontWeight.w600, - // letterSpacing: -0.48), - // ) - // ]), - // ), ), ], ), Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.end, - children: [ - "12 NOV, 2022".toText11(isBold: true), - heightSpacer06per(), - "09:56 AM".toText10() - // AppText( - // loginViewModel.user.editedOn != null - // ? AppDateUtils.getDayMonthYearDateFormatted(AppDateUtils.convertStringToDate(loginViewModel.user.editedOn), isMonthShort: true) - // : loginViewModel.user.createdOn != null - // ? AppDateUtils.getDayMonthYearDateFormatted(AppDateUtils.convertStringToDate(loginViewModel.user.createdOn), isMonthShort: true) - // : '--', - // textAlign: TextAlign.right, - // fontSize: SizeConfig.getTextMultiplierBasedOnWidth() * 4.5, - // color: Color(0xFF2E303A), - // fontWeight: FontWeight.w700, - // letterSpacing: -0.48, - // ), - // AppText( - // loginViewModel.user.editedOn != null - // ? AppDateUtils.getHour(AppDateUtils.convertStringToDate(loginViewModel.user.editedOn)) - // : loginViewModel.user.createdOn != null - // ? AppDateUtils.getHour(AppDateUtils.convertStringToDate(loginViewModel.user.createdOn)) - // : '--', - // textAlign: TextAlign.right, - // fontSize: SizeConfig.getTextMultiplierBasedOnWidth() * 3.5, - // fontWeight: FontWeight.w600, - // letterSpacing: -0.48, - // color: Color(0xFF575757), - // ) - ], + children: ["12 NOV, 2022".toText11(isBold: true), heightSpacer06per(), "09:56 AM".toText10()], ) ], ), @@ -163,15 +237,18 @@ class LoginMethodsPageState extends State { heightSpacer2per(), ], ) - : Column(mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.start, children: [ - LocaleKeys.pleaseVerifyForBio.tr().toText14().paddingAll(10), - ]), - isMoreOption != null && isMoreOption == false + : Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.pleaseVerifyForBio.tr().toText14().paddingAll(10), + ], + ), + isMoreOption == false ? Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Row(mainAxisAlignment: MainAxisAlignment.center, children: [ Expanded( child: VerificationMethodsList( - loginViewModel: loginViewModel, authMethodType: SelectedAuthMethodTypesService.getMethodsTypeService(1), authenticateUser: (AuthMethodTypes authMethodType, isActive) { loginViewModel.startSMSService(authMethodType, context: context); @@ -180,7 +257,6 @@ class LoginMethodsPageState extends State { ), Expanded( child: VerificationMethodsList( - loginViewModel: loginViewModel, authMethodType: AuthMethodTypes.moreOptions, onShowMore: () { setState(() { @@ -197,7 +273,6 @@ class LoginMethodsPageState extends State { children: [ Expanded( child: VerificationMethodsList( - loginViewModel: loginViewModel, authMethodType: AuthMethodTypes.fingerPrint, authenticateUser: (AuthMethodTypes authMethodType, isActive) { loginViewModel.startSMSService(authMethodType, context: context); @@ -205,7 +280,6 @@ class LoginMethodsPageState extends State { )), Expanded( child: VerificationMethodsList( - loginViewModel: loginViewModel, authMethodType: AuthMethodTypes.faceID, authenticateUser: (AuthMethodTypes authMethodType, isActive) { loginViewModel.startSMSService(authMethodType, context: context); @@ -219,7 +293,6 @@ class LoginMethodsPageState extends State { children: [ Expanded( child: VerificationMethodsList( - loginViewModel: loginViewModel, authMethodType: AuthMethodTypes.sms, authenticateUser: (AuthMethodTypes authMethodType, isActive) { loginViewModel.startSMSService(authMethodType, context: context); @@ -227,7 +300,6 @@ class LoginMethodsPageState extends State { )), Expanded( child: VerificationMethodsList( - loginViewModel: loginViewModel, authMethodType: AuthMethodTypes.whatsApp, authenticateUser: (AuthMethodTypes authMethodType, isActive) { loginViewModel.startSMSService(authMethodType, context: context); diff --git a/lib/ui/login/login_page.dart b/lib/ui/login/login_page.dart index ae5d7a7..ebe86f2 100644 --- a/lib/ui/login/login_page.dart +++ b/lib/ui/login/login_page.dart @@ -1,5 +1,6 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:hmg_nurses/classes/colors.dart'; import 'package:hmg_nurses/classes/enums.dart'; import 'package:hmg_nurses/classes/utils.dart'; @@ -8,13 +9,16 @@ import 'package:hmg_nurses/extensions/string_extensions.dart'; import 'package:hmg_nurses/extensions/widget_extensions.dart'; import 'package:hmg_nurses/extensions/int_extensions.dart'; import 'package:hmg_nurses/generated/locale_keys.g.dart'; +import 'package:hmg_nurses/main.dart'; import 'package:hmg_nurses/model/login/imei_details_model.dart'; +import 'package:hmg_nurses/model/login/member_login_model.dart'; import 'package:hmg_nurses/model/login/project_info_model.dart'; import 'package:hmg_nurses/provider/login_provider_model.dart'; import 'package:hmg_nurses/widgets/button/default_button.dart'; import 'package:hmg_nurses/widgets/cupertino_picker.dart'; import 'package:hmg_nurses/widgets/input_widget.dart'; import 'package:injector/injector.dart'; +import 'package:local_auth/local_auth.dart'; import 'package:provider/provider.dart'; import 'package:sizer/sizer.dart'; @@ -28,130 +32,122 @@ class LoginPage extends StatefulWidget { } class _LoginPageState extends State { - final ILoginApiRepo _loginApiRepo = Injector.appInstance.get(); - - int branchID=0; + int branchID = 0; + late LoginProviderModel provider; final loginFormKey = GlobalKey(); var projectIdController = TextEditingController(); var userIdController = TextEditingController(); var passwordController = TextEditingController(); - FocusNode projectIdFocusNode = FocusNode(); - FocusNode userIdFocusNode = FocusNode(); - FocusNode passwordIdFocusNode = FocusNode(); @override void initState() { super.initState(); - checkLastSession(); - } - - checkLastSession() async { - try { - Utils.showLoading(); - List deviceInfo = await _loginApiRepo.getDeviceInfoByIMEI(); - Utils.showToast(deviceInfo.length.toString()); - Utils.showLoading(); - } catch (e) {} + provider = Provider.of(navigatorKey.currentContext!); + provider.checkLastSession(); } @override Widget build(BuildContext context) { - final provider = Provider.of(context); return Scaffold( body: SafeArea( - child: SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - LocaleKeys.welcomeTo.tr().toText14(color: MyColors.blackColor), - LocaleKeys.drSulaiman.tr().toText20(isBold: true, color: MyColors.blackColor), - "Nurses App".toText16(color: MyColors.redColor), - ], - ), - ), - SizedBox(height: 4.h), - Form( - key: loginFormKey, - child: Padding( - padding: EdgeInsets.symmetric(horizontal: 8.w), - child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ - buildSpacer20h(), - CustomTextField( - LocaleKeys.userID.tr(), - userIdController, - isEnableBorder: true, - ), - buildSpacer20h(), - CustomTextField( - LocaleKeys.password.tr(), - passwordController, - isTextIsPassword: true, - onChange: (v) { - if (v.length > 0) { - provider.getAssignedBranches(userIdController.text); - } - }, - ), - buildSpacer20h(), - Consumer( - builder: (_, data, w) { - return data.state == ViewState.hide - ? Container() - : data.state == ViewState.busy - ? const Center(child: CircularProgressIndicator()) - : CustomTextField( - LocaleKeys.branch.tr(), - projectIdController, - hasSelection: true, - isEnable: false, - onClick: () => CustomCupertinoPicker.showCupertinoPicker( - context, - provider.assignedBranches, - (index) { - projectIdController.text=provider.assignedBranches[index].facilityName!; - branchID=provider.assignedBranches[index].facilityId as int; - print(branchID); - provider.notifyListeners(); - }, - ), - ); - }, + child: Column( + children: [ + Expanded( + child: SingleChildScrollView( + child: SizedBox( + height: MediaQuery.of(context).size.height / 1.2, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + flex: 1, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.welcomeTo.tr().toText14(color: MyColors.blackColor), + LocaleKeys.drSulaiman.tr().toText20(isBold: true, color: MyColors.blackColor), + "Nurses App".toText16(color: MyColors.redColor), + ], + ), + ), + Expanded( + flex: 3, + child: Form( + key: loginFormKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + CustomTextField( + LocaleKeys.userID.tr(), + userIdController, + isEnableBorder: true, + isInputTypeNum: true, + ), + 16.height, + CustomTextField( + LocaleKeys.password.tr(), + passwordController, + isTextIsPassword: true, + onChange: (v) { + if (v.length == 1) { + provider.getAssignedBranches(userIdController.text); + } + }, + ), + 16.height, + Consumer( + builder: (_, data, w) { + // if (data.state == ViewState.idle && provider.assignedBranches.isNotEmpty) { + // projectIdController.text = provider.assignedBranches.first.facilityName!; + // branchID = provider.assignedBranches.first.facilityId as int; + // print(branchID); + // provider.notifyListeners(); + // } + return data.state == ViewState.hide + ? Container() + : data.state == ViewState.busy + ? const Center(child: CircularProgressIndicator()) + : CustomTextField( + LocaleKeys.branch.tr(), + projectIdController, + hasSelection: true, + isEnable: false, + onClick: () => CustomCupertinoPicker.showCupertinoPicker( + context, + provider.assignedBranches, + (index) { + projectIdController.text = provider.assignedBranches[index].facilityName!; + branchID = provider.assignedBranches[index].facilityId as int; + provider.notifyListeners(); + }, + ), + ); + }, + ), + ], + ), + ), + ), + ], ), - buildSpacer20h(), - SizedBox( - height: 12.h, - ), - ]), + ), ), ), - ], - ), - ), - bottomSheet: Container( - height: 12.h, - color: MyColors.backgroundColor, - width: double.infinity, - child: Center( - child: FractionallySizedBox( - widthFactor: 0.89, - child: Column( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Padding( - padding: EdgeInsets.symmetric(horizontal: 4.w), - child: DefaultButton(LocaleKeys.login.tr(), () { - Navigator.pushNamed(context, AppRoutes.loginMethodsPage); - }, colors: const [MyColors.redColor, MyColors.redColor]), - ), - heightSpacer3per(), + 21.height, + DefaultButton( + LocaleKeys.login.tr(), + () async { + appState.password = passwordController.text; + provider.performLogin(userIdController.text, passwordController.text, branchID); + }, + colors: const [ + MyColors.redColor, + MyColors.redColor, ], ), - ), - ), + ], + ).paddingAll(21), ), ); } diff --git a/lib/ui/login/login_vm.dart b/lib/ui/login/login_vm.dart index 27b1e7e..4003b2d 100644 --- a/lib/ui/login/login_vm.dart +++ b/lib/ui/login/login_vm.dart @@ -15,7 +15,6 @@ class LoginViewModel extends BaseViewModel { bool isLogin = false; bool unverified = false; bool isFromLogin = false; - APPSTATUS appStatus = APPSTATUS.loading; String localToken = ""; String nurseProfile = ""; @@ -26,7 +25,7 @@ class LoginViewModel extends BaseViewModel { LoginViewModel(); /// get type name based on id. - getType(type) { + String getType(type) { switch (type) { case 1: return LocaleKeys.sms.tr(); @@ -41,6 +40,20 @@ class LoginViewModel extends BaseViewModel { } } + int getLoginMethodId(AuthMethodTypes authMethodTypes) { + switch (authMethodTypes) { + case AuthMethodTypes.sms: + return 1; + case AuthMethodTypes.whatsApp: + return 2; + case AuthMethodTypes.fingerPrint: + return 3; + case AuthMethodTypes.faceID: + return 4; + default: + return 1; + } + } /// ask user to add his biometric showIOSAuthMessages() async { try { @@ -77,28 +90,7 @@ class LoginViewModel extends BaseViewModel { } } - /// determine the status of the app - APPSTATUS get status { - if (state == ViewState.busy) { - appStatus = APPSTATUS.loading; - } else { - if (nurseProfile != null) { - appStatus = APPSTATUS.authenticated; - } else if (unverified) { - appStatus = APPSTATUS.unverified; - } else if (isLogin) { - appStatus = APPSTATUS.authenticated; - } else { - appStatus = APPSTATUS.unAuthenticated; - } - } - return appStatus; - } - - setAppStatus(APPSTATUS status) { - appStatus = status; - notifyListeners(); - } + /// determine the status of the ap setUnverified(bool unverified, {bool isFromLogin = false}) { this.unverified = unverified; @@ -129,7 +121,7 @@ class LoginViewModel extends BaseViewModel { startSMSService(AuthMethodTypes type, {isSilentLogin = false, required BuildContext context}) { OtpDialog( type: 1, - mobileNo: 0504278212, + mobileNo: "0504278212", onSuccess: (String otpCode, TextEditingController pinPut) { Utils.showLoading(); //TODO: API CALL diff --git a/lib/ui/login/widgets/verification_method_card.dart b/lib/ui/login/widgets/verification_method_card.dart index 09a7bb5..0199585 100644 --- a/lib/ui/login/widgets/verification_method_card.dart +++ b/lib/ui/login/widgets/verification_method_card.dart @@ -9,58 +9,62 @@ import 'package:hmg_nurses/generated/locale_keys.g.dart'; import 'package:hmg_nurses/ui/login/login_vm.dart'; import 'package:local_auth/local_auth.dart'; -class VerificationMethodsList extends StatefulWidget { +class VerificationMethodsList extends StatelessWidget { final AuthMethodTypes authMethodType; final Function(AuthMethodTypes type, bool isActive)? authenticateUser; final Function? onShowMore; - final LoginViewModel loginViewModel; + final bool isBioAvailable; - const VerificationMethodsList({Key? key, required this.authMethodType, this.authenticateUser, this.onShowMore, required this.loginViewModel}) : super(key: key); - - @override - VerificationMethodsListState createState() => VerificationMethodsListState(); -} - -class VerificationMethodsListState extends State { - final LocalAuthentication auth = LocalAuthentication(); + const VerificationMethodsList({ + Key? key, + required this.authMethodType, + this.authenticateUser, + this.onShowMore, + this.isBioAvailable = true, + }) : super(key: key); @override Widget build(BuildContext context) { - switch (widget.authMethodType) { + switch (authMethodType) { case AuthMethodTypes.whatsApp: return MethodTypeCard( assetPath: 'assets/images/login/verify_whatsapp.svg', - onTap: () => {widget.authenticateUser!(AuthMethodTypes.whatsApp, true)}, + onTap: () => {authenticateUser!(AuthMethodTypes.whatsApp, true)}, label: LocaleKeys.verifyThroughWhatsapp.tr(), + isBioAvailable: isBioAvailable, ); case AuthMethodTypes.sms: return MethodTypeCard( assetPath: "assets/images/login/verify_sms.svg", - onTap: () => {widget.authenticateUser!(AuthMethodTypes.sms, true)}, + onTap: () => {authenticateUser!(AuthMethodTypes.sms, true)}, label: LocaleKeys.verifyThroughSMS.tr(), + isBioAvailable: isBioAvailable, ); case AuthMethodTypes.fingerPrint: return MethodTypeCard( assetPath: 'assets/images/login/verify_thumb.svg', - onTap: () => {widget.authenticateUser!(AuthMethodTypes.fingerPrint, true)}, + onTap: () => {authenticateUser!(AuthMethodTypes.fingerPrint, true)}, label: LocaleKeys.verifyThroughFingerprint.tr(), + isBioAvailable: isBioAvailable, ); case AuthMethodTypes.faceID: return MethodTypeCard( assetPath: 'assets/images/login/verify_face.svg', - onTap: () => {widget.authenticateUser!(AuthMethodTypes.faceID, true)}, + onTap: () => {authenticateUser!(AuthMethodTypes.faceID, true)}, label: LocaleKeys.verifyThroughFace.tr(), + isBioAvailable: isBioAvailable, ); default: return MethodTypeCard( assetPath: 'assets/images/login/more_icon.png', onTap: () { - widget.onShowMore!(); + onShowMore!(); }, isSvg: false, label: LocaleKeys.moreVerificationOpts.tr(), height: 0, + isBioAvailable: isBioAvailable, ); } } @@ -74,12 +78,14 @@ class MethodTypeCard extends StatelessWidget { required this.label, this.height = 20, this.isSvg = true, + required this.isBioAvailable, }) : super(key: key); final String assetPath; final GestureTapCallback onTap; final String label; final double height; final bool isSvg; + final bool isBioAvailable; @override Widget build(BuildContext context) { @@ -92,44 +98,44 @@ class MethodTypeCard extends StatelessWidget { return InkWell( onTap: onTap, child: Container( - margin: const EdgeInsets.all(10), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: const BorderRadius.all(Radius.circular(10)), - border: Border.all(color: HexColor('#707070'), width: 0.1), - ), - height: cardHeight, - child: Padding( - padding: const EdgeInsets.all(12.0), - child: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - isSvg - ? SvgPicture.asset(assetPath, width: SizeConfig.widthMultiplier! * (14), height: cardHeight * 0.20) - : Image.asset( - assetPath, - width: SizeConfig.widthMultiplier! * (12), - height: cardHeight * 0.35, - // height: , - ), - SizedBox( - height: height, + decoration: BoxDecoration( + color: isBioAvailable ? Colors.white : Colors.grey[400], + borderRadius: const BorderRadius.all(Radius.circular(10)), + border: Border.all(color: HexColor('#707070'), width: 0.1), + ), + height: cardHeight, + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + isSvg + ? SvgPicture.asset(assetPath, width: SizeConfig.widthMultiplier! * (14), height: cardHeight * 0.20) + : Image.asset( + assetPath, + width: SizeConfig.widthMultiplier! * (12), + height: cardHeight * 0.35, + // height: , + ), + SizedBox( + height: height, + ), + Text( + label, + style: TextStyle( + fontSize: SizeConfig.getTextMultiplierBasedOnWidth() * (SizeConfig.isHeightVeryShort ? 3 : 3.7), + color: MyColors.darkTextColor, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, ), - Text( - label, - style: TextStyle( - fontSize: SizeConfig.getTextMultiplierBasedOnWidth() * (SizeConfig.isHeightVeryShort ? 3 : 3.7), - color: MyColors.darkTextColor, - fontWeight: FontWeight.w600, - letterSpacing: -0.48, - ), - ) - ], - ), + ) + ], ), - )), + ), + ), + ), ); } } diff --git a/lib/widgets/cupertino_picker.dart b/lib/widgets/cupertino_picker.dart index ad0a16f..8cd48f8 100644 --- a/lib/widgets/cupertino_picker.dart +++ b/lib/widgets/cupertino_picker.dart @@ -44,14 +44,14 @@ class CustomCupertinoPicker { mainAxisAlignment: MainAxisAlignment.end, children: [ CupertinoButton( - child: Text(LocaleKeys.userID.tr(), style: textStyle(context)), + child: Text(LocaleKeys.cancel.tr(), style: textStyle(context)), onPressed: () { Navigator.pop(context); }, ), CupertinoButton( child: Text( - LocaleKeys.userID.tr(), + LocaleKeys.select.tr(), style: textStyle(context), ), onPressed: () { diff --git a/lib/widgets/dialogs/otp_dialog.dart b/lib/widgets/dialogs/otp_dialog.dart index 324ff70..873fad8 100644 --- a/lib/widgets/dialogs/otp_dialog.dart +++ b/lib/widgets/dialogs/otp_dialog.dart @@ -14,7 +14,7 @@ final ValueNotifier otpFieldClear = ValueNotifier(""); class OtpDialog { final int type; - final int? mobileNo; + final String? mobileNo; final Function(String, TextEditingController _pinPutController) onSuccess; final Function onFailure; final Function onResendCode; @@ -78,10 +78,10 @@ class OtpDialog { type == 1 ? "assets/images/login/verify_sms.svg" : type == 2 - ? "assets/images/login/verify_whatsapp.svg" - : type == 3 - ? "assets/images/login/verify_face.svg" - : 'assets/images/login/verify_thumb.svg', + ? "assets/images/login/verify_whatsapp.svg" + : type == 3 + ? "assets/images/login/verify_face.svg" + : 'assets/images/login/verify_thumb.svg', height: 50, width: 50, ), @@ -118,33 +118,34 @@ class OtpDialog { 10.height, stopTimer ? Row( - children: [ - Expanded( - child: LocaleKeys.codeExpire.tr().toText16( - color: MyColors.redColor, - ), - ), - 12.width, - Image.asset( - "assets/icons/ic_alarm.png", - width: 20, - height: 20, - color: MyColors.redColor, - ), - ], - ) + children: [ + Expanded( + child: LocaleKeys.codeExpire.tr().toText16( + color: MyColors.redColor, + maxlines: 1, + ), + ), + 12.width, + Image.asset( + "assets/icons/ic_alarm.png", + width: 20, + height: 20, + color: MyColors.redColor, + ), + ], + ) : RichText( - text: TextSpan( - text: '${LocaleKeys.theVerificationCodeWillExpireIn.tr()}\n', - style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: MyColors.darkTextColor, letterSpacing: -0.48), - children: [ - TextSpan( - text: displayTime, - style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: MyColors.textMixColor, letterSpacing: -0.48), + text: TextSpan( + text: '${LocaleKeys.theVerificationCodeWillExpireIn.tr()}\n', + style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: MyColors.darkTextColor, letterSpacing: -0.48), + children: [ + TextSpan( + text: displayTime, + style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: MyColors.textMixColor, letterSpacing: -0.48), + ), + ], + ), ), - ], - ), - ), ], ); }, @@ -153,7 +154,7 @@ class OtpDialog { 18.height, DefaultButton( stopTimer ? LocaleKeys.resend.tr() : LocaleKeys.cancel.tr(), - () async { + () async { if (stopTimer) { hideSMSBox(context); onResendCode(); @@ -166,9 +167,9 @@ class OtpDialog { colors: stopTimer ? null : [ - MyColors.redColor, - MyColors.redColor, - ], + MyColors.redColor, + MyColors.redColor, + ], ), ], ), @@ -215,7 +216,7 @@ class OtpDialog { void startTimer(setState) { remainingTime--; if (stopTimer) return; - setState(() { + setState(() { displayTime = getSecondsAsDigitalClock(remainingTime); }); @@ -249,4 +250,4 @@ class OtpDialog { // // return null; // // } // } -} \ No newline at end of file +} diff --git a/lib/widgets/input_widget.dart b/lib/widgets/input_widget.dart index 1a38198..9674e28 100644 --- a/lib/widgets/input_widget.dart +++ b/lib/widgets/input_widget.dart @@ -19,6 +19,8 @@ class CustomTextField extends StatefulWidget { final double verticalPadding; final double horizontalPadding; final Function(String)? onChange; + final Function()? onEditComplete; + final Function(String)? onSubmit; final Function? onClick; final FocusNode? focusNode; @@ -34,6 +36,8 @@ class CustomTextField extends StatefulWidget { this.isEnableBorder = true, this.lines = 1, this.onChange, + this.onEditComplete, + this.onSubmit, this.onClick, this.isInputTypeNum = false, this.isBackgroundEnable = false, @@ -48,10 +52,12 @@ class CustomTextField extends StatefulWidget { class CustomTextFieldState extends State { late bool isObscureText; + late FocusNode focusNode; @override void initState() { super.initState(); + focusNode = FocusNode(); isObscureText = widget.isTextIsPassword; } @@ -62,24 +68,20 @@ class CustomTextFieldState extends State { @override Widget build(BuildContext context) { - return Container( - padding: EdgeInsets.only(left: widget.horizontalPadding, right: widget.horizontalPadding, bottom: widget.verticalPadding, top: widget.verticalPadding), - alignment: Alignment.center, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(15), - color: widget.isBackgroundEnable ? const Color(0xffF7F7F7) : Colors.white, - border: Border.all(color: widget.isEnableBorder ? Colors.grey.shade300 : Colors.transparent, width: 1), - ), - child: InkWell( - onTap: widget.hasSelection - ? () { - widget.onClick!(); - } - : () { - if (widget.focusNode != null) { - widget.focusNode?.requestFocus(); - } - }, + return InkWell( + onTap: () { + focusNode.requestFocus(); + if(widget.hasSelection) + widget.onClick!(); + }, + child: Container( + padding: EdgeInsets.only(left: widget.horizontalPadding, right: widget.horizontalPadding, bottom: widget.verticalPadding, top: widget.verticalPadding), + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + color: widget.isBackgroundEnable ? const Color(0xffF7F7F7) : Colors.white, + border: Border.all(color: widget.isEnableBorder ? Colors.grey.shade300 : Colors.transparent, width: 1), + ), child: Row( children: [ Expanded( @@ -98,7 +100,7 @@ class CustomTextFieldState extends State { ), ), TextField( - focusNode: widget.focusNode, + focusNode: focusNode, autofocus: false, enabled: widget.isEnable, scrollPadding: EdgeInsets.zero, @@ -108,6 +110,8 @@ class CustomTextFieldState extends State { obscuringCharacter: "*", obscureText: isObscureText, onChanged: widget.onChange, + onEditingComplete: widget.onEditComplete, + onSubmitted: widget.onSubmit, style: const TextStyle( fontSize: 14, height: 21 / 14, diff --git a/pubspec.lock b/pubspec.lock index 0d40ef3..2d0e2f0 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -265,35 +265,7 @@ packages: name: local_auth url: "https://pub.dartlang.org" source: hosted - version: "2.1.2" - local_auth_android: - dependency: transitive - description: - name: local_auth_android - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.15" - local_auth_ios: - dependency: transitive - description: - name: local_auth_ios - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.10" - local_auth_platform_interface: - dependency: transitive - description: - name: local_auth_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - local_auth_windows: - dependency: transitive - description: - name: local_auth_windows - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.4" + version: "1.1.11" logger: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 7a5bf24..44449e8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -49,7 +49,7 @@ dependencies: auto_size_text: ^3.0.0 shimmer: ^2.0.0 sizer: ^2.0.15 - local_auth: ^2.1.2 + local_auth: ^1.1.9 # get_it: ^7.2.0 hexcolor: ^2.0.4 @@ -87,6 +87,7 @@ flutter: - assets/langs/ - assets/images/login/ - assets/images/patient/ + - assets/images/