diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index b78b8545..df7dfbc1 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -187,7 +187,7 @@ "lastName": "اسم العائلة", "female": "أنثى", "male": "ذكر", - "preferredLanguage": "اللغة المفضلة *", + "preferredLanguage": "اللغة المفضلة", "locationsRegister": "أين ترغب في إنشاء هذا الملف؟", "ksa": "السعودية", "dubai": "دبي", diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index cbea7b94..b0fe4622 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -187,7 +187,7 @@ "lastName": "Last Name", "female": "Female", "male": "Male", - "preferredLanguage": "Preferred Language *", + "preferredLanguage": "Preferred Language", "locationsRegister": "Where do you want to create this file?", "ksa": "KSA", "dubai": "Dubai", diff --git a/lib/features/profile_settings/models/get_patient_info_response_model.dart b/lib/features/profile_settings/models/get_patient_info_response_model.dart index e69de29b..ea89c9f9 100644 --- a/lib/features/profile_settings/models/get_patient_info_response_model.dart +++ b/lib/features/profile_settings/models/get_patient_info_response_model.dart @@ -0,0 +1,136 @@ +class GetPatientInfoForUpdate { + int? projectID; + int? patientType; + int? patientID; + String? emailAddress; + bool? isEmailAlertRequired; + bool? isSMSAlertRequired; + String? preferredLanguage; + String? emergencyContactName; + String? emergencyContactNo; + int? editedBy; + String? editedOn; + String? patientIdentificationNo; + int? patientIdentificationType; + String? firstName; + String? middleName; + String? lastName; + int? gender; + String? dateofBirth; + String? dateofBirthN; + String? firstNameN; + String? middleNameN; + String? lastNameN; + int? projectID1; + int? patientType1; + int? patientID1; + bool? isIVRStopped; + String? aGE; + String? genderString; + bool? isNeedUpdateIdintificationNo; + String? nationality; + String? type; + + GetPatientInfoForUpdate( + {this.projectID, + this.patientType, + this.patientID, + this.emailAddress, + this.isEmailAlertRequired, + this.isSMSAlertRequired, + this.preferredLanguage, + this.emergencyContactName, + this.emergencyContactNo, + this.editedBy, + this.editedOn, + this.patientIdentificationNo, + this.patientIdentificationType, + this.firstName, + this.middleName, + this.lastName, + this.gender, + this.dateofBirth, + this.dateofBirthN, + this.firstNameN, + this.middleNameN, + this.lastNameN, + this.projectID1, + this.patientType1, + this.patientID1, + this.isIVRStopped, + this.aGE, + this.genderString, + this.isNeedUpdateIdintificationNo, + this.nationality, + this.type}); + + GetPatientInfoForUpdate.fromJson(Map json) { + projectID = json['ProjectID']; + patientType = json['PatientType']; + patientID = json['PatientID']; + emailAddress = json['EmailAddress']; + isEmailAlertRequired = json['IsEmailAlertRequired']; + isSMSAlertRequired = json['IsSMSAlertRequired']; + preferredLanguage = json['PreferredLanguage']; + emergencyContactName = json['EmergencyContactName']; + emergencyContactNo = json['EmergencyContactNo']; + editedBy = json['EditedBy']; + editedOn = json['EditedOn']; + patientIdentificationNo = json['PatientIdentificationNo']; + patientIdentificationType = json['PatientIdentificationType']; + firstName = json['FirstName']; + middleName = json['MiddleName']; + lastName = json['LastName']; + gender = json['Gender']; + dateofBirth = json['DateofBirth']; + dateofBirthN = json['DateofBirthN']; + firstNameN = json['FirstNameN']; + middleNameN = json['MiddleNameN']; + lastNameN = json['LastNameN']; + projectID1 = json['ProjectID1']; + patientType1 = json['PatientType1']; + patientID1 = json['PatientID1']; + isIVRStopped = json['IsIVRStopped']; + aGE = json['AGE']; + genderString = json['GenderString']; + isNeedUpdateIdintificationNo = json['IsNeedUpdateIdintificationNo']; + nationality = json['Nationality']; + type = json['Type']; + } + + Map toJson() { + final Map data = new Map(); + data['ProjectID'] = this.projectID; + data['PatientType'] = this.patientType; + data['PatientID'] = this.patientID; + data['EmailAddress'] = this.emailAddress; + data['IsEmailAlertRequired'] = this.isEmailAlertRequired; + data['IsSMSAlertRequired'] = this.isSMSAlertRequired; + data['PreferredLanguage'] = this.preferredLanguage; + data['EmergencyContactName'] = this.emergencyContactName; + data['EmergencyContactNo'] = this.emergencyContactNo; + data['EditedBy'] = this.editedBy; + data['EditedOn'] = this.editedOn; + data['PatientIdentificationNo'] = this.patientIdentificationNo; + data['PatientIdentificationType'] = this.patientIdentificationType; + data['FirstName'] = this.firstName; + data['MiddleName'] = this.middleName; + data['LastName'] = this.lastName; + data['Gender'] = this.gender; + data['DateofBirth'] = this.dateofBirth; + data['DateofBirthN'] = this.dateofBirthN; + data['FirstNameN'] = this.firstNameN; + data['MiddleNameN'] = this.middleNameN; + data['LastNameN'] = this.lastNameN; + data['ProjectID1'] = this.projectID1; + data['PatientType1'] = this.patientType1; + data['PatientID1'] = this.patientID1; + data['IsIVRStopped'] = this.isIVRStopped; + data['AGE'] = this.aGE; + data['GenderString'] = this.genderString; + data['IsNeedUpdateIdintificationNo'] = this.isNeedUpdateIdintificationNo; + data['Nationality'] = this.nationality; + data['Type'] = this.type; + return data; + } +} diff --git a/lib/features/profile_settings/profile_settings_repo.dart b/lib/features/profile_settings/profile_settings_repo.dart index 253bf505..9d4c1221 100644 --- a/lib/features/profile_settings/profile_settings_repo.dart +++ b/lib/features/profile_settings/profile_settings_repo.dart @@ -3,6 +3,7 @@ import 'package:hmg_patient_app_new/core/api/api_client.dart'; import 'package:hmg_patient_app_new/core/api_consts.dart'; import 'package:hmg_patient_app_new/core/common_models/generic_api_model.dart'; import 'package:hmg_patient_app_new/core/exceptions/api_failure.dart'; +import 'package:hmg_patient_app_new/features/profile_settings/models/get_patient_info_response_model.dart'; import 'package:hmg_patient_app_new/services/logger_service.dart'; abstract class ProfileSettingsRepo { @@ -13,6 +14,8 @@ abstract class ProfileSettingsRepo { /// Deactivates (deletes) the patient's account. Future>> deactivateAccount(); + + Future>> getProfileSettings(); } class ProfileSettingsRepoImp implements ProfileSettingsRepo { @@ -96,5 +99,43 @@ class ProfileSettingsRepoImp implements ProfileSettingsRepo { return Left(UnknownFailure(e.toString())); } } + + @override + Future> getProfileSettings() async { + final Map body = {}; + + try { + GenericApiModel? apiResponse; + Failure? failure; + + await apiClient.post( + PROFILE_SETTING, + body: body, + onFailure: (error, statusCode, {messageStatus, failureType}) { + failure = failureType; + }, + onSuccess: (response, statusCode, {messageStatus, errorMessage}) { + try { + final patientProfileInfo = GetPatientInfoForUpdate.fromJson(response['PateintInfoForUpdateList'][0]); + + apiResponse = GenericApiModel( + messageStatus: messageStatus, + statusCode: statusCode, + errorMessage: errorMessage, + data: patientProfileInfo, + ); + } catch (e) { + failure = DataParsingFailure(e.toString()); + } + }, + ); + + if (failure != null) return Left(failure!); + if (apiResponse == null) return Left(ServerFailure("Unknown error")); + return Right(apiResponse!); + } catch (e) { + return Left(UnknownFailure(e.toString())); + } + } } diff --git a/lib/features/profile_settings/profile_settings_view_model.dart b/lib/features/profile_settings/profile_settings_view_model.dart index 92f11528..28f28af6 100644 --- a/lib/features/profile_settings/profile_settings_view_model.dart +++ b/lib/features/profile_settings/profile_settings_view_model.dart @@ -1,8 +1,16 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; +import 'package:get_it/get_it.dart'; +import 'package:hmg_patient_app_new/features/profile_settings/models/get_patient_info_response_model.dart'; import 'package:hmg_patient_app_new/features/profile_settings/profile_settings_repo.dart'; +import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/presentation/profile_settings/widgets/preferred_language_widget.dart'; import 'package:hmg_patient_app_new/services/cache_service.dart'; import 'package:hmg_patient_app_new/services/error_handler_service.dart'; +import 'package:hmg_patient_app_new/services/navigation_service.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; +import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; class ProfileSettingsViewModel extends ChangeNotifier { static const String _darkModeKey = 'is_dark_mode'; @@ -30,6 +38,9 @@ class ProfileSettingsViewModel extends ChangeNotifier { bool isDeactivateAccountSuccess = false; String? deactivateAccountError; + late GetPatientInfoForUpdate getPatientInfoForUpdate; + bool isPatientProfileLoading = false; + ProfileSettingsViewModel({ required CacheService cacheService, required this.profileSettingsRepo, @@ -88,6 +99,34 @@ class ProfileSettingsViewModel extends ChangeNotifier { ); } + Future getProfileSettings({ + Function(dynamic)? onSuccess, + Function(String)? onError, + }) async { + isPatientProfileLoading = true; + notifyListeners(); + + final result = await profileSettingsRepo.getProfileSettings(); + + result.fold( + (failure) { + isPatientProfileLoading = false; + notifyListeners(); + if (onError != null) { + onError(failure.message); + } else { + errorHandlerService.handleError(failure: failure); + } + }, + (response) { + getPatientInfoForUpdate = response.data; + isPatientProfileLoading = false; + notifyListeners(); + onSuccess?.call(response.data); + }, + ); + } + // ── Deactivate account ─────────────────────────────────────────────── Future deactivateAccount({ @@ -123,7 +162,14 @@ class ProfileSettingsViewModel extends ChangeNotifier { // ── Helpers ────────────────────────────────────────────────────────── - void notify() { - notifyListeners(); + openPreferredLanguageBottomSheet() { + showCommonBottomSheetWithoutHeight( + title: LocaleKeys.preferredLanguage.tr(), + GetIt.instance().navigatorKey.currentContext!, + child: PreferredLanguageWidget(), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); } } diff --git a/lib/presentation/book_appointment/book_appointment_page.dart b/lib/presentation/book_appointment/book_appointment_page.dart index 4a8ada6a..382516d7 100644 --- a/lib/presentation/book_appointment/book_appointment_page.dart +++ b/lib/presentation/book_appointment/book_appointment_page.dart @@ -57,7 +57,7 @@ class _BookAppointmentPageState extends State { scheduleMicrotask(() { // bookAppointmentsViewModel.selectedTabIndex = 0; bookAppointmentsViewModel.initBookAppointmentViewModel(); - bookAppointmentsViewModel.getLocation(); + // bookAppointmentsViewModel.getLocation(); immediateLiveCareViewModel.initImmediateLiveCare(); if (appState.isAuthenticated) { getIt.get().getPatientMyDoctors(); diff --git a/lib/presentation/home/widgets/welcome_widget.dart b/lib/presentation/home/widgets/welcome_widget.dart index 9b613e64..beff2ae4 100644 --- a/lib/presentation/home/widgets/welcome_widget.dart +++ b/lib/presentation/home/widgets/welcome_widget.dart @@ -7,6 +7,7 @@ import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/features/insurance/insurance_view_model.dart'; +import 'package:hmg_patient_app_new/features/profile_settings/profile_settings_view_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/insurance/insurance_home_page.dart'; import 'package:hmg_patient_app_new/presentation/profile_settings/profile_settings.dart'; @@ -40,6 +41,7 @@ class WelcomeWidget extends StatelessWidget { spacing: 8.h, children: [ Icon(Icons.menu, color: AppColors.textColor).onPress(() { + getIt.get().getProfileSettings(); Navigator.of(context).push(springPageRoute(ProfileSettings())); }), Image.asset(imageUrl, width: 40, height: 40), diff --git a/lib/presentation/insurance/widgets/patient_insurance_card.dart b/lib/presentation/insurance/widgets/patient_insurance_card.dart index 1607a7c6..ab70eb6f 100644 --- a/lib/presentation/insurance/widgets/patient_insurance_card.dart +++ b/lib/presentation/insurance/widgets/patient_insurance_card.dart @@ -136,7 +136,7 @@ class PatientInsuranceCard extends StatelessWidget { insuranceCardDetailsModel.groupName!.toText12(isBold: true), Row( children: [ - insuranceCardDetailsModel.companyName!.toText12(isBold: true), + (insuranceCardDetailsModel.companyName!.length > 40 ? "${insuranceCardDetailsModel.companyName!.substring(0, 40)}..." : insuranceCardDetailsModel.companyName!).toText12(isBold: true), SizedBox( width: 6.h, ), @@ -146,7 +146,7 @@ class PatientInsuranceCard extends StatelessWidget { color: AppColors.infoColor, borderRadius: 50.r, ), - child: (insuranceCardDetailsModel.subCategoryDesc!.length > 5 ? insuranceCardDetailsModel.subCategoryDesc!.substring(0, 12) : insuranceCardDetailsModel.subCategoryDesc!) + child: ((insuranceCardDetailsModel.subCategoryDesc ?? "").length > 10 ? (insuranceCardDetailsModel.subCategoryDesc ?? "").substring(0, 10) : (insuranceCardDetailsModel.subCategoryDesc ?? "")) .toText8(isBold: true, color: AppColors.whiteColor), ), ], diff --git a/lib/presentation/my_invoices/my_invoices_details_page.dart b/lib/presentation/my_invoices/my_invoices_details_page.dart index 79e1adc3..0410d311 100644 --- a/lib/presentation/my_invoices/my_invoices_details_page.dart +++ b/lib/presentation/my_invoices/my_invoices_details_page.dart @@ -6,6 +6,7 @@ import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/utils/date_util.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; +import 'package:hmg_patient_app_new/extensions/int_extensions.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/features/my_invoices/models/get_invoice_details_response_model.dart'; @@ -183,48 +184,6 @@ class _MyInvoicesDetailsPageState extends State { ), ), SizedBox(height: 16.h), - Row( - mainAxisSize: MainAxisSize.max, - children: [ - Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 20.h, - hasShadow: true, - ), - child: Padding( - padding: EdgeInsets.all(14.h), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - widget.getInvoiceDetailsResponseModel.listConsultation!.first.procedureName!.toText16(isBold: true), - SizedBox(height: 16.h), - Wrap( - direction: Axis.horizontal, - spacing: 6.w, - runSpacing: 6.h, - children: [ - AppCustomChipWidget( - labelText: "${LocaleKeys.quantity.tr()}: ${widget.getInvoiceDetailsResponseModel.listConsultation!.first.quantity!}", - labelPadding: EdgeInsetsDirectional.only(start: 6.w, end: 6.w), - ), - AppCustomChipWidget( - labelText: "${LocaleKeys.price.tr()}: ${widget.getInvoiceDetailsResponseModel.listConsultation!.first.price!} ${LocaleKeys.sar.tr()}", - labelPadding: EdgeInsetsDirectional.only(start: 6.w, end: 6.w), - ), - AppCustomChipWidget( - labelText: "${LocaleKeys.total.tr()}: ${widget.getInvoiceDetailsResponseModel.listConsultation!.first.total!} ${LocaleKeys.sar.tr()}", - labelPadding: EdgeInsetsDirectional.only(start: 6.w, end: 6.w), - ), - ], - ), - ], - ), - ), - ), - ], - ), - SizedBox(height: 16.h), Container( decoration: RoundedRectangleBorder().toSmoothCornerDecoration( color: AppColors.whiteColor, @@ -257,6 +216,57 @@ class _MyInvoicesDetailsPageState extends State { ), ), ), + SizedBox(height: 16.h), + Row( + mainAxisSize: MainAxisSize.max, + children: [ + Expanded( + child: Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 20.h, + hasShadow: true, + ), + child: Padding( + padding: EdgeInsets.all(14.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Header row + Row( + children: [ + Expanded(flex: 3, child: LocaleKeys.name.tr().toText12(color: AppColors.textColor, fontWeight: FontWeight.w600)), + Expanded(flex: 1, child: LocaleKeys.quantity.tr().toText12(color: AppColors.textColor, fontWeight: FontWeight.w600, isCenter: true)), + Expanded( + flex: 2, child: LocaleKeys.price.tr().toText12(color: AppColors.textColor, fontWeight: FontWeight.w600, isCenter: true)), + Expanded( + flex: 2, child: LocaleKeys.total.tr().toText12(color: AppColors.textColor, fontWeight: FontWeight.w600, isCenter: true)), + ], + ), + SizedBox(height: 16.h), + 2.divider, + SizedBox(height: 12.h), + // Data rows + ...widget.getInvoiceDetailsResponseModel.listConsultation!.map( + (consultation) => Padding( + padding: EdgeInsets.symmetric(vertical: 6.h), + child: Row( + children: [ + Expanded(flex: 3, child: (consultation.procedureName ?? '-').toText12(fontWeight: FontWeight.w500)), + Expanded(flex: 1, child: '${consultation.quantity ?? '-'}'.toText12(fontWeight: FontWeight.w500, isCenter: true)), + Expanded(flex: 2, child: '${consultation.price ?? '-'}'.toText12(fontWeight: FontWeight.w500, isCenter: true)), + Expanded(flex: 2, child: '${consultation.total ?? '-'}'.toText12(fontWeight: FontWeight.w500, isCenter: true)), + ], + ), + ), + ), + ], + ), + ), + ), + ), + ], + ), ], ), ), diff --git a/lib/presentation/profile_settings/profile_settings.dart b/lib/presentation/profile_settings/profile_settings.dart index 1a10e0de..eb6b4800 100644 --- a/lib/presentation/profile_settings/profile_settings.dart +++ b/lib/presentation/profile_settings/profile_settings.dart @@ -28,6 +28,7 @@ import 'package:hmg_patient_app_new/presentation/habib_wallet/habib_wallet_page. import 'package:hmg_patient_app_new/presentation/habib_wallet/recharge_wallet_page.dart'; import 'package:hmg_patient_app_new/presentation/insurance/widgets/insurance_update_details_card.dart'; import 'package:hmg_patient_app_new/presentation/profile_settings/widgets/update_email_widget.dart'; +import 'package:hmg_patient_app_new/presentation/profile_settings/widgets/update_emergency_contact_widget.dart'; import 'package:hmg_patient_app_new/services/dialog_service.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/app_language_change.dart'; @@ -242,49 +243,47 @@ class ProfileSettingsState extends State { ], ), ), - // Container( - // margin: EdgeInsets.only(left: 24.w, right: 24.w, top: 16.h, bottom: 24.h), - // padding: EdgeInsets.only(top: 4.h, bottom: 4.h), - // decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true), - // child: Column( - // children: [ - // actionItem(AppAssets.language_change, LocaleKeys.language.tr(context: context), () { - // showCommonBottomSheetWithoutHeight(context, title: LocaleKeys.language.tr(context: context), child: AppLanguageChange(), callBackFunc: () {}, isFullScreen: false); - // }, trailingLabel: Utils.appState.isArabic() ? "العربية" : "English"), - // 1.divider, - // actionItem(AppAssets.bell, LocaleKeys.notificationsSettings.tr(context: context), () { - // openAppSettings(); - // }), - // // 1.divider, - // // actionItem(AppAssets.touch_face_id, LocaleKeys.touchIDFaceIDServices.tr(context: context), () {}, switchValue: true), - // ], - // ), - // ), - // LocaleKeys.personalInformation.tr(context: context).toText18(weight: FontWeight.w600, textOverflow: TextOverflow.ellipsis, maxlines: 1).paddingOnly(left: 24.w, right: 24.w), - // Container( - // margin: EdgeInsets.only(left: 24.w, right: 24.w, top: 16.h, bottom: 24.h), - // padding: EdgeInsets.only(top: 4.h, bottom: 4.h), - // decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true), - // child: Column( - // children: [ - // actionItem(AppAssets.email_transparent, LocaleKeys.updateEmailAddress.tr(context: context), () { - // showCommonBottomSheetWithoutHeight( - // context, - // title: LocaleKeys.updateEmailAddress.tr(context: context), - // child: UpdateEmailDialog(), - // callBackFunc: () {}, - // isFullScreen: false, - // ); - // }), - // // 1.divider, - // // actionItem(AppAssets.smart_phone_fill, "Phone Number".needTranslation, () {}), - // // 1.divider, - // // actionItem(AppAssets.my_address, "My Addresses".needTranslation, () {}), - // // 1.divider, - // // actionItem(AppAssets.emergency, "Emergency Contact".needTranslation, () {}), - // ], - // ), - // ), + LocaleKeys.personalInformation.tr(context: context).toText18(weight: FontWeight.w600, textOverflow: TextOverflow.ellipsis, maxlines: 1).paddingOnly(left: 24.w, right: 24.w), + Container( + margin: EdgeInsets.only(left: 24.w, right: 24.w, top: 16.h, bottom: 24.h), + padding: EdgeInsets.only(top: 4.h, bottom: 4.h), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true), + child: Column( + children: [ + actionItem(AppAssets.email_transparent, LocaleKeys.updateEmailAddress.tr(context: context), () { + showCommonBottomSheetWithoutHeight( + context, + title: LocaleKeys.updateEmailAddress.tr(context: context), + child: UpdateEmailDialog(), + callBackFunc: () {}, + isFullScreen: false, + ); + }), + 1.divider, + actionItem(AppAssets.language, LocaleKeys.preferredLanguage.tr(context: context), () { + profileVm.openPreferredLanguageBottomSheet(); + }, + trailingLabel: profileVm.isPatientProfileLoading + ? "English" + : (profileVm.getPatientInfoForUpdate.preferredLanguage! == "1" ? LocaleKeys.arabic.tr(context: context) : LocaleKeys.english.tr(context: context)), + isShowLoading: profileVm.isPatientProfileLoading), + 1.divider, + actionItem(AppAssets.smart_phone_fill, LocaleKeys.emrgNo.tr(context: context), () { + showCommonBottomSheetWithoutHeight( + context, + title: LocaleKeys.emrgNo.tr(context: context), + child: UpdateEmergencyContactDialog(), + callBackFunc: () {}, + isFullScreen: false, + ); + }), + // 1.divider, + // actionItem(AppAssets.my_address, "My Addresses".needTranslation, () {}), + // 1.divider, + // actionItem(AppAssets.emergency, "Emergency Contact".needTranslation, () {}), + ], + ), + ), LocaleKeys.helpAndSupport.tr(context: context).toText18(weight: FontWeight.w600, textOverflow: TextOverflow.ellipsis, maxlines: 1).paddingOnly(left: 24.w, right: 24.w), Container( margin: EdgeInsets.only(left: 24.w, right: 24.w, top: 16.h), @@ -382,7 +381,8 @@ class ProfileSettingsState extends State { return _permissionsLabel; } - Widget actionItem(String icon, String label, VoidCallback onPress, {String trailingLabel = "", bool? switchValue, ValueChanged? onSwitchChanged, bool isExternalLink = false}) { + Widget actionItem(String icon, String label, VoidCallback onPress, + {String trailingLabel = "", bool? switchValue, ValueChanged? onSwitchChanged, bool isExternalLink = false, bool isShowLoading = false}) { return SizedBox( height: 56.h, child: Row( @@ -390,7 +390,8 @@ class ProfileSettingsState extends State { children: [ Utils.buildSvgWithAssets(icon: icon, iconColor: AppColors.greyTextColor), label.toText14(weight: FontWeight.w500, textOverflow: TextOverflow.ellipsis, maxlines: 1).expanded, - if (trailingLabel.isNotEmpty) trailingLabel.toText14(color: AppColors.greyTextColor, weight: FontWeight.w500, textOverflow: TextOverflow.ellipsis, maxlines: 1), + if (trailingLabel.isNotEmpty) + trailingLabel.toText14(color: AppColors.greyTextColor, weight: FontWeight.w500, textOverflow: TextOverflow.ellipsis, maxlines: 1).toShimmer2(isShow: isShowLoading), switchValue != null ? Switch( value: switchValue, diff --git a/lib/presentation/profile_settings/widgets/preferred_language_widget.dart b/lib/presentation/profile_settings/widgets/preferred_language_widget.dart index e69de29b..789bb284 100644 --- a/lib/presentation/profile_settings/widgets/preferred_language_widget.dart +++ b/lib/presentation/profile_settings/widgets/preferred_language_widget.dart @@ -0,0 +1,116 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; +import 'package:hmg_patient_app_new/core/utils/utils.dart'; +import 'package:hmg_patient_app_new/extensions/int_extensions.dart'; +import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; +import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; +import 'package:hmg_patient_app_new/features/profile_settings/profile_settings_view_model.dart'; +import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/theme/colors.dart'; +import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; +import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; +import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; +import 'package:provider/provider.dart'; + +class PreferredLanguageWidget extends StatefulWidget { + PreferredLanguageWidget({super.key}); + + @override + State createState() => _PreferredLanguageWidgetState(); +} + +class _PreferredLanguageWidgetState extends State { + String? selectedValue; + late ProfileSettingsViewModel profileSettingsViewModel; + + @override + void initState() { + super.initState(); + WidgetsBinding.instance.addPostFrameCallback((_) { + setState(() { + selectedValue = profileSettingsViewModel.getPatientInfoForUpdate.preferredLanguage!; + }); + }); + } + + @override + Widget build(BuildContext context) { + profileSettingsViewModel = Provider.of(context, listen: false); + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 24.h, + children: [ + LocaleKeys.languageSetting.tr(context: context).toText14(), + Container( + padding: EdgeInsets.only(top: 4, bottom: 4), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true), + child: Column( + children: [ + languageItem("English", "2"), + 1.divider, + languageItem("العربية", "1"), + ], + ), + ), + CustomButton( + text: LocaleKeys.save.tr(context: context), + onPressed: () { + LoaderBottomSheet.showLoader(loadingText: LocaleKeys.loadingText.tr(context: context)); + profileSettingsViewModel!.updatePatientInfo( + patientInfo: { + "PreferredLanguage": selectedValue, + "EmailAddress": profileSettingsViewModel.getPatientInfoForUpdate.emailAddress, + "EmergencyContactName": profileSettingsViewModel.getPatientInfoForUpdate.emergencyContactName, + "EmergencyContactNo": profileSettingsViewModel.getPatientInfoForUpdate.emergencyContactNo, + "IsEmailAlertRequired": true, + "IsSMSAlertRequired": true, + }, + onSuccess: (response) { + LoaderBottomSheet.hideLoader(); + showCommonBottomSheetWithoutHeight(context, title: LocaleKeys.success.tr(context: context), child: Utils.getSuccessWidget(loadingText: LocaleKeys.success.tr()), + callBackFunc: () async { + Navigator.of(context).pop(); + profileSettingsViewModel.getProfileSettings(); + }, isFullScreen: false); + }, + onError: (error) { + LoaderBottomSheet.hideLoader(); + // Show error message + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text(error)), + ); + }, + ); + }), + ], + ); + } + + Widget languageItem(String title, String _value) { + return SizedBox( + height: 72, + child: Row( + spacing: 8.h, + children: [ + Radio( + value: _value, + groupValue: selectedValue, + activeColor: AppColors.errorColor, + onChanged: (value) { + setState(() { + selectedValue = _value; + }); + }, + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + ), + title.toText16(weight: FontWeight.w500, textOverflow: TextOverflow.ellipsis, maxlines: 1, fontFamily: _value == "1" ? 'GESSTwo' : 'Poppins').expanded, + ], + ).paddingOnly(left: 16, right: 16).onPress(() { + setState(() { + selectedValue = _value; + }); + }), + ); + } +} diff --git a/lib/presentation/profile_settings/widgets/update_email_widget.dart b/lib/presentation/profile_settings/widgets/update_email_widget.dart index ad9b9d5a..cb844bcb 100644 --- a/lib/presentation/profile_settings/widgets/update_email_widget.dart +++ b/lib/presentation/profile_settings/widgets/update_email_widget.dart @@ -31,7 +31,11 @@ class _UpdateEmailDialogState extends State { void initState() { _textFieldFocusNode = FocusNode(); textController = TextEditingController(); - textController!.text = getIt.get().getAuthenticatedUser()!.emailAddress ?? ""; + WidgetsBinding.instance.addPostFrameCallback((_) { + setState(() { + textController!.text = profileSettingsViewModel!.getPatientInfoForUpdate.emailAddress ?? ""; + }); + }); super.initState(); } @@ -52,7 +56,7 @@ class _UpdateEmailDialogState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - "Enter the new email address to be updated in your HMG File: ".toText16(textAlign: TextAlign.start, weight: FontWeight.w500), + "Enter the new email address to be updated: ".toText16(textAlign: TextAlign.start, weight: FontWeight.w500), SizedBox(height: 12.h), TextInputWidget( labelText: LocaleKeys.email.tr(), @@ -78,12 +82,20 @@ class _UpdateEmailDialogState extends State { onPressed: () { LoaderBottomSheet.showLoader(loadingText: LocaleKeys.updatingEmailAddress.tr(context: context)); profileSettingsViewModel!.updatePatientInfo( - patientInfo: {"EmailAddress": textController!.text}, + patientInfo: { + "PreferredLanguage": profileSettingsViewModel!.getPatientInfoForUpdate.preferredLanguage, + "EmailAddress": textController!.text, + "EmergencyContactName": profileSettingsViewModel!.getPatientInfoForUpdate.emergencyContactName, + "EmergencyContactNo": profileSettingsViewModel!.getPatientInfoForUpdate.emergencyContactNo, + "IsEmailAlertRequired": true, + "IsSMSAlertRequired": true, + }, onSuccess: (response) { LoaderBottomSheet.hideLoader(); showCommonBottomSheetWithoutHeight(context, title: LocaleKeys.success.tr(context: context), child: Utils.getSuccessWidget(loadingText: LocaleKeys.success.tr()), callBackFunc: () async { Navigator.of(context).pop(); + profileSettingsViewModel!.getProfileSettings(); }, isFullScreen: false); }, onError: (error) { diff --git a/lib/presentation/profile_settings/widgets/update_emergency_contact_widget.dart b/lib/presentation/profile_settings/widgets/update_emergency_contact_widget.dart index e69de29b..f725bba1 100644 --- a/lib/presentation/profile_settings/widgets/update_emergency_contact_widget.dart +++ b/lib/presentation/profile_settings/widgets/update_emergency_contact_widget.dart @@ -0,0 +1,118 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/core/app_assets.dart'; +import 'package:hmg_patient_app_new/core/app_state.dart'; +import 'package:hmg_patient_app_new/core/dependencies.dart'; +import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; +import 'package:hmg_patient_app_new/core/utils/utils.dart'; +import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; +import 'package:hmg_patient_app_new/features/profile_settings/profile_settings_view_model.dart'; +import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/theme/colors.dart'; +import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; +import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; +import 'package:hmg_patient_app_new/widgets/input_widget.dart'; +import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; +import 'package:provider/provider.dart'; + +class UpdateEmergencyContactDialog extends StatefulWidget { + UpdateEmergencyContactDialog({super.key}); + + @override + State createState() => _UpdateEmergencyContactDialogState(); +} + +class _UpdateEmergencyContactDialogState extends State { + late FocusNode _textFieldFocusNode; + late TextEditingController? textController; + ProfileSettingsViewModel? profileSettingsViewModel; + + @override + void initState() { + _textFieldFocusNode = FocusNode(); + textController = TextEditingController(); + WidgetsBinding.instance.addPostFrameCallback((_) { + setState(() { + textController!.text = profileSettingsViewModel!.getPatientInfoForUpdate.emergencyContactNo!; + }); + }); + super.initState(); + } + + @override + void dispose() { + _textFieldFocusNode.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + profileSettingsViewModel = Provider.of(context); + return GestureDetector( + onTap: () { + _textFieldFocusNode.unfocus(); + FocusScope.of(context).unfocus(); + }, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "Enter the new emergency contact number to be updated: ".toText16(textAlign: TextAlign.start, weight: FontWeight.w500), + SizedBox(height: 12.h), + TextInputWidget( + labelText: LocaleKeys.emrgNo.tr(), + hintText: "05xxxxxxxx", + controller: textController, + focusNode: _textFieldFocusNode, + autoFocus: true, + padding: EdgeInsets.all(8.h), + keyboardType: TextInputType.number, + isEnable: true, + isReadOnly: false, + prefix: null, + isBorderAllowed: false, + isAllowLeadingIcon: true, + fontSize: 14.f, + isCountryDropDown: false, + leadingIcon: AppAssets.call_fill, + fontFamily: "Poppins", + ), + SizedBox(height: 12.h), + CustomButton( + text: LocaleKeys.submit.tr(context: context), + onPressed: () { + LoaderBottomSheet.showLoader(loadingText: LocaleKeys.loadingText.tr(context: context)); + profileSettingsViewModel!.updatePatientInfo( + patientInfo: { + "PreferredLanguage": profileSettingsViewModel!.getPatientInfoForUpdate.preferredLanguage, + "EmailAddress": profileSettingsViewModel!.getPatientInfoForUpdate.emailAddress, + "EmergencyContactName": profileSettingsViewModel!.getPatientInfoForUpdate.emergencyContactName, + "EmergencyContactNo": textController!.text, + "IsEmailAlertRequired": true, + "IsSMSAlertRequired": true, + }, + onSuccess: (response) { + LoaderBottomSheet.hideLoader(); + showCommonBottomSheetWithoutHeight(context, title: LocaleKeys.success.tr(context: context), child: Utils.getSuccessWidget(loadingText: LocaleKeys.success.tr()), + callBackFunc: () async { + Navigator.of(context).pop(); + profileSettingsViewModel!.getProfileSettings(); + }, isFullScreen: false); + }, + onError: (error) { + LoaderBottomSheet.hideLoader(); + // Show error message + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text(error)), + ); + }, + ); + }, + backgroundColor: AppColors.primaryRedColor, + borderColor: AppColors.primaryRedColor, + textColor: const Color(0xFFffffff), + ), + ], + ), + ); + } +}