diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index ffa3a908..cd5030d2 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -92,7 +92,7 @@
-
+
diff --git a/lib/features/my_appointments/my_appointments_repo.dart b/lib/features/my_appointments/my_appointments_repo.dart
index 0f33138a..4c7c41e2 100644
--- a/lib/features/my_appointments/my_appointments_repo.dart
+++ b/lib/features/my_appointments/my_appointments_repo.dart
@@ -566,6 +566,8 @@ class MyAppointmentsRepoImp implements MyAppointmentsRepo {
final appointmentsList = (list as List).map((item) => GetFavoriteDoctorsListModel.fromJson(item as Map)).toList().cast();
+ appointmentsList.removeWhere((element) => element.isActive == false);
+
apiResponse = GenericApiModel>(
messageStatus: messageStatus,
statusCode: statusCode,
diff --git a/lib/features/notifications/notifications_view_model.dart b/lib/features/notifications/notifications_view_model.dart
index ea552292..85049ec9 100644
--- a/lib/features/notifications/notifications_view_model.dart
+++ b/lib/features/notifications/notifications_view_model.dart
@@ -15,7 +15,7 @@ class NotificationsViewModel extends ChangeNotifier {
List notificationsList = [];
int currentPage = 0;
- int pagingSize = 15;
+ int pagingSize = 50;
int notificationStatusID = 2; // Default to status 2 (e.g., unread)
NotificationsViewModel({
diff --git a/lib/presentation/appointments/appointment_payment_page.dart b/lib/presentation/appointments/appointment_payment_page.dart
index d762f795..e755cfeb 100644
--- a/lib/presentation/appointments/appointment_payment_page.dart
+++ b/lib/presentation/appointments/appointment_payment_page.dart
@@ -258,7 +258,8 @@ class _AppointmentPaymentPageState extends State {
CustomPageRoute(
page: InsuranceHomePage(),
),
- );
+ )
+ .then((val) {});
},
backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.secondaryLightRedBorderColor,
diff --git a/lib/presentation/book_appointment/laser/widgets/body_part_listing.dart b/lib/presentation/book_appointment/laser/widgets/body_part_listing.dart
index fb641327..c01899cb 100644
--- a/lib/presentation/book_appointment/laser/widgets/body_part_listing.dart
+++ b/lib/presentation/book_appointment/laser/widgets/body_part_listing.dart
@@ -1,5 +1,6 @@
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_export.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
@@ -8,7 +9,9 @@ import 'package:hmg_patient_app_new/features/book_appointments/models/laser_body
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/laser_body_parts.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/chip/app_custom_chip_widget.dart';
import 'package:provider/provider.dart';
+import 'package:smooth_corner/smooth_corner.dart';
class BodyPartsListing extends StatelessWidget {
final List parts;
@@ -49,11 +52,7 @@ class BodyPartsListing extends StatelessWidget {
Visibility(
visible: !isLoading,
child: GridView.builder(
- gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
- crossAxisCount: 3,
- childAspectRatio: 85 / 107,
- crossAxisSpacing: 4.h,
- mainAxisSpacing: 21.h),
+ gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 75 / 107, crossAxisSpacing: 4.h, mainAxisSpacing: 21.h),
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: parts.length,
@@ -73,7 +72,7 @@ class BodyPartsListing extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AspectRatio(
- aspectRatio: 130 / 120,
+ aspectRatio: 150 / 140,
child: FittedBox(
fit: BoxFit.fitWidth,
child: Stack(
@@ -112,14 +111,41 @@ class BodyPartsListing extends StatelessWidget {
child: Center(
child: Column(
children: [
- context.read().getLaserProcedureNameWRTLanguage(parts[index]).toText12(isBold: true, color: AppColors.textColor, isCenter: true, maxLine: 2),
- Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- "${LocaleKeys.mins.tr()}: ".toText12(isBold: true, color: AppColors.textColor, isCenter: true, maxLine: 2),
- parts[index].timeDuration!.toText12(isBold: true, color: AppColors.textColor, isCenter: true, maxLine: 2),
- ],
- ),
+ context.read().getLaserProcedureNameWRTLanguage(parts[index]).toText12(isBold: true, color: AppColors.textColor, isCenter: true, maxLine: 1),
+ SizedBox(height: 4.h),
+ AppCustomChipWidget(
+ backgroundColor: _isSelected ? AppColors.chipSecondaryLightRedColor : AppColors.whiteColor,
+ textColor: _isSelected ? AppColors.chipPrimaryRedBorderColor : AppColors.blackColor,
+ // labelText: "${parts[index].timeDuration!} ${LocaleKeys.mins.tr()}",
+ richText: "${parts[index].timeDuration!} ${LocaleKeys.mins.tr()}".toText12(
+ fontWeight: FontWeight.w500,
+ color: _isSelected ? AppColors.chipPrimaryRedBorderColor : AppColors.blackColor,
+ ),
+ icon: AppAssets.waiting_time_clock,
+ iconHasColor: true,
+ iconColor: _isSelected ? AppColors.chipPrimaryRedBorderColor : AppColors.blackColor,
+ iconSize: 16,
+ labelPadding: EdgeInsetsDirectional.only(start: 8.w, end: 8.w),
+ padding: EdgeInsets.symmetric(vertical: 8.h, horizontal: 8.w),
+ deleteIconSize: Size(18.w, 18.h),
+ shape: SmoothRectangleBorder(
+ borderRadius: BorderRadius.circular(10.r),
+ smoothness: 10,
+ side: BorderSide(color: _isSelected ? AppColors.chipPrimaryRedBorderColor : AppColors.borderGrayColor, width: 1),
+ )),
+
+ // AppCustomChipWidget(
+ // labelText: "${parts[index].timeDuration!} ${LocaleKeys.mins.tr()}",
+ // backgroundColor: AppColors.whiteColor,
+ // // textColor: Utils.getCardBorderColor(myAppointmentsVM.currentQueueStatus),
+ // ),
+ // Row(
+ // mainAxisAlignment: MainAxisAlignment.center,
+ // children: [
+ // "${LocaleKeys.mins.tr()}: ".toText12(isBold: true, color: AppColors.textColor, isCenter: true, maxLine: 2),
+ // parts[index].timeDuration!.toText12(isBold: true, color: AppColors.textColor, isCenter: true, maxLine: 2),
+ // ],
+ // ),
],
),
),
diff --git a/lib/presentation/book_appointment/livecare/immediate_livecare_payment_details.dart b/lib/presentation/book_appointment/livecare/immediate_livecare_payment_details.dart
index c885b595..673532ac 100644
--- a/lib/presentation/book_appointment/livecare/immediate_livecare_payment_details.dart
+++ b/lib/presentation/book_appointment/livecare/immediate_livecare_payment_details.dart
@@ -171,7 +171,22 @@ class ImmediateLiveCarePaymentDetails extends StatelessWidget {
CustomPageRoute(
page: InsuranceHomePage(),
),
- );
+ )
+ .then((val) async {
+ LoaderBottomSheet.showLoader(loadingText: LocaleKeys.fetchingFeesPleaseWait.tr());
+ await immediateLiveCareVM.getLiveCareImmediateAppointmentFees(onSuccess: (val) {
+ LoaderBottomSheet.hideLoader();
+ }, onError: (err) {
+ LoaderBottomSheet.hideLoader();
+ showCommonBottomSheetWithoutHeight(
+ context,
+ child: Utils.getErrorWidget(loadingText: err),
+ callBackFunc: () {},
+ isFullScreen: false,
+ isCloseButtonVisible: true,
+ );
+ });
+ });
},
backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.secondaryLightRedBorderColor,
@@ -343,15 +358,17 @@ class ImmediateLiveCarePaymentDetails extends StatelessWidget {
bool cameraGranted = statuses[Permission.camera]?.isGranted ?? false;
bool micGranted = statuses[Permission.microphone]?.isGranted ?? false;
bool notifGranted = statuses[Permission.notification]?.isGranted ?? false;
+ bool alertWindowGranted = Platform.isAndroid ? (statuses[Permission.systemAlertWindow]?.isGranted ?? false) : true;
// If all required permissions are already granted
- if (cameraGranted && micGranted && notifGranted) return true;
+ if (cameraGranted && micGranted && notifGranted && alertWindowGranted) return true;
// Collect only the missing permissions
final missing = [];
if (!cameraGranted) missing.add(Permission.camera);
if (!micGranted) missing.add(Permission.microphone);
if (!notifGranted) missing.add(Permission.notification);
+ if (Platform.isAndroid && !alertWindowGranted) missing.add(Permission.systemAlertWindow);
// If any of the missing permissions are permanently denied/restricted -> open settings (single dialog)
final permanent = missing.where((p) => (statuses[p]?.isPermanentlyDenied ?? false) || (statuses[p]?.isRestricted ?? false)).toList();
@@ -392,6 +409,7 @@ class ImmediateLiveCarePaymentDetails extends StatelessWidget {
cameraGranted = newStatuses[Permission.camera]?.isGranted ?? cameraGranted;
micGranted = newStatuses[Permission.microphone]?.isGranted ?? micGranted;
notifGranted = newStatuses[Permission.notification]?.isGranted ?? notifGranted;
+ alertWindowGranted = newStatuses[Permission.systemAlertWindow]?.isGranted ?? alertWindowGranted;
// If any requested permission is now permanently denied -> open settings
final newlyPermanent = missing.where((p) => (newStatuses[p]?.isPermanentlyDenied ?? false) || (newStatuses[p]?.isRestricted ?? false)).toList();
@@ -407,7 +425,7 @@ class ImmediateLiveCarePaymentDetails extends StatelessWidget {
return false;
}
- return cameraGranted && micGranted && notifGranted;
+ return cameraGranted && micGranted && notifGranted && alertWindowGranted;
}
// Future askVideoCallPermission() async {
diff --git a/lib/presentation/home/landing_page.dart b/lib/presentation/home/landing_page.dart
index bce87ca2..32525234 100644
--- a/lib/presentation/home/landing_page.dart
+++ b/lib/presentation/home/landing_page.dart
@@ -199,6 +199,7 @@ class _LandingPageState extends State {
Navigator.of(context).push(
CustomPageRoute(
+ direction: AxisDirection.down,
page: FamilyMedicalScreen(),
),
);
diff --git a/lib/presentation/home/widgets/welcome_widget.dart b/lib/presentation/home/widgets/welcome_widget.dart
index b05aeb99..b2d4e3a1 100644
--- a/lib/presentation/home/widgets/welcome_widget.dart
+++ b/lib/presentation/home/widgets/welcome_widget.dart
@@ -45,6 +45,7 @@ class WelcomeWidget extends StatelessWidget {
getIt.get().getProfileSettings();
Navigator.of(context).push(
CustomPageRoute(
+ direction: getIt.get().isArabic() ? AxisDirection.right : AxisDirection.left,
page: ProfileSettings(),
),
);
diff --git a/lib/presentation/insurance/widgets/insurance_update_details_card.dart b/lib/presentation/insurance/widgets/insurance_update_details_card.dart
index e7cfe059..ae1eaf51 100644
--- a/lib/presentation/insurance/widgets/insurance_update_details_card.dart
+++ b/lib/presentation/insurance/widgets/insurance_update_details_card.dart
@@ -12,6 +12,7 @@ import 'package:hmg_patient_app_new/features/insurance/insurance_view_model.dart
import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/lab/lab_result_item_view.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/buttons/custom_button.dart';
import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart';
@@ -121,17 +122,27 @@ class PatientInsuranceCardUpdateCard extends StatelessWidget {
insuranceCardImage: "",
onSuccess: (val) {
LoaderBottomSheet.hideLoader();
- showCommonBottomSheetWithoutHeight(
- title: LocaleKeys.success.tr(context: context),
- context,
- child: Utils.getSuccessWidget(loadingText: LocaleKeys.insuranceRequestSubmittedSuccessfully.tr(context: context)),
- callBackFunc: () {
- Navigator.pop(context);
- },
- isFullScreen: false,
- isCloseButtonVisible: false,
- isAutoDismiss: true
- );
+ getIt.get().showCommonBottomSheetWithoutH(
+ message: LocaleKeys.insuranceRequestSubmittedSuccessfully.tr(context: context),
+ label: LocaleKeys.notice.tr(),
+ onOkPressed: () {
+ Navigator.pop(context);
+ },
+ okLabel: "confirm",
+ cancelLabel: LocaleKeys.acknowledged.tr(context: context),
+ isConfirmButton: true,
+ );
+ // showCommonBottomSheetWithoutHeight(
+ // title: LocaleKeys.success.tr(context: context),
+ // context,
+ // child: Utils.getSuccessWidget(loadingText: LocaleKeys.insuranceRequestSubmittedSuccessfully.tr(context: context)),
+ // callBackFunc: () {
+ // Navigator.pop(context);
+ // },
+ // isFullScreen: false,
+ // isCloseButtonVisible: false,
+ // isAutoDismiss: true
+ // );
// Future.delayed(Duration(milliseconds: 2000)).then((value) async {
// Navigator.pop(context);
// });
diff --git a/lib/presentation/my_family/my_family.dart b/lib/presentation/my_family/my_family.dart
index dca75747..66b31cfc 100644
--- a/lib/presentation/my_family/my_family.dart
+++ b/lib/presentation/my_family/my_family.dart
@@ -43,6 +43,7 @@ class _FamilyMedicalScreenState extends State {
AppState appState = getIt.get();
return CollapsingListView(
+ isClose: true,
title: LocaleKeys.familyTitle.tr(context: context),
bottomChild: appState.getAuthenticatedUser()!.isParentUser!
? Container(
diff --git a/lib/presentation/notifications/notifications_list_page.dart b/lib/presentation/notifications/notifications_list_page.dart
index bc90b4aa..99201688 100644
--- a/lib/presentation/notifications/notifications_list_page.dart
+++ b/lib/presentation/notifications/notifications_list_page.dart
@@ -216,18 +216,18 @@ class _NotificationsListPageState extends State {
}).paddingSymmetrical(16.w, 0.h),
).paddingSymmetrical(24.w, 0.h),
SizedBox(height: 16.h),
- SizedBox(
- key: _bottomKey,
- child: "Show more notifications".toText16(
- color: AppColors.primaryRedColor,
- isBold: true,
- isUnderLine: true
- ),
- ).onPress(() async {
- await notificationsVM.loadMoreNotifications();
- _scrollToBottom();
- }),
- SizedBox(height: 24.h),
+ // SizedBox(
+ // key: _bottomKey,
+ // child: "Show more notifications".toText16(
+ // color: AppColors.primaryRedColor,
+ // isBold: true,
+ // isUnderLine: true
+ // ),
+ // ).onPress(() async {
+ // await notificationsVM.loadMoreNotifications();
+ // _scrollToBottom();
+ // }),
+ SizedBox(height: 24.h),
],
);
}),
diff --git a/lib/presentation/radiology/radiology_orders_page.dart b/lib/presentation/radiology/radiology_orders_page.dart
index 1a3ab448..db2e4f52 100644
--- a/lib/presentation/radiology/radiology_orders_page.dart
+++ b/lib/presentation/radiology/radiology_orders_page.dart
@@ -11,7 +11,6 @@ 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/lab/lab_view_model.dart';
-import 'package:hmg_patient_app_new/features/radiology/models/resp_models/patient_radiology_response_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/lab/lab_result_item_view.dart';
import 'package:hmg_patient_app_new/presentation/radiology/radiology_result_page.dart';
diff --git a/lib/presentation/radiology/radiology_result_page.dart b/lib/presentation/radiology/radiology_result_page.dart
index 05f23530..8fbdd8e6 100644
--- a/lib/presentation/radiology/radiology_result_page.dart
+++ b/lib/presentation/radiology/radiology_result_page.dart
@@ -158,28 +158,64 @@ class _RadiologyResultPageState extends State {
borderRadius: 24.h,
hasShadow: true,
),
- child: widget.patientRadiologyResponseModel.dIAPACSURL != "" ? CustomButton(
- text: LocaleKeys.openRad.tr(context: context),
- onPressed: () async {
- if (radiologyViewModel.radiologyImageURL.isNotEmpty) {
- Uri uri = Uri.parse(radiologyViewModel.radiologyImageURL);
- launchUrl(uri, mode: LaunchMode.platformDefault, webOnlyWindowName: "");
- } else {
- Utils.showToast("Radiology image not available");
- }
- },
- backgroundColor: AppColors.primaryRedColor,
- borderColor: AppColors.primaryRedColor,
- textColor: Colors.white,
- fontSize: 16,
- fontWeight: FontWeight.w500,
- borderRadius: 12,
- padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
- height: 45.h,
- icon: AppAssets.imageIcon,
- iconColor: Colors.white,
- iconSize: 20.h,
- ).paddingSymmetrical(24.h, 24.h) : SizedBox.shrink(),
+ child: Column(
+ children: [
+ SizedBox(height: 24.h),
+ widget.patientRadiologyResponseModel.dIAPACSURL != ""
+ ? CustomButton(
+ text: LocaleKeys.openRad.tr(context: context),
+ onPressed: () async {
+ if (radiologyViewModel.radiologyImageURL.isNotEmpty) {
+ Uri uri = Uri.parse(radiologyViewModel.radiologyImageURL);
+ launchUrl(uri, mode: LaunchMode.platformDefault, webOnlyWindowName: "");
+ } else {
+ Utils.showToast("Radiology image not available");
+ }
+ },
+ backgroundColor: AppColors.primaryRedColor,
+ borderColor: AppColors.primaryRedColor,
+ textColor: Colors.white,
+ fontSize: 16,
+ fontWeight: FontWeight.w500,
+ borderRadius: 12,
+ padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
+ height: 56.h,
+ icon: AppAssets.imageIcon,
+ iconColor: Colors.white,
+ iconSize: 20.h,
+ ).paddingSymmetrical(24.h, 0.h)
+ : SizedBox.shrink(),
+ Container(
+ height: 56.h,
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(12.r),
+ gradient: LinearGradient(
+ begin: Alignment.centerLeft,
+ end: Alignment.centerRight,
+ stops: [0.236, 1.0], // 53.6% and 100%
+ colors: [
+ Color(0xFF8A38F5), // Transparent
+ Color(0xFFE20BBB), // Solid #F8F8F8
+ ],
+ ),
+ ),
+ child: Row(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Padding(
+ padding: EdgeInsets.only(right: 4.w, left: 4.w),
+ child: Utils.buildSvgWithAssets(icon: AppAssets.aiOverView, width: 16.h, height: 16.h, iconColor: Colors.white),
+ ),
+ LocaleKeys.generateAiAnalysisResult.tr(context: context).toText16(isBold: true, color: Colors.white)
+ ],
+ ),
+ ).paddingSymmetrical(24.h, 12.h).onPress(() {
+ // Need to implement the Radiology AI analysis result generation functionality here
+ Utils.showToast("Radiology AI analysis result generation functionality is not implemented yet");
+ }),
+ ],
+ ),
),
],
),
diff --git a/lib/services/livecare_permission_service.dart b/lib/services/livecare_permission_service.dart
index a9a5d294..b8d71ff1 100644
--- a/lib/services/livecare_permission_service.dart
+++ b/lib/services/livecare_permission_service.dart
@@ -1,4 +1,5 @@
import 'dart:async';
+import 'dart:io';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
@@ -29,6 +30,7 @@ class LiveCarePermissionService {
Permission.camera,
Permission.microphone,
Permission.notification,
+ if (Platform.isAndroid) Permission.systemAlertWindow,
];
try {
@@ -87,6 +89,7 @@ class LiveCarePermissionService {
if (permission == Permission.camera) return 'Camera';
if (permission == Permission.microphone) return 'Microphone';
if (permission == Permission.notification) return 'Notifications';
+ if (permission == Permission.systemAlertWindow) return 'Display over other apps';
return permission.toString();
}
}