diff --git a/assets/images/svg/patient_qr_code_icon.svg b/assets/images/svg/patient_qr_code_icon.svg
new file mode 100644
index 00000000..c76f0326
--- /dev/null
+++ b/assets/images/svg/patient_qr_code_icon.svg
@@ -0,0 +1,12 @@
+
diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json
index d0321ace..b2bc5c2d 100644
--- a/assets/langs/ar-SA.json
+++ b/assets/langs/ar-SA.json
@@ -1959,12 +1959,14 @@
"refund": "استرداد",
"parkingQR": "رمز الاستجابة السريعة لوقوف السيارات",
"parkingQRDesc": "امسح رمز الاستجابة السريعة (QR Code) أدناه عند بوابة الخروج من موقف السيارات:",
- "livecareUpdateInsuranceSent": "تم استلام طلب تحديث بيانات التأمين الخاص بك، ويجري العمل عليه حالياً. سنقوم بإشعارك فور اكتمال التحديث.",
- "livecareUpdateInsurance": "سيتم تحويل طلب تحديث بيانات التأمين إلى فريق LiveCare المختص لاستكمال الإجراءات. هل تود المتابعة؟",
- "schedule": "جدول",
- "doctorSchedule": "جدول الطبيب",
- "weeklyShift": "الفترات الأسبوعية",
- "dayOff": "إجازة",
- "notAvailable": "غير متاح",
- "hide": "إخفاء"
+ "livecareUpdateInsuranceSent": "تم استلام طلب تحديث بيانات التأمين الخاص بك، ويجري العمل عليه حالياً. سنقوم بإشعارك فور اكتمال التحديث.",
+ "livecareUpdateInsurance": "سيتم تحويل طلب تحديث بيانات التأمين إلى فريق LiveCare المختص لاستكمال الإجراءات. هل تود المتابعة؟",
+ "schedule": "جدول",
+ "doctorSchedule": "جدول الطبيب",
+ "weeklyShift": "الفترات الأسبوعية",
+ "dayOff": "إجازة",
+ "notAvailable": "غير متاح",
+ "hide": "إخفاء",
+ "viewPatientQR": "عرض رمز الاستجابة السريعة للمريض",
+ "patientQR": "رمز الاستجابة السريعة للمريض"
}
diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json
index ae344b01..0e3429e4 100644
--- a/assets/langs/en-US.json
+++ b/assets/langs/en-US.json
@@ -1949,14 +1949,16 @@
"invoiceHistory": "Invoice History",
"parkingQR": "Parking QR Code",
"parkingQRDesc": "Scan the below QR Code at the exit parking gate:",
- "livecareUpdateInsuranceSent": "Your insurance update request is being processed. You will be notified once the update is completed.",
- "livecareUpdateInsurance": "Please note that your insurance update request will be sent to the our LiveCare team for update. Would you like to proceed?",
- "schedule": "Schedule",
- "doctorSchedule": "Doctor Schedule",
- "weeklyShift": "Weekly Shift",
- "dayOff": "Off",
- "notAvailable": "Not Available",
- "hide": "Hide"
+ "livecareUpdateInsuranceSent": "Your insurance update request is being processed. You will be notified once the update is completed.",
+ "livecareUpdateInsurance": "Please note that your insurance update request will be sent to the our LiveCare team for update. Would you like to proceed?",
+ "schedule": "Schedule",
+ "doctorSchedule": "Doctor Schedule",
+ "weeklyShift": "Weekly Shift",
+ "dayOff": "Off",
+ "notAvailable": "Not Available",
+ "hide": "Hide",
+ "viewPatientQR": "View Patient QR Code",
+ "patientQR": "Patient QR Code"
}
diff --git a/lib/core/app_assets.dart b/lib/core/app_assets.dart
index aba22eb3..b4611890 100644
--- a/lib/core/app_assets.dart
+++ b/lib/core/app_assets.dart
@@ -399,6 +399,7 @@ class AppAssets {
static const String habibLogoOnly = '$svgBasePath/habib logo_only.svg';
static const String descriptionIcon = '$svgBasePath/description_icon.svg';
static const String selectImageIcon = '$svgBasePath/select_image_icon.svg';
+ static const String patientQRCodeIcon = '$svgBasePath/patient_qr_code_icon.svg';
// PNGS //
static const String hmgLogo = '$pngBasePath/hmg_logo.png';
diff --git a/lib/features/insurance/insurance_view_model.dart b/lib/features/insurance/insurance_view_model.dart
index 621ebe4c..2422920a 100644
--- a/lib/features/insurance/insurance_view_model.dart
+++ b/lib/features/insurance/insurance_view_model.dart
@@ -33,14 +33,10 @@ class InsuranceViewModel extends ChangeNotifier {
InsuranceViewModel({required this.insuranceRepo, required this.errorHandlerService});
initInsuranceProvider() {
- debugPrint("InsuranceViewModel: initInsuranceProvider called, isInsuranceDataToBeLoaded=$isInsuranceDataToBeLoaded");
if (isInsuranceDataToBeLoaded) {
patientInsuranceList.clear();
isInsuranceLoading = true;
- debugPrint("InsuranceViewModel: Calling getPatientInsuranceDetails API");
getPatientInsuranceDetails();
- } else {
- debugPrint("InsuranceViewModel: Skipping API call, isInsuranceDataToBeLoaded is false");
}
patientInsuranceCardHistoryList.clear();
isInsuranceHistoryLoading = true;
@@ -82,17 +78,14 @@ class InsuranceViewModel extends ChangeNotifier {
Future getPatientInsuranceDetails({Function(dynamic)? onSuccess, Function(String)? onError}) async {
if (!isInsuranceDataToBeLoaded) {
- debugPrint("InsuranceViewModel: getPatientInsuranceDetails - skipping, flag is false");
return;
}
- debugPrint("InsuranceViewModel: getPatientInsuranceDetails - making API call");
final result = await insuranceRepo.getPatientInsuranceDetails();
result.fold(
// (failure) async => await errorHandlerService.handleError(failure: failure),
(failure) async {
- debugPrint("InsuranceViewModel: API call failed - ${failure.toString()}");
isInsuranceLoading = false;
isInsuranceDataToBeLoaded = true;
isInsuranceExpired = false;
@@ -102,11 +95,9 @@ class InsuranceViewModel extends ChangeNotifier {
},
(apiResponse) {
if (apiResponse.messageStatus == 2) {
- debugPrint("InsuranceViewModel: API returned error status");
isInsuranceDataToBeLoaded = false;
// dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
} else if (apiResponse.messageStatus == 1) {
- debugPrint("InsuranceViewModel: API success - received ${apiResponse.data?.length ?? 0} insurance records");
patientInsuranceList = apiResponse.data!;
isInsuranceLoading = false;
isInsuranceDataToBeLoaded = false;
@@ -115,7 +106,6 @@ class InsuranceViewModel extends ChangeNotifier {
isInsuranceExpired = DateTime.now().isAfter(
DateUtil.convertStringToDate(patientInsuranceList.first.cardValidTo),
);
- debugPrint("InsuranceViewModel: Insurance card expired: $isInsuranceExpired");
}
isInsuranceExpiryBannerShown = isInsuranceExpired;
diff --git a/lib/features/my_appointments/my_appointments_repo.dart b/lib/features/my_appointments/my_appointments_repo.dart
index 87484e06..d7a926d3 100644
--- a/lib/features/my_appointments/my_appointments_repo.dart
+++ b/lib/features/my_appointments/my_appointments_repo.dart
@@ -172,9 +172,9 @@ class MyAppointmentsRepoImp implements MyAppointmentsRepo {
try {
final list = response['OnlineCheckInAppointments'];
patientShareObj = (list == null || list.isEmpty) ? PatientAppointmentShareResponseModel() : PatientAppointmentShareResponseModel.fromJson(list[0]);
- patientShareObj.isCash = response["IsCash"];
- patientShareObj.isEligible = response["IsEligible"];
- patientShareObj.isInsured = response["IsInsured"];
+ patientShareObj.isCash = isLiveCareAppointment ? list[0]["IsCash"] : response["IsCash"];
+ patientShareObj.isEligible = isLiveCareAppointment ? list[0]["IsEligible"] : response["IsEligible"];
+ patientShareObj.isInsured = isLiveCareAppointment ? list[0]["IsInsured"] : response["IsInsured"];
// if (list == null || list.isEmpty) {
// throw Exception("patient share list is empty");
diff --git a/lib/features/my_appointments/my_appointments_view_model.dart b/lib/features/my_appointments/my_appointments_view_model.dart
index b480a354..52d8b240 100644
--- a/lib/features/my_appointments/my_appointments_view_model.dart
+++ b/lib/features/my_appointments/my_appointments_view_model.dart
@@ -277,7 +277,6 @@ class MyAppointmentsViewModel extends ChangeNotifier {
}
if (!isAppointmentDataToBeLoaded) return;
- debugPrint('getPatientAppointments CALLED!!!');
patientAppointmentsByClinic.clear();
patientAppointmentsByHospital.clear();
@@ -347,9 +346,6 @@ class MyAppointmentsViewModel extends ChangeNotifier {
}
// }
- debugPrint('Upcoming Appointments: ${patientUpcomingAppointmentsHistoryList.length}');
- debugPrint('Arrived Appointments: ${patientArrivedAppointmentsHistoryList.length}');
- debugPrint('All Appointments: ${patientAppointmentsHistoryList.length}');
getFiltersForSelectedAppointmentList(filteredAppointmentList);
notifyListeners();
}
@@ -1299,7 +1295,6 @@ class MyAppointmentsViewModel extends ChangeNotifier {
);
} catch (e) {
// Ignore errors if reminder doesn't exist
- debugPrint("No existing ${type.displayName} to remove");
}
}
}
diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart
index 80cea8b4..51a687a8 100644
--- a/lib/generated/locale_keys.g.dart
+++ b/lib/generated/locale_keys.g.dart
@@ -1948,5 +1948,7 @@ abstract class LocaleKeys {
static const weeklyShift = 'weeklyShift';
static const dayOff = 'dayOff';
static const hide = 'hide';
+ static const viewPatientQR = 'viewPatientQR';
+ static const patientQR = 'patientQR';
}
diff --git a/lib/presentation/book_appointment/book_appointment_page.dart b/lib/presentation/book_appointment/book_appointment_page.dart
index 55769fbe..9b210eee 100644
--- a/lib/presentation/book_appointment/book_appointment_page.dart
+++ b/lib/presentation/book_appointment/book_appointment_page.dart
@@ -67,7 +67,7 @@ class _BookAppointmentPageState extends State {
immediateLiveCareViewModel.initImmediateLiveCare();
if (appState.isAuthenticated) {
getIt.get().getPatientMyDoctors(isTop8: true);
- getIt.get().getPatientFavouriteDoctors();
+ // getIt.get().getPatientFavouriteDoctors();
}
});
WidgetsBinding.instance.addPostFrameCallback((_) {
diff --git a/lib/presentation/insurance/insurance_approval_details_page.dart b/lib/presentation/insurance/insurance_approval_details_page.dart
index b1fce84a..d0d7f681 100644
--- a/lib/presentation/insurance/insurance_approval_details_page.dart
+++ b/lib/presentation/insurance/insurance_approval_details_page.dart
@@ -102,7 +102,7 @@ class InsuranceApprovalDetailsPage extends StatelessWidget {
spacing: 3.h,
runSpacing: 4.h,
children: [
- AppCustomChipWidget(labelText: insuranceApprovalResponseModel.clinicName!),
+ AppCustomChipWidget(labelText: insuranceApprovalResponseModel.clinicName ?? ""),
AppCustomChipWidget(labelText: "${LocaleKeys.approvalNo.tr(context: context)} ${insuranceApprovalResponseModel.approvalNo}", isEnglishOnly: true),
AppCustomChipWidget(labelText: "${LocaleKeys.unusedCount.tr(context: context)} ${insuranceApprovalResponseModel.unUsedCount}", isEnglishOnly: true),
AppCustomChipWidget(labelText: "${LocaleKeys.companyName.tr(context: context)} ${insuranceApprovalResponseModel.companyName}"),
diff --git a/lib/presentation/medical_file/medical_file_page.dart b/lib/presentation/medical_file/medical_file_page.dart
index b382bf01..cdee10db 100644
--- a/lib/presentation/medical_file/medical_file_page.dart
+++ b/lib/presentation/medical_file/medical_file_page.dart
@@ -110,16 +110,19 @@ class _MedicalFilePageState extends State {
appState = getIt.get();
scheduleMicrotask(() {
if (appState.isAuthenticated) {
- myAppointmentsViewModel.getPatientMyDoctors(isTop8: true);
- prescriptionsViewModel.initPrescriptionsViewModel();
insuranceViewModel.initInsuranceProvider();
- medicalFileViewModel.setIsPatientSickLeaveListLoading(true);
- medicalFileViewModel.getPatientSickLeaveList();
- medicalFileViewModel.onTabChanged(0);
- medicalFileViewModel.setIsPatientMedicalReportsLoading(true);
- medicalFileViewModel.getPatientMedicalReportList();
// Load vital signs
hmgServicesViewModel.getPatientVitalSign();
+
+ // myAppointmentsViewModel.getPatientMyDoctors(isTop8: true);
+ // prescriptionsViewModel.initPrescriptionsViewModel();
+
+ // medicalFileViewModel.setIsPatientSickLeaveListLoading(true);
+ // medicalFileViewModel.getPatientSickLeaveList();
+ // medicalFileViewModel.setIsPatientMedicalReportsLoading(true);
+ // medicalFileViewModel.getPatientMedicalReportList();
+
+ medicalFileViewModel.onTabChanged(0);
}
});
super.initState();
@@ -236,8 +239,8 @@ class _MedicalFilePageState extends State {
children: [
SizedBox(
width: MediaQuery.of(context).size.width * 0.6,
- child: "${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}"
- .toText18(isBold: true, textOverflow: TextOverflow.ellipsis, maxlines: 2),
+ child:
+ "${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}".toText18(isBold: true, textOverflow: TextOverflow.ellipsis, maxlines: 2),
),
SizedBox(height: 4.h),
Wrap(
@@ -481,6 +484,20 @@ class _MedicalFilePageState extends State {
expansionMode: ExpansionMode.exactlyOne,
dividerColor: AppColors.dividerColor,
itemPadding: EdgeInsets.symmetric(vertical: 16.h, horizontal: 14.h),
+ onItemToggled: (index, isExpanded) {
+ debugPrint("Item at index $index is now ${isExpanded ? 'expanded' : 'collapsed'}");
+
+ if (index == 0 && isExpanded) {
+ myAppointmentsViewModel.getPatientMyDoctors(isTop8: true);
+ prescriptionsViewModel.initPrescriptionsViewModel();
+ }
+ if (index == 1 && isExpanded) {
+ medicalFileViewModel.setIsPatientSickLeaveListLoading(true);
+ medicalFileViewModel.getPatientSickLeaveList();
+ medicalFileViewModel.setIsPatientMedicalReportsLoading(true);
+ medicalFileViewModel.getPatientMedicalReportList();
+ }
+ },
items: [
ExpandableListItem(
title: LocaleKeys.medicalServices.tr(context: context).toText18(isBold: true),
diff --git a/lib/presentation/profile_settings/profile_settings.dart b/lib/presentation/profile_settings/profile_settings.dart
index 2e6b60b6..2e9bb3b7 100644
--- a/lib/presentation/profile_settings/profile_settings.dart
+++ b/lib/presentation/profile_settings/profile_settings.dart
@@ -42,6 +42,8 @@ import 'package:in_app_review/in_app_review.dart';
import 'dart:ui' as ui;
+import 'widgets/patient_qr_code_widget.dart';
+
class ProfileSettings extends StatefulWidget {
const ProfileSettings({super.key});
@@ -232,6 +234,17 @@ class ProfileSettingsState extends State {
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: false),
child: Column(
children: [
+ actionItem(AppAssets.patientQRCodeIcon, LocaleKeys.viewPatientQR.tr(context: context), () {
+ showCommonBottomSheetWithoutHeight(
+ title: LocaleKeys.patientQR.tr(context: context),
+ context,
+ child: PatientQrCodeWidget(),
+ callBackFunc: () {},
+ isFullScreen: false,
+ isCloseButtonVisible: true,
+ );
+ }),
+ 1.divider,
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"),
diff --git a/lib/presentation/profile_settings/widgets/patient_qr_code_widget.dart b/lib/presentation/profile_settings/widgets/patient_qr_code_widget.dart
new file mode 100644
index 00000000..adc1632e
--- /dev/null
+++ b/lib/presentation/profile_settings/widgets/patient_qr_code_widget.dart
@@ -0,0 +1,56 @@
+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/extensions/string_extensions.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/chip/app_custom_chip_widget.dart';
+
+import '../../../generated/locale_keys.g.dart';
+
+class PatientQrCodeWidget extends StatelessWidget {
+ PatientQrCodeWidget({super.key});
+
+ late AppState appState;
+
+ @override
+ Widget build(BuildContext context) {
+ appState = getIt.get();
+ return Column(
+ children: [
+ SizedBox(height: 8.h),
+ "${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}".toText18(isBold: true, textOverflow: TextOverflow.ellipsis, maxlines: 2),
+ SizedBox(height: 8.h),
+ Wrap(
+ direction: Axis.horizontal,
+ spacing: 4.w,
+ runSpacing: 6.w,
+ children: [
+ AppCustomChipWidget(
+ icon: AppAssets.file_icon,
+ labelText: "${LocaleKeys.fileno.tr(context: context)}: ${appState.getAuthenticatedUser()!.patientId}",
+ labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: 6.w),
+ ),
+ AppCustomChipWidget(
+ icon: AppAssets.checkmark_icon,
+ labelText: LocaleKeys.verified.tr(context: context),
+ iconColor: AppColors.successColor,
+ labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: 6.w),
+ ),
+ ],
+ ),
+ SizedBox(height: 16.h),
+ Image.network(
+ "https://api.qrserver.com/v1/create-qr-code/?size=250x250&data=${appState.getAuthenticatedUser()!.patientId.toString()}",
+ fit: BoxFit.fill,
+ height: 156.h,
+ width: 156.h,
+ ),
+ SizedBox(height: 16.h),
+ ],
+ );
+ }
+}