haroon_dev #208

Merged
Haroon6138 merged 7 commits from haroon_dev into master 2 days ago

@ -92,7 +92,7 @@
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" tools:node="remove"/>
<uses-permission android:name="android.permission.VIDEO_CAPTURE" />
<uses-permission android:name="android.permission.AUDIO_CAPTURE" />

@ -365,7 +365,7 @@
"paymentOnline": "الخدمة",
"onlineCheckIn": "تسجيل الوصول عبر الإنترنت",
"myBalances": "رصيدي",
"myWallet": "محف<EFBFBD><EFBFBD>تي",
"myWallet": "محفظتي",
"balanceAmount": "مبلغ المحفظة",
"totalBalance": "إجمالي الرصيد",
"createAdvancedPayment": "إعادة شحن المحفظة",
@ -489,7 +489,7 @@
"services2": "الخدمات",
"cantSeeProfile": "لرؤية ملفك الطبي، يرجى تسجيل الدخول أو التسجيل الآن",
"loginRegisterNow": "تسجيل الدخول أو التسجيل الآن",
"hmgPharmacy": "صيدلية مجموعة الحبيب الطبية",
"hmgPharmacy": "صيدلية الحبيب",
"ecommerceSolution": "حلول التجارة الإلكترونية",
"comprehensive": "شامل",
"onlineConsulting": "استشارات عبر الإنترنت",
@ -860,7 +860,7 @@
"onboardingBody1": "ببضع نقرات فقط يمكنك استشارة الطبيب الذي تختاره.",
"onboardingHeading2": "الوصول إلى السجل الطبي بين يديك",
"onboardingBody2": "تتبع تاريخك الطبي بما في ذلك الفحوصات المخبرية، الوصفات الطبية، التأمين، وغيرها.",
"hmgHospitals": "مستشفيات مجموعة الحبيب الطبية",
"hmgHospitals": "مستشفيات الحبيب",
"hmcMedicalClinic": "مراكز مجموعة الحبيب الطبية",
"applyFilter": "تطبيق الفلتر",
"facilityAndLocation": "المرفق والموقع",
@ -1649,8 +1649,7 @@
"cancelAppointmentConfirmMessage": "هل أنت متأكد من رغبتك في إلغاء هذا الموعد؟",
"acknowledged": "معترف به",
"searchLabResults": "بحث نتائج المختبر",
"callForAssistance": "اتصل للحصول على المساعدة الفورية"
"callForAssistance": "اتصل للحصول على المساعدة الفورية",
"oneWaySubtitle": "نقل من الموقع إلى المستشفى",
"twoWaySubtitle": "نقل من الموقع إلى المستشفى والعودة مرة أخرى",
"toHospitalSubtitle": "نقل من موقعك الحالي إلى المستشفى",

@ -1641,7 +1641,7 @@
"cancelAppointmentConfirmMessage": "Are you sure you want to cancel this appointment?",
"acknowledged": "Acknowledged",
"searchLabResults": "Search lab results",
"callForAssistance": "Call for immediate assistance"
"callForAssistance": "Call for immediate assistance",
"oneWaySubtitle": "Pickup from location to hospital",
"twoWaySubtitle": "Round trip from location to hospital and back",
"toHospitalSubtitle": "Transfer from your current location to the hospital",

@ -4,7 +4,7 @@ import 'package:hmg_patient_app_new/core/enums.dart';
class ApiConsts {
static const maxSmallScreen = 660;
static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.uat;
static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.prod;
// static String baseUrl = 'https://uat.hmgwebservices.com/'; // HIS API URL UAT

@ -174,7 +174,7 @@ class AppAssets {
static const String warning = '$svgBasePath/warning.svg';
static const String share_location = '$svgBasePath/share_location.svg';
static const String to_arrow = '$svgBasePath/to_arrow.svg';
static const String dual_arrow = '$svgBasePath/to_arrow.svg';
static const String dual_arrow = '$svgBasePath/dual_arrow.svg';
static const String forward_arrow_medium = '$svgBasePath/forward_arrow_medium.svg';
static const String eReferral = '$svgBasePath/e-referral.svg';
static const String comprehensiveCheckup = '$svgBasePath/comprehensive_checkup.svg';

@ -152,9 +152,11 @@ class Utils {
static String getDayMonthYearDateFormatted(DateTime? dateTime) {
if (dateTime == null) return "";
return appState.isArabic()
? "${dateTime.day.toString()} ${getMonthArabic(dateTime.month)}, ${dateTime.year.toString()}"
: "${dateTime.day.toString()} ${getMonth(dateTime.month)}, ${dateTime.year.toString()}";
return
// appState.isArabic()
// ? "${dateTime.day.toString()} ${getMonthArabic(dateTime.month)}, ${dateTime.year.toString()}"
// :
"${dateTime.day.toString()} ${getMonth(dateTime.month)}, ${dateTime.year.toString()}";
}
/// get month by

@ -296,10 +296,11 @@ extension EmailValidator on String {
style: TextStyle(height: 1, color: color ?? AppColors.blackColor, fontSize: 22.f, letterSpacing: -1, fontWeight: isBold ? FontWeight.bold : FontWeight.normal),
);
Widget toText24({Color? color, bool isBold = false, bool isCenter = false, FontWeight? fontWeight, double? letterSpacing}) => Text(
Widget toText24({Color? color, bool isBold = false, bool isCenter = false, FontWeight? fontWeight, double? letterSpacing, bool isEnglishOnly = false,}) => Text(
this,
textAlign: isCenter ? TextAlign.center : null,
style: TextStyle(
fontFamily: (isEnglishOnly ? "Poppins" : getIt.get<AppState>().getLanguageCode() == "ar" ? 'GESSTwo' : 'Poppins'),
height: 23 / 24, color: color ?? AppColors.blackColor, fontSize: 24.f, letterSpacing: letterSpacing ?? -1, fontWeight: isBold ? FontWeight.bold : fontWeight ?? FontWeight.normal),
);

@ -31,6 +31,7 @@ import 'package:hmg_patient_app_new/features/authentication/models/resp_models/s
import 'package:hmg_patient_app_new/features/hmg_services/hmg_services_view_model.dart';
import 'package:hmg_patient_app_new/features/medical_file/medical_file_view_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart';
import 'package:hmg_patient_app_new/features/symptoms_checker/symptoms_checker_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/authentication/login.dart';
import 'package:hmg_patient_app_new/presentation/authentication/saved_login_screen.dart';
@ -131,6 +132,8 @@ class AuthenticationViewModel extends ChangeNotifier {
pickedCountryByUAEUser = null;
_appState.setUserRegistrationPayload = RegistrationDataModelPayload();
_appState.setNHICUserData = CheckUserStatusResponseNHIC();
getIt.get<SymptomsCheckerViewModel>().setSelectedHeight(0);
getIt.get<SymptomsCheckerViewModel>().setSelectedWeight(0);
}
void onCountryChange(CountryEnum country) {

@ -153,6 +153,72 @@ class BookAppointmentsViewModel extends ChangeNotifier {
AppointmentNearestGateResponseModel? appointmentNearestGateResponseModel;
///variables for laser clinic
bool isLaserHospitalsLoading = false;
List<PatientDoctorAppointmentList> laserHospitalsList = [];
int laserHospitalHmgCount = 0;
int laserHospitalHmcCount = 0;
Future<void> getLaserHospitals({Function(dynamic)? onSuccess, Function(String)? onError}) async {
isLaserHospitalsLoading = true;
laserHospitalsList.clear();
laserHospitalHmgCount = 0;
laserHospitalHmcCount = 0;
notifyListeners();
final result = await bookAppointmentsRepo.getDoctorsList(253, 0, false, 0, '');
result.fold(
(failure) async {
isLaserHospitalsLoading = false;
notifyListeners();
onError?.call(failure.message);
},
(apiResponse) async {
if (apiResponse.messageStatus == 1) {
var doctorList = apiResponse.data!;
var regionList = await DoctorMapper.getMappedDoctor(
doctorList,
isArabic: _appState.isArabic(),
lat: _appState.userLat,
long: _appState.userLong,
);
var isLocationEnabled = (_appState.userLat != 0) && (_appState.userLong != 0);
regionList = await DoctorMapper.sortList(isLocationEnabled, regionList);
// Flatten all hospitals across all regions into a single list
laserHospitalsList.clear();
Set<String> addedHospitals = {};
regionList.registeredDoctorMap?.forEach((region, regionData) {
for (var hospital in regionData?.hmgDoctorList ?? <PatientDoctorAppointmentList>[]) {
if (!addedHospitals.contains(hospital.filterName)) {
addedHospitals.add(hospital.filterName ?? '');
laserHospitalsList.add(hospital);
}
}
for (var hospital in regionData?.hmcDoctorList ?? <PatientDoctorAppointmentList>[]) {
if (!addedHospitals.contains(hospital.filterName)) {
addedHospitals.add(hospital.filterName ?? '');
laserHospitalsList.add(hospital);
}
}
});
laserHospitalHmgCount = laserHospitalsList.where((h) => h.isHMC != true).length;
laserHospitalHmcCount = laserHospitalsList.where((h) => h.isHMC == true).length;
isLaserHospitalsLoading = false;
notifyListeners();
onSuccess?.call(apiResponse);
} else {
isLaserHospitalsLoading = false;
notifyListeners();
onError?.call(apiResponse.errorMessage ?? 'Unknown error');
}
},
);
}
List<LaserCategoryType> femaleLaserCategory = [
LaserCategoryType(1, 'bodyString'),
LaserCategoryType(2, 'face'),
@ -546,6 +612,9 @@ class BookAppointmentsViewModel extends ChangeNotifier {
//TODO: Make the API dynamic with parameters for ProjectID, isNearest, languageID, doctorId, doctorName
Future<void> getDoctorsList({int projectID = 0, bool isNearest = true, int doctorId = 0, String doctorName = "", Function(dynamic)? onSuccess, Function(String)? onError}) async {
doctorsList.clear();
filteredDoctorList.clear();
doctorsListGrouped.clear();
notifyListeners();
projectID = currentlySelectedHospitalFromRegionFlow != null ? int.parse(currentlySelectedHospitalFromRegionFlow!) : projectID;
final result =
await bookAppointmentsRepo.getDoctorsList(selectedClinic.clinicID ?? 0, projectID, doctorName.isNotEmpty ? false : isNearest, doctorId, doctorName, isContinueDentalPlan: isContinueDentalPlan);

@ -73,6 +73,7 @@ class PatientAppointmentHistoryResponseModel {
num? patientShare;
num? patientShareWithTax;
num? patientTaxAmount;
String? doctorNationalityFlagURL;
PatientAppointmentHistoryResponseModel({
this.setupID,
@ -148,6 +149,7 @@ class PatientAppointmentHistoryResponseModel {
this.patientShare,
this.patientShareWithTax,
this.patientTaxAmount,
this.doctorNationalityFlagURL,
});
PatientAppointmentHistoryResponseModel.fromJson(Map<String, dynamic> json) {
@ -235,6 +237,7 @@ class PatientAppointmentHistoryResponseModel {
patientShare = json['PatientShare'];
patientShareWithTax = json['PatientShareWithTax'];
patientTaxAmount = json['PatientTaxAmount'];
doctorNationalityFlagURL = json['DoctorNationalityFlagURL'];
}
Map<String, dynamic> toJson() {

@ -566,6 +566,8 @@ class MyAppointmentsRepoImp implements MyAppointmentsRepo {
final appointmentsList = (list as List).map((item) => GetFavoriteDoctorsListModel.fromJson(item as Map<String, dynamic>)).toList().cast<GetFavoriteDoctorsListModel>();
appointmentsList.removeWhere((element) => element.isActive == false);
apiResponse = GenericApiModel<List<GetFavoriteDoctorsListModel>>(
messageStatus: messageStatus,
statusCode: statusCode,

@ -15,7 +15,7 @@ class NotificationsViewModel extends ChangeNotifier {
List<NotificationResponseModel> notificationsList = [];
int currentPage = 0;
int pagingSize = 15;
int pagingSize = 50;
int notificationStatusID = 2; // Default to status 2 (e.g., unread)
NotificationsViewModel({

@ -258,7 +258,8 @@ class _AppointmentPaymentPageState extends State<AppointmentPaymentPage> {
CustomPageRoute(
page: InsuranceHomePage(),
),
);
)
.then((val) {});
},
backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.secondaryLightRedBorderColor,

@ -165,7 +165,16 @@ class AppointmentCard extends StatelessWidget {
children: [
(isLoading ? 'Dr' : "${patientAppointmentHistoryResponseModel.doctorTitle}").toText16(isBold: true, maxlines: 1),
(isLoading ? 'John Doe' : " ${patientAppointmentHistoryResponseModel.doctorNameObj!.truncate(20)}")
.toText16(isBold: true, maxlines: 1, isEnglishOnly: !Utils.isArabicText(patientAppointmentHistoryResponseModel.doctorNameObj ?? "John Doe"))
.toText16(isBold: true, maxlines: 1, isEnglishOnly: !Utils.isArabicText(patientAppointmentHistoryResponseModel.doctorNameObj ?? "John Doe")),
SizedBox(width: 12.w),
(patientAppointmentHistoryResponseModel.doctorNationalityFlagURL != null && patientAppointmentHistoryResponseModel.doctorNationalityFlagURL!.isNotEmpty)
? Image.network(
patientAppointmentHistoryResponseModel.doctorNationalityFlagURL ?? "https://hmgwebservices.com/Images/flag/SAU.png",
width: 20.h,
height: 15.h,
fit: BoxFit.cover,
)
: SizedBox.shrink(),
],
).toShimmer2(isShow: isLoading),
SizedBox(height: 8.h),

@ -71,20 +71,20 @@ class AppointmentCheckinBottomSheet extends StatelessWidget {
}
});
}),
SizedBox(height: 16.h),
checkInOptionCard(
AppAssets.checkin_nfc_icon,
LocaleKeys.nfcNearFieldCommunication.tr(context: context),
LocaleKeys.scanPhoneViaNFC.tr(context: context),
).onPress(() {
Future.delayed(const Duration(milliseconds: 500), () {
showNfcReader(context, onNcfScan: (String nfcId) {
Future.delayed(const Duration(milliseconds: 100), () {
sendCheckInRequest(nfcId, 1, context);
});
}, onCancel: () {});
});
}),
// SizedBox(height: 16.h),
// checkInOptionCard(O
// AppAssets.checkin_nfc_icon,
// LocaleKeys.nfcNearFieldCommunication.tr(context: context),
// LocaleKeys.scanPhoneViaNFC.tr(context: context),
// ).onPress(() {
// Future.delayed(const Duration(milliseconds: 500), () {
// showNfcReader(context, onNcfScan: (String nfcId) {
// Future.delayed(const Duration(milliseconds: 100), () {
// sendCheckInRequest(nfcId, 1, context);
// });
// }, onCancel: () {});
// });
// }),
SizedBox(height: 16.h),
checkInOptionCard(
AppAssets.checkin_qr_icon,

@ -87,7 +87,20 @@ class AppointmentDoctorCard extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
patientAppointmentHistoryResponseModel.doctorNameObj!.toText16(isBold: true, isEnglishOnly: !Utils.isArabicText(patientAppointmentHistoryResponseModel.doctorNameObj ?? "")),
Row(
children: [
patientAppointmentHistoryResponseModel.doctorNameObj!.toText16(isBold: true, isEnglishOnly: !Utils.isArabicText(patientAppointmentHistoryResponseModel.doctorNameObj ?? "")),
SizedBox(width: 12.w),
(patientAppointmentHistoryResponseModel.doctorNationalityFlagURL != null && patientAppointmentHistoryResponseModel.doctorNationalityFlagURL!.isNotEmpty)
? Image.network(
patientAppointmentHistoryResponseModel.doctorNationalityFlagURL ?? "https://hmgwebservices.com/Images/flag/SAU.png",
width: 20.h,
height: 15.h,
fit: BoxFit.cover,
)
: SizedBox.shrink(),
],
),
SizedBox(height: 8.h),
Wrap(
direction: Axis.horizontal,

@ -10,6 +10,8 @@ import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart';
import 'dart:ui' as ui;
class HospitalListItem extends StatelessWidget {
final PatientDoctorAppointmentList? hospitalData;
final bool isLocationEnabled;
@ -76,12 +78,16 @@ class HospitalListItem extends StatelessWidget {
children: [
Visibility(
visible: (hospitalData?.distanceInKMs != "0"),
child: AppCustomChipWidget(
labelText: "${hospitalData?.distanceInKMs ?? ""} km",
deleteIcon: AppAssets.location_red,
deleteIconSize: Size(9, 12),
backgroundColor: AppColors.secondaryLightRedColor,
textColor: AppColors.errorColor,
child: Directionality(
textDirection: ui.TextDirection.ltr,
child: AppCustomChipWidget(
labelText: "${hospitalData?.distanceInKMs ?? ""} km",
deleteIcon: AppAssets.location_red,
deleteIconSize: Size(9, 12),
backgroundColor: AppColors.secondaryLightRedColor,
textColor: AppColors.errorColor,
isEnglishOnly: true,
),
),
),
Visibility(

@ -117,38 +117,38 @@ class _RegionBottomSheetBodyState extends State<RegionBottomSheetBody> {
height: MediaQuery.of(context).size.height * 0.5,
child: Column(
children: [
Consumer<AppointmentViaRegionViewmodel>(
builder: (context, regionVM, _) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 4.w, vertical: 8.h),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Utils.buildSvgWithAssets(icon: AppAssets.location, iconColor: AppColors.greyTextColor, width: 24.h, height: 24.h),
SizedBox(width: 12.w),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.sortByLocation.tr(context: context).toText14(isBold: true),
// SizedBox(height: 4.h),
LocaleKeys.sortByNearestLocation.tr(context: context).toText11(color: AppColors.textColorLight, weight: FontWeight.w500),
],
),
],
),
Switch(
value: regionVM.sortByLocation,
onChanged: (value) => _handleSortByLocationToggle(value),
activeThumbColor: AppColors.successColor,
activeTrackColor: AppColors.successColor.withValues(alpha: 0.15),
),
],
),
);
},
),
// Consumer<AppointmentViaRegionViewmodel>(
// builder: (context, regionVM, _) {
// return Padding(
// padding: EdgeInsets.symmetric(horizontal: 4.w, vertical: 8.h),
// child: Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// Row(
// children: [
// Utils.buildSvgWithAssets(icon: AppAssets.location, iconColor: AppColors.greyTextColor, width: 24.h, height: 24.h),
// SizedBox(width: 12.w),
// Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// LocaleKeys.sortByLocation.tr(context: context).toText14(isBold: true),
// // SizedBox(height: 4.h),
// LocaleKeys.sortByNearestLocation.tr(context: context).toText11(color: AppColors.textColorLight, weight: FontWeight.w500),
// ],
// ),
// ],
// ),
// Switch(
// value: regionVM.sortByLocation,
// onChanged: (value) => _handleSortByLocationToggle(value),
// activeThumbColor: AppColors.successColor,
// activeTrackColor: AppColors.successColor.withValues(alpha: 0.15),
// ),
// ],
// ),
// );
// },
// ),
Expanded(
child: ListView.separated(
itemCount: myAppointmentsVM.hospitalList?.registeredDoctorMap?.length ?? 0,

@ -1,5 +1,6 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart' show NumberFormat;
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';
@ -160,8 +161,7 @@ class DoctorProfilePage extends StatelessWidget {
Utils.buildSvgWithAssets(icon: AppAssets.doctor_profile_reviews_icon, width: 48.w, height: 48.h, fit: BoxFit.contain, applyThemeColor: false),
SizedBox(height: 16.h),
LocaleKeys.reviews.tr(context: context).toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor),
bookAppointmentsViewModel.doctorsProfileResponseModel.noOfPatientsRate
.toString()
NumberFormat.decimalPattern().format(bookAppointmentsViewModel.doctorsProfileResponseModel.noOfPatientsRate ?? 0)
.toText16(isBold: true, color: AppColors.textColor, isUnderLine: true, decorationColor: AppColors.textColor, fontFamily: "Poppins"),
],
).onPress(() {

@ -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<LaserBodyPart> 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<BookAppointmentsViewModel>().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<BookAppointmentsViewModel>().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),
// ],
// ),
],
),
),

@ -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 = <Permission>[];
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<bool> askVideoCallPermission() async {

@ -16,6 +16,8 @@ import 'package:hmg_patient_app_new/features/book_appointments/book_appointments
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/get_clinic_list_response_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/get_livecare_clinics_response_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/appointment_via_region_viewmodel.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/facility_selection.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/doctor_list_api_response.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/appointments/widgets/faculity_selection/facility_type_selection_widget.dart';
import 'package:hmg_patient_app_new/presentation/appointments/widgets/hospital_bottom_sheet/hospital_bottom_sheet_body.dart';
@ -1027,6 +1029,7 @@ class _SelectClinicPageState extends State<SelectClinicPage> {
//17 and 235
void handleDoctorScreen(GetClinicsListResponseModel clinic) async {
regionalViewModel.flush();
if (widget.isFromRegionFlow) {
//Dental Clinic Flow
if (clinic.clinicID == 17) {
@ -1061,8 +1064,22 @@ class _SelectClinicPageState extends State<SelectClinicPage> {
);
}
} else {
if (clinic.clinicID == 253) {
LoaderBottomSheet.showLoader(loadingText: LocaleKeys.loadingText.tr(context: context));
await bookAppointmentsViewModel.getLaserHospitals(
onSuccess: (_) {
LoaderBottomSheet.hideLoader();
_showLaserHospitalBottomSheet();
},
onError: (err) {
LoaderBottomSheet.hideLoader();
},
);
return;
}
var bottomSheetType = RegionBottomSheetType.FOR_CLINIIC;
if (clinic.clinicID == 17 || clinic.clinicID == 253) {
if (clinic.clinicID == 17) {
regionalViewModel.setBottomSheetState(AppointmentViaRegionState.HOSPITAL_SELECTION);
bottomSheetType = RegionBottomSheetType.REGION_FOR_DENTAL_AND_LASER;
}
openRegionListBottomSheet(context, bottomSheetType);
@ -1072,7 +1089,6 @@ class _SelectClinicPageState extends State<SelectClinicPage> {
void openRegionListBottomSheet(BuildContext context, RegionBottomSheetType type) {
bookAppointmentsViewModel.setProjectID(null);
regionalViewModel.flush();
regionalViewModel.setBottomSheetType(type);
// AppointmentViaRegionViewmodel? viewmodel = null;
showCommonBottomSheetWithoutHeight(context, title: "", titleWidget: Consumer<AppointmentViaRegionViewmodel>(builder: (_, data, __) => getTitle(data)), isDismissible: false,
@ -1350,4 +1366,60 @@ class _SelectClinicPageState extends State<SelectClinicPage> {
// bookAppointmentsViewModel.getRegionMappedProjectList();
}
void _showLaserHospitalBottomSheet() {
final TextEditingController laserHospitalSearchController = TextEditingController();
List<PatientDoctorAppointmentList> filteredList = List.from(bookAppointmentsViewModel.laserHospitalsList);
showCommonBottomSheetWithoutHeight(
context,
title: LocaleKeys.selectHospital.tr(context: context),
isDismissible: true,
isCloseButtonVisible: true,
child: StatefulBuilder(
builder: (context, setModalState) {
return HospitalBottomSheetBody(
searchText: laserHospitalSearchController,
displayList: filteredList,
selectedFacility: FacilitySelection.ALL,
hmcCount: bookAppointmentsViewModel.laserHospitalHmcCount,
hmgCount: bookAppointmentsViewModel.laserHospitalHmgCount,
sortByLocation: false,
onFacilityClicked: (facility) {
setModalState(() {
if (facility == FacilitySelection.ALL) {
filteredList = List.from(bookAppointmentsViewModel.laserHospitalsList);
} else if (facility == FacilitySelection.HMG) {
filteredList = bookAppointmentsViewModel.laserHospitalsList.where((h) => h.isHMC != true).toList();
} else {
filteredList = bookAppointmentsViewModel.laserHospitalsList.where((h) => h.isHMC == true).toList();
}
});
},
onHospitalClicked: (hospital) {
Navigator.of(context).pop(); // close bottom sheet
final projectID = hospital.hospitalList.isNotEmpty ? hospital.hospitalList.first.iD?.toString() : hospital.patientDoctorAppointmentList?.first.projectID?.toString();
bookAppointmentsViewModel.setProjectID(projectID);
bookAppointmentsViewModel.resetLaserData();
bookAppointmentsViewModel.getLaserClinic();
Navigator.push(
context,
CustomPageRoute(page: LaserAppointment()),
);
},
onHospitalSearch: (value) {
setModalState(() {
if (value.isEmpty) {
filteredList = List.from(bookAppointmentsViewModel.laserHospitalsList);
} else {
filteredList = bookAppointmentsViewModel.laserHospitalsList.where((h) => h.filterName != null && h.filterName!.toLowerCase().contains(value.toLowerCase())).toList();
}
});
},
);
},
),
callBackFunc: () {},
);
}
}

@ -220,8 +220,9 @@ class _SelectDoctorPageState extends State<SelectDoctorPage> {
],
).paddingSymmetrical(0.h, 0.h),
if (bookAppointmentsViewModel.isGetDocForHealthCal && bookAppointmentsVM.showSortFilterButtons) SizedBox(height: 16.h),
Row(
mainAxisSize: MainAxisSize.max,
bookAppointmentsVM.doctorsListGrouped.isNotEmpty
? Row(
mainAxisSize: MainAxisSize.max,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
@ -241,8 +242,9 @@ class _SelectDoctorPageState extends State<SelectDoctorPage> {
},
),
],
),
ListView.separated(
)
: SizedBox.shrink(),
ListView.separated(
padding: EdgeInsets.only(top: 16.h),
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),

@ -133,9 +133,9 @@ class DoctorCard extends StatelessWidget {
labelText: (isLoading ? "Cardiologist" : DateUtil.getDateStringForNearestSlot(doctorsListResponseModel.nearestFreeSlot)),
// richText: (isLoading ? "Cardiologist" : DateUtil.getDateStringForNearestSlot(doctorsListResponseModel.nearestFreeSlot))
// .toText10(isEnglishOnly: true, color: AppColors.textColor),
// backgroundColor: AppColors.successColor,
isEnglishOnly: true,
textColor: AppColors.textColor,
backgroundColor: AppColors.successColor.withValues(alpha: .15),
isEnglishOnly: true,
textColor: AppColors.successColor,
).toShimmer2(isShow: isLoading)
: SizedBox.shrink()
: SizedBox.shrink(),

@ -1,6 +1,9 @@
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/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
@ -116,19 +119,19 @@ class DoctorRatingDialog extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: 130,
height: 160,
decoration: BoxDecoration(
width: 130.w,
height: 140.h,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
borderRadius: 16.r,
color: _getBadgeColor(averageRating),
borderRadius: BorderRadius.circular(18),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
averageRating.toStringAsFixed(1),
averageRating.toString(),
style: TextStyle(
fontSize: 60,
fontSize: 48.f,
fontWeight: FontWeight.w700,
color: averageRating == 0 || averageRating == 0.0 ? AppColors.textColor : AppColors.whiteColor,
height: 1.1,
@ -137,21 +140,34 @@ class DoctorRatingDialog extends StatelessWidget {
const SizedBox(height: 8),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 16,
horizontal: 8,
vertical: 6,
),
decoration: BoxDecoration(
color: averageRating == 0 || averageRating == 0.0 ? AppColors.greyF7Color : const Color.fromRGBO(0, 0, 0, 0.15),
color: averageRating == 0 || averageRating == 0.0 ? AppColors.greyF7Color : AppColors.textColor.withAlpha(20),
borderRadius: BorderRadius.circular(8),
),
child: Text(
'$totalReviews Review',
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
color: averageRating == 0 || averageRating == 0.0 ? AppColors.textColor : AppColors.whiteColor,
),
child: Row(
children: [
NumberFormat.decimalPattern().format(totalReviews).toText12(
fontWeight: FontWeight.w500,
color: averageRating == 0 || averageRating == 0.0 ? AppColors.textColor : AppColors.whiteColor,
isEnglishOnly: true
),
' ${LocaleKeys.reviews.tr(context: context)}'.toText12(
fontWeight: FontWeight.w500,
color: averageRating == 0 || averageRating == 0.0 ? AppColors.textColor : AppColors.whiteColor,
),
],
),
// child: Text(
// '${NumberFormat.decimalPattern().format(totalReviews)} ${LocaleKeys.reviews.tr(context: context)}',
// style: TextStyle(
// fontSize: 12.f,
// fontWeight: FontWeight.w500,
// color: averageRating == 0 || averageRating == 0.0 ? AppColors.textColor : AppColors.whiteColor,
// ),
// ),
),
],
),
@ -199,7 +215,7 @@ class DoctorRatingDialog extends StatelessWidget {
child: ClipRRect(
borderRadius: BorderRadius.circular(6),
child: SizedBox(
height: 10,
height: 5.h,
child: LinearProgressIndicator(
value: percent / 100,
backgroundColor: AppColors.shimmerBaseColor,

@ -45,7 +45,7 @@ class FindUsPage extends StatelessWidget {
activeBackgroundColor: AppColors.primaryRedColor.withValues(alpha: .1),
tabs: [
CustomTabBarModel(null, LocaleKeys.hmgHospitals.tr()),
CustomTabBarModel(null, LocaleKeys.pharmaciesList.tr()),
CustomTabBarModel(null, LocaleKeys.hmgPharmacy.tr()),
],
onTabChange: (index) {
contactUsVM.setHMGHospitalsListSelected(index == 0);

@ -18,6 +18,7 @@ import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart';
import 'package:map_launcher/map_launcher.dart';
import 'package:provider/provider.dart';
import 'package:url_launcher/url_launcher.dart';
import 'dart:ui' as ui;
class FindUsItemCard extends StatelessWidget {
FindUsItemCard({super.key, required this.getHMGLocationsModel});
@ -57,13 +58,17 @@ class FindUsItemCard extends StatelessWidget {
(getHMGLocationsModel.distanceInKilometers != 0 && contactUsViewModel.hasLocationEnabled)
? Column(
children: [
AppCustomChipWidget(
labelText: "${getHMGLocationsModel.distanceInKilometers ?? ""} km",
labelPadding: EdgeInsetsDirectional.only(start: -4.h, end: 8.w),
icon: AppAssets.location_red,
// iconColor: AppColors.primaryRedColor,
// backgroundColor: AppColors.secondaryLightRedColor,
// textColor: AppColors.errorColor,
Directionality(
textDirection: ui.TextDirection.ltr,
child: AppCustomChipWidget(
labelText: "${getHMGLocationsModel.distanceInKilometers ?? ""} km",
labelPadding: EdgeInsetsDirectional.only(start: -4.h, end: 8.w),
icon: AppAssets.location_red,
isEnglishOnly: true,
// iconColor: AppColors.primaryRedColor,
// backgroundColor: AppColors.secondaryLightRedColor,
// textColor: AppColors.errorColor,
),
),
SizedBox(
height: 16.h,

@ -2,6 +2,8 @@ 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/core/app_state.dart';
import 'package:hmg_patient_app_new/core/dependencies.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/emergency_services/emergency_services_view_model.dart';
@ -46,7 +48,7 @@ class WayPickup extends StatelessWidget {
firstIcon: AppAssets.to_arrow,
middleIcon: AppAssets.to_arrow,
lastIcon: AppAssets.hospital,
shouldFlipIcon: getIt.get<AppState>().isArabic(),
shouldFlipIcon: getIt.get<AppState>().isArabic(),
price: context.read<EmergencyServicesViewModel>().selectedTransportOption?.priceTotal?.toString()??"",
onTap: () {
context

@ -60,20 +60,20 @@ class ErOnlineCheckinSelectCheckinBottomSheet extends StatelessWidget {
}
});
}),
SizedBox(height: 16.h),
checkInOptionCard(
AppAssets.checkin_nfc_icon,
LocaleKeys.nfcNearFieldCommunication.tr(context: context),
LocaleKeys.scanPhoneViaNFC.tr(context: context),
).onPress(() {
Future.delayed(const Duration(milliseconds: 500), () {
showNfcReader(context, onNcfScan: (String nfcId) {
Future.delayed(const Duration(milliseconds: 100), () {
sendCheckInRequest(nfcId, context);
});
}, onCancel: () {});
});
}),
// SizedBox(height: 16.h),
// checkInOptionCard(
// AppAssets.checkin_nfc_icon,
// LocaleKeys.nfcNearFieldCommunication.tr(context: context),
// LocaleKeys.scanPhoneViaNFC.tr(context: context),
// ).onPress(() {
// Future.delayed(const Duration(milliseconds: 500), () {
// showNfcReader(context, onNcfScan: (String nfcId) {
// Future.delayed(const Duration(milliseconds: 100), () {
// sendCheckInRequest(nfcId, context);
// });
// }, onCancel: () {});
// });
// }),
SizedBox(height: 16.h),
checkInOptionCard(
AppAssets.checkin_qr_icon,

@ -23,7 +23,6 @@ class ErHistoryListing extends StatelessWidget {
return Scaffold(
body: Column(
children: [
Expanded(
child: CollapsingListView(
title: LocaleKeys.history.tr(context: context),
@ -31,15 +30,12 @@ class ErHistoryListing extends StatelessWidget {
physics: NeverScrollableScrollPhysics(),
child: Column(
children: [
Selector<EmergencyServicesViewModel,(List, bool)>(
selector: (context, vm) => (vm.orderDisplayList, vm.historyLoading),
builder: (context, data, _) {
return Column(
children: [
orderChips(context, data.$2, data.$1),
Visibility(
visible:data.$1.isNotEmpty == true,
child: ListView.builder(

@ -13,6 +13,7 @@ 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 'package:provider/provider.dart';
import 'dart:ui' as ui;
import '../../../../core/utils/utils.dart';
@ -37,11 +38,11 @@ class AmbulanceHistoryItem extends StatelessWidget {
spacing: 8.h,
children: [
RequestStatus(status: order.statusId ?? 0),
"Req ID: ${order.iD}".toText16(color: AppColors.textColor, weight: FontWeight.w600),
"Req ID: ${order.iD}".toText16(color: AppColors.textColor, weight: FontWeight.w600, isEnglishOnly: true),
Row(
spacing: 4.w,
children: [
chip( Utils.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(order.time)), AppAssets.calendar, AppColors.blackBgColor),
chip(Utils.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(order.time)), AppAssets.calendar, AppColors.blackBgColor),
chip(LocaleKeys.ambulancerequest.tr(context: context), AppAssets.ambulance, AppColors.blackBgColor),
],
),
@ -71,11 +72,15 @@ class AmbulanceHistoryItem extends StatelessWidget {
}
chip(String title, String iconString, Color iconColor) {
return AppCustomChipWidget(
labelText: title,
icon: iconString,
iconColor: iconColor,
iconSize: 12.h,
return Directionality(
textDirection: ui.TextDirection.ltr,
child: AppCustomChipWidget(
labelText: title,
icon: iconString,
iconColor: iconColor,
iconSize: 12.h,
isEnglishOnly: true,
),
);
}

@ -13,6 +13,7 @@ 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 'package:provider/provider.dart';
import 'dart:ui' as ui;
import '../../../../core/utils/utils.dart';
@ -37,11 +38,11 @@ class RRTItem extends StatelessWidget {
spacing: 8.h,
children: [
RequestStatus(status: order.statusId ?? 0),
"Req ID: ${order.iD}".toText16(color: AppColors.textColor, weight: FontWeight.w600),
"Req ID: ${order.iD}".toText16(color: AppColors.textColor, weight: FontWeight.w600, isEnglishOnly: true),
Row(
spacing: 4.w,
children: [
chip( Utils.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(order.time)), AppAssets.calendar, AppColors.blackBgColor),
chip(Utils.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(order.time)), AppAssets.calendar, AppColors.blackBgColor),
chip(LocaleKeys.rapidResponseTeam.tr(context: context), AppAssets.ic_rrt_vehicle, AppColors.blackBgColor),
],
),
@ -65,11 +66,15 @@ class RRTItem extends StatelessWidget {
}
chip(String title, String iconString, Color iconColor) {
return AppCustomChipWidget(
labelText: title,
icon: iconString,
iconColor: iconColor,
iconSize: 12.h,
return Directionality(
textDirection: ui.TextDirection.ltr,
child: AppCustomChipWidget(
labelText: title,
icon: iconString,
iconColor: iconColor,
iconSize: 12.h,
isEnglishOnly: true,
),
);
}

@ -13,6 +13,8 @@ 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 'package:provider/provider.dart';
import 'dart:ui' as ui;
class NearestERItem extends StatelessWidget {
final ProjectAvgERWaitingTime nearestERItem;
final bool isLoading;
@ -68,20 +70,28 @@ class NearestERItem extends StatelessWidget {
Row(
spacing: 8.h,
children: [
AppCustomChipWidget(
labelText: "${nearestERItem.distanceInKilometers} km",
icon: AppAssets.location,
iconHasColor: false,
labelPadding: EdgeInsetsDirectional.only(start: 4.h, end: 0.h),
padding: EdgeInsets.all(8.h),
).toShimmer2(isShow: isLoading),
AppCustomChipWidget(
labelText: "Expected waiting time: ${nearestERItem.getTime()} mins",
icon: AppAssets.waiting_time_clock,
iconHasColor: false,
labelPadding: EdgeInsetsDirectional.only(start: 4.h, end: 0.h),
padding: EdgeInsets.all(8.h),
).toShimmer2(isShow: isLoading),
Directionality(
textDirection: ui.TextDirection.ltr,
child: AppCustomChipWidget(
labelText: "${nearestERItem.distanceInKilometers} km",
icon: AppAssets.location,
iconHasColor: false,
labelPadding: EdgeInsetsDirectional.only(start: 4.h, end: 0.h),
padding: EdgeInsets.all(8.h),
isEnglishOnly: true,
).toShimmer2(isShow: isLoading),
),
Directionality(
textDirection: ui.TextDirection.ltr,
child: AppCustomChipWidget(
labelText: "Expected waiting time: ${nearestERItem.getTime()} mins",
icon: AppAssets.waiting_time_clock,
iconHasColor: false,
labelPadding: EdgeInsetsDirectional.only(start: 4.h, end: 0.h),
padding: EdgeInsets.all(8.h),
isEnglishOnly: true,
).toShimmer2(isShow: isLoading),
),
],
),
SizedBox(height: 16.h),

@ -74,7 +74,7 @@ class _HabibWalletState extends State<HabibWalletPage> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"${_appState.getAuthenticatedUser()!.firstName!} ${_appState.getAuthenticatedUser()!.lastName!}".toText19(isBold: true, color: Colors.white),
"MRN: ${_appState.getAuthenticatedUser()!.patientId!}".toText14(weight: FontWeight.w500, color: AppColors.greyTextColor),
"MRN: ${_appState.getAuthenticatedUser()!.patientId!}".toText14(weight: FontWeight.w500, color: AppColors.greyTextColor, isEnglishOnly: true),
],
).expanded,
Utils.buildSvgWithAssets(icon: AppAssets.habiblogo, width: 24.h, height: 24.h, applyThemeColor: false),
@ -84,7 +84,8 @@ class _HabibWalletState extends State<HabibWalletPage> {
LocaleKeys.balanceAmount.tr(context: context).toText14(weight: FontWeight.w500, color: Colors.white),
SizedBox(height: 4.h),
Consumer<HabibWalletViewModel>(builder: (context, habibWalletVM, child) {
return Utils.getPaymentAmountWithSymbol2(habibWalletVM.habibWalletAmount, textColor: Colors.white, iconColor: Colors.white, iconSize: 16, isExpanded: false)
return Utils.getPaymentAmountWithSymbol2(num.parse(NumberFormat.decimalPattern().format(habibWalletVM.habibWalletAmount)),
textColor: Colors.white, iconColor: Colors.white, iconSize: 16, isExpanded: false)
.toShimmer2(isShow: habibWalletVM.isWalletAmountLoading, radius: 12.h, width: 80.h, height: 24.h);
}),
],
@ -138,7 +139,8 @@ class _HabibWalletState extends State<HabibWalletPage> {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(child: habibWalletVM.habibWalletBalanceList[index].projectDescription!.toText16(weight: FontWeight.w500, color: AppColors.textColor)),
Utils.getPaymentAmountWithSymbol2(habibWalletVM.habibWalletBalanceList[index].patientAdvanceBalanceAmount!, textColor: AppColors.textColor, iconColor: AppColors.textColor, iconSize: 18.h, isExpanded: false, fontSize: 28.f, fontWeight: FontWeight.w500),
Utils.getPaymentAmountWithSymbol2(num.parse(NumberFormat.decimalPattern().format(habibWalletVM.habibWalletBalanceList[index].patientAdvanceBalanceAmount!)),
textColor: AppColors.textColor, iconColor: AppColors.textColor, iconSize: 18.h, isExpanded: false, fontSize: 28.f, fontWeight: FontWeight.w500),
],
).paddingSymmetrical(0, 12.h);
},

@ -140,7 +140,7 @@ class _RechargeWalletPageState extends State<RechargeWalletPage> {
children: [
(habibWalletVM.getSelectedRechargeTypeValue()).toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500),
"${LocaleKeys.medicalFile.tr(context: context)}: ${habibWalletVM.fileNumber}"
.toText14(color: AppColors.textColor, weight: FontWeight.w500, letterSpacing: -0.2),
.toText14(color: AppColors.textColor, weight: FontWeight.w500, letterSpacing: -0.2, isEnglishOnly: true),
],
),
],
@ -203,7 +203,7 @@ class _RechargeWalletPageState extends State<RechargeWalletPage> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.email.tr(context: context).toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500),
"${appState.getAuthenticatedUser()!.emailAddress}".toText14(color: AppColors.textColor, weight: FontWeight.w500, letterSpacing: -0.2),
"${appState.getAuthenticatedUser()!.emailAddress}".toText14(color: AppColors.textColor, weight: FontWeight.w500, letterSpacing: -0.2, isEnglishOnly: true),
],
),
],

@ -62,7 +62,7 @@ class _WalletPaymentConfirmPageState extends State<WalletPaymentConfirmPage> {
children: [
Expanded(
child: CollapsingListView(
title: "Select Payment Method",
title: LocaleKeys.selectPaymentOption.tr(context: context),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
@ -169,9 +169,17 @@ class _WalletPaymentConfirmPageState extends State<WalletPaymentConfirmPage> {
spacing: 4.h,
runSpacing: 4.h,
children: [
AppCustomChipWidget(labelText: "${LocaleKeys.fileno.tr(context: context)}.: ${habibWalletVM.fileNumber}"),
AppCustomChipWidget(labelText: "${LocaleKeys.mobileNumber.tr(context: context)}: ${habibWalletVM.mobileNumber}"),
AppCustomChipWidget(labelText: "${habibWalletVM.selectedHospital!.name}"),
AppCustomChipWidget(
labelText: "${LocaleKeys.fileno.tr(context: context)}.: ${habibWalletVM.fileNumber}",
isEnglishOnly: true,
),
AppCustomChipWidget(
labelText: "${LocaleKeys.mobileNumber.tr(context: context)}: ${habibWalletVM.mobileNumber}",
isEnglishOnly: true,
),
AppCustomChipWidget(
labelText: "${habibWalletVM.selectedHospital!.name}",
),
],
).paddingSymmetrical(24.h, 0.h),
SizedBox(height: 16.h),
@ -181,7 +189,9 @@ class _WalletPaymentConfirmPageState extends State<WalletPaymentConfirmPage> {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
LocaleKeys.totalAmountToPay.tr(context: context).toText16(isBold: true),
Utils.getPaymentAmountWithSymbol(habibWalletVM.walletRechargeAmount.toString().toText24(isBold: true), AppColors.blackColor, 15.h, isSaudiCurrency: true),
Utils.getPaymentAmountWithSymbol(
NumberFormat.decimalPattern().format(habibWalletVM.walletRechargeAmount).toString().toText24(isBold: true, isEnglishOnly: true), AppColors.blackColor, 15.h,
isSaudiCurrency: true),
],
).paddingSymmetrical(24.h, 0.h),
SizedBox(height: 12.h),

@ -1,6 +1,7 @@
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/enums.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
@ -57,7 +58,9 @@ class _HealthCalculatorsPageState extends State<HealthCalculatorsPage> {
SizedBox(
width: 12.w,
),
Utils.buildSvgWithAssets(icon: AppAssets.arrowRight, width: 24.w, height: 24.h, fit: BoxFit.contain, iconColor: AppColors.textColor),
Transform.flip(
flipX: getIt.get<AppState>().isArabic(),
child: Utils.buildSvgWithAssets(icon: AppAssets.arrowRight, width: 24.w, height: 24.h, fit: BoxFit.contain, iconColor: AppColors.textColor)),
],
).paddingAll(16.w))
.onPress(() {
@ -86,7 +89,9 @@ class _HealthCalculatorsPageState extends State<HealthCalculatorsPage> {
),
),
SizedBox(width: 12.w),
Utils.buildSvgWithAssets(icon: AppAssets.arrowRight, width: 24.w, height: 24.h, fit: BoxFit.contain, iconColor: AppColors.textColor),
Transform.flip(
flipX: getIt.get<AppState>().isArabic(),
child: Utils.buildSvgWithAssets(icon: AppAssets.arrowRight, width: 24.w, height: 24.h, fit: BoxFit.contain, iconColor: AppColors.textColor)),
],
).paddingAll(16.w))
.onPress(() {

@ -2,6 +2,8 @@ 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/core/app_state.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:hmg_patient_app_new/core/enums.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/extensions/route_extensions.dart';
@ -56,12 +58,15 @@ Widget buildHealthTrackerCard({
),
),
SizedBox(width: 12.w),
Utils.buildSvgWithAssets(
icon: AppAssets.arrowRight,
width: 24.w,
height: 24.h,
fit: BoxFit.contain,
iconColor: AppColors.textColor,
Transform.flip(
flipX: getIt.get<AppState>().isArabic(),
child: Utils.buildSvgWithAssets(
icon: AppAssets.arrowRight,
width: 24.w,
height: 24.h,
fit: BoxFit.contain,
iconColor: AppColors.textColor,
),
),
],
).paddingAll(16.w),

@ -440,6 +440,7 @@ class ServicesPage extends StatelessWidget {
),
SizedBox(height: 24.h),
getIt.get<AppState>().isAuthenticated ? Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.personalServices.tr().toText18(weight: FontWeight.w600).paddingSymmetrical(24.w, 0),
SizedBox(height: 16.h),
@ -470,7 +471,7 @@ class ServicesPage extends StatelessWidget {
Spacer(),
getIt.get<AppState>().isAuthenticated
? Consumer<HabibWalletViewModel>(builder: (context, habibWalletVM, child) {
return Utils.getPaymentAmountWithSymbol2(habibWalletVM.habibWalletAmount, isExpanded: false)
return Utils.getPaymentAmountWithSymbol2(num.parse(NumberFormat.decimalPattern().format(habibWalletVM.habibWalletAmount)), isExpanded: false)
.toShimmer2(isShow: habibWalletVM.isWalletAmountLoading, radius: 12.r, width: 80.w, height: 24.h);
})
: LocaleKeys.loginToViewWalletBalance.tr().toText12(fontWeight: FontWeight.w500, maxLine: 2),

@ -199,6 +199,7 @@ class _LandingPageState extends State<LandingPage> {
Navigator.of(context).push(
CustomPageRoute(
direction: AxisDirection.down,
page: FamilyMedicalScreen(),
),
);
@ -234,8 +235,8 @@ class _LandingPageState extends State<LandingPage> {
mainAxisSize: MainAxisSize.min,
spacing: 18.h,
children: [
Stack(children: [
if (appState.isAuthenticated)
Stack(clipBehavior: Clip.none, children: [
if (appState.isAuthenticated)
Utils.buildSvgWithAssets(icon: AppAssets.bell, height: 24.h, width: 24.h).onPress(() async {
if (appState.isAuthenticated) {
notificationsViewModel.setNotificationStatusID(2);
@ -252,22 +253,22 @@ class _LandingPageState extends State<LandingPage> {
}),
(appState.isAuthenticated && (int.parse(todoSectionVM.notificationsCount ?? "0") > 0))
? Positioned(
right: 0,
top: 0,
right: appState.isArabic() ? 8.w : -8.w,
top: -8.h,
// left: 4.h,
// bottom: 4.h,
child: Container(
width: 8.w,
height: 8.h,
padding: EdgeInsets.all(4),
width: 18.w,
height: 18.h,
padding: EdgeInsets.all(2),
decoration: BoxDecoration(
color: AppColors.primaryRedColor,
borderRadius: BorderRadius.circular(20.r),
),
child: Text(
"",
todoSectionVM.notificationsCount.toString(),
style: TextStyle(
color: Colors.white,
fontSize: 8.f,
),
color: Colors.white, fontFamily: "Poppins", fontSize: 10.f, fontWeight: FontWeight.w500),
textAlign: TextAlign.center,
),
),

@ -23,51 +23,67 @@ class ServiceInfoPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CollapsingListView(
title: "",
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
return Scaffold(
backgroundColor: AppColors.bgScaffoldColor,
body: Column(
children: [
AppCustomChipWidget(
richText: serviceName.toText14(color: AppColors.infoColor, weight: FontWeight.w500),
backgroundColor: AppColors.infoColor.withAlpha(50),
textColor: AppColors.infoColor,
).paddingSymmetrical(24.h, 0.h),
SizedBox(height: 24.h),
serviceHeader.toText28(isBold: true, height: 1.4).paddingSymmetrical(24.h, 0.h),
SizedBox(height: 24.h),
serviceDescription.toText14(weight: FontWeight.w500, color: AppColors.greyTextColor).paddingSymmetrical(24.h, 0.h),
SizedBox(height: 24.h),
CustomButton(
text: LocaleKeys.login.tr(context: context),
onPressed: () {
getIt<AuthenticationViewModel>().onLoginPressed();
},
backgroundColor: AppColors.secondaryLightRedColor,
borderColor: AppColors.secondaryLightRedColor,
textColor: AppColors.primaryRedColor,
fontSize: 16.f,
fontWeight: FontWeight.w500,
borderRadius: 12.r,
padding: EdgeInsets.symmetric(horizontal: 10.w),
height: 40.h,
icon: AppAssets.login1,
iconColor: AppColors.primaryRedColor,
iconSize: 18.h,
).paddingSymmetrical(24.h, 0.h),
SizedBox(height: 36.h),
ClipRRect(
borderRadius: BorderRadius.circular(24.r),
child: Transform.flip(
flipX: getIt.get<AppState>().isArabic(),
child: Image.asset(
serviceImage,
fit: BoxFit.fitHeight,
height: 480.h,
width: 520.w,
Expanded(
child: CollapsingListView(
title: "",
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ClipRRect(
borderRadius: BorderRadius.circular(24.r),
child: Transform.flip(
flipX: getIt.get<AppState>().isArabic(),
child: Image.asset(
serviceImage,
fit: BoxFit.fitHeight,
// height: 480.h,
// width: 520.w,
),
),
).paddingSymmetrical(24.h, 0.h),
SizedBox(height: 32.h),
AppCustomChipWidget(
richText: serviceName.toText14(color: AppColors.infoColor, weight: FontWeight.w500),
backgroundColor: AppColors.infoColor.withAlpha(50),
textColor: AppColors.infoColor,
).paddingSymmetrical(24.h, 0.h),
SizedBox(height: 24.h),
serviceHeader.toText28(isBold: true, height: 1.4).paddingSymmetrical(24.h, 0.h),
SizedBox(height: 24.h),
serviceDescription.toText14(weight: FontWeight.w500, color: AppColors.greyTextColor).paddingSymmetrical(24.h, 0.h),
SizedBox(height: 24.h),
],
),
),
),
Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 24.r,
hasShadow: true,
),
child: CustomButton(
text: LocaleKeys.login.tr(context: context),
onPressed: () {
getIt<AuthenticationViewModel>().onLoginPressed();
},
backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedColor,
textColor: AppColors.whiteColor,
fontSize: 16.f,
fontWeight: FontWeight.w500,
borderRadius: 12.r,
padding: EdgeInsets.symmetric(horizontal: 10.w),
height: 56.h,
icon: AppAssets.login1,
iconColor: AppColors.whiteColor,
iconSize: 18.h,
).paddingSymmetrical(24.h, 24.h),
)
],
),
);

@ -87,7 +87,8 @@ class HabibWalletCard extends StatelessWidget {
fit: BoxFit.contain,
),
SizedBox(width: 8.h),
habibWalletVM.habibWalletAmount
NumberFormat.decimalPattern()
.format(habibWalletVM.habibWalletAmount)
.toString()
.toText32(isBold: true, isEnglishOnly: true)
.toShimmer2(isShow: habibWalletVM.isWalletAmountLoading, radius: 12.h, width: 80.h, height: 40.h),

@ -45,6 +45,7 @@ class WelcomeWidget extends StatelessWidget {
getIt.get<ProfileSettingsViewModel>().getProfileSettings();
Navigator.of(context).push(
CustomPageRoute(
direction: getIt.get<AppState>().isArabic() ? AxisDirection.right : AxisDirection.left,
page: ProfileSettings(),
),
);

@ -16,6 +16,8 @@ import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart';
import 'package:provider/provider.dart';
import 'dart:ui' as ui;
class InsuranceApprovalDetailsPage extends StatelessWidget {
InsuranceApprovalDetailsPage({super.key, required this.insuranceApprovalResponseModel});
@ -36,7 +38,7 @@ class InsuranceApprovalDetailsPage extends StatelessWidget {
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 24.h,
hasShadow: true,
hasShadow: false,
),
child: Padding(
padding: EdgeInsets.all(14.h),
@ -84,21 +86,42 @@ class InsuranceApprovalDetailsPage extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
(insuranceApprovalResponseModel.doctorName!).toText16(isBold: true),
SizedBox(height: 8.h),
Wrap(
direction: Axis.horizontal,
spacing: 3.h,
runSpacing: 4.h,
children: [
AppCustomChipWidget(labelText: insuranceApprovalResponseModel.clinicName!),
AppCustomChipWidget(labelText: "${LocaleKeys.approvalNo.tr(context: context)} ${insuranceApprovalResponseModel.approvalNo}"),
AppCustomChipWidget(labelText: "${LocaleKeys.unusedCount.tr(context: context)} ${insuranceApprovalResponseModel.unUsedCount}"),
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}"),
AppCustomChipWidget(
labelText:
"${LocaleKeys.receiptOn.tr(context: context)} ${DateUtil.formatDateToDate(DateUtil.convertStringToDate(insuranceApprovalResponseModel.receiptOn), false)}"),
richText: Row(
mainAxisSize: MainAxisSize.min,
children: [
"${LocaleKeys.receiptOn.tr(context: context)} ".toText10(),
Directionality(
textDirection: ui.TextDirection.ltr,
child: DateUtil.formatDateToDate(DateUtil.convertStringToDate(insuranceApprovalResponseModel.receiptOn), false).toText10(isEnglishOnly: true)),
],
),
isEnglishOnly: true,
),
AppCustomChipWidget(
labelText:
"${LocaleKeys.expiryOn.tr(context: context)} ${DateUtil.formatDateToDate(DateUtil.convertStringToDate(insuranceApprovalResponseModel.expiryDate), false)}"),
richText: Row(
mainAxisSize: MainAxisSize.min,
children: [
"${LocaleKeys.expiryOn.tr(context: context)} ".toText10(),
Directionality(
textDirection: ui.TextDirection.ltr,
child: DateUtil.formatDateToDate(DateUtil.convertStringToDate(insuranceApprovalResponseModel.expiryDate), false).toText10(isEnglishOnly: true)),
],
),
isEnglishOnly: true,
),
],
),
],
@ -115,7 +138,7 @@ class InsuranceApprovalDetailsPage extends StatelessWidget {
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 24.h,
hasShadow: true,
hasShadow: false,
),
child: Padding(
padding: EdgeInsets.all(16.h),
@ -138,7 +161,6 @@ class InsuranceApprovalDetailsPage extends StatelessWidget {
child: AnimatedContainer(
duration: Duration(milliseconds: 300),
curve: Curves.easeInOut,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [

@ -15,6 +15,8 @@ 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 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'dart:ui' as ui;
class InsuranceApprovalCard extends StatelessWidget {
InsuranceApprovalCard({super.key, required this.insuranceApprovalResponseModel, required this.isLoading, required this.appState});
@ -88,6 +90,7 @@ class InsuranceApprovalCard extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
(isLoading ? "John Smith" : insuranceApprovalResponseModel.doctorName!).toText16(isBold: true).toShimmer2(isShow: isLoading),
SizedBox(height: 8.h),
Wrap(
direction: Axis.horizontal,
spacing: 3.h,
@ -98,14 +101,17 @@ class InsuranceApprovalCard extends StatelessWidget {
// textColor: insuranceApprovalResponseModel.status == 9 ? AppColors.successColor : AppColors.primaryRedColor,
// ).toShimmer2(isShow: isLoading),
AppCustomChipWidget(labelText: isLoading ? "Cardiology" : insuranceApprovalResponseModel.clinicName!).toShimmer2(isShow: isLoading),
AppCustomChipWidget(
icon: AppAssets.doctor_calendar_icon,
labelText: isLoading ? "Cardiology" : DateUtil.formatDateToDate(DateUtil.convertStringToDate(insuranceApprovalResponseModel.submitOn), false))
.toShimmer2(isShow: isLoading),
Directionality(
textDirection: ui.TextDirection.ltr,
child: AppCustomChipWidget(
icon: AppAssets.doctor_calendar_icon,
labelText: isLoading ? "Cardiology" : DateUtil.formatDateToDate(DateUtil.convertStringToDate(insuranceApprovalResponseModel.submitOn), false), isEnglishOnly: true,)
.toShimmer2(isShow: isLoading),
),
isLoading
? SizedBox.shrink()
: AppCustomChipWidget(
labelText: isLoading ? LocaleKeys.approvalNo.tr(context: context) : "${LocaleKeys.approvalNo.tr(context: context)} ${insuranceApprovalResponseModel.approvalNo}")
labelText: isLoading ? LocaleKeys.approvalNo.tr(context: context) : "${LocaleKeys.approvalNo.tr(context: context)} ${insuranceApprovalResponseModel.approvalNo}", isEnglishOnly: true,)
.toShimmer2(isShow: isLoading),
],
),

@ -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';
@ -58,7 +59,7 @@ class PatientInsuranceCardUpdateCard extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
insuranceViewModel.patientInsuranceUpdateResponseModel!.memberName!.toText16(weight: FontWeight.w600),
"Policy: ${insuranceViewModel.patientInsuranceUpdateResponseModel!.policyNumber}".toText12(isBold: true, color: AppColors.lightGrayColor),
LocaleKeys.policyNumberInsurancePage.tr(namedArgs: {'number': insuranceViewModel.patientInsuranceUpdateResponseModel!.policyNumber.toString()}).toText12(isBold: true, color: AppColors.lightGrayColor, isEnglishOnly: true),
SizedBox(height: 8.h),
Row(
children: [
@ -86,9 +87,10 @@ class PatientInsuranceCardUpdateCard extends StatelessWidget {
icon: AppAssets.doctor_calendar_icon,
labelText:
"${LocaleKeys.expiryOn.tr(context: context)} ${DateUtil.formatDateToDate(DateTime.parse(insuranceViewModel.patientInsuranceUpdateResponseModel!.effectiveTo!), false)}",
isEnglishOnly: true,
),
AppCustomChipWidget(
labelText: "Member ID: ${insuranceViewModel.patientInsuranceUpdateResponseModel!.memberID!}",
labelText: "Member ID: ${insuranceViewModel.patientInsuranceUpdateResponseModel!.memberID!}", isEnglishOnly: true,
),
],
),
@ -121,17 +123,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<DialogService>().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);
// });

@ -54,11 +54,12 @@ class PatientInsuranceCard extends StatelessWidget {
SizedBox(
width: MediaQuery.of(context).size.width * 0.4,
child: "${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}".toText18(isBold: true, textOverflow: TextOverflow.clip, isEnglishOnly: true)),
Row(
children: [
"${LocaleKeys.policyNumber.tr(context: context)}${insuranceCardDetailsModel.insurancePolicyNo}".toText12(isBold: true, color: AppColors.lightGrayColor),
],
),
LocaleKeys.policyNumberInsurancePage.tr(namedArgs: {'number': insuranceCardDetailsModel.insurancePolicyNo.toString()}).toText12(isBold: true, color: AppColors.lightGrayColor, isEnglishOnly: true),
// Row(
// children: [
// "${LocaleKeys.policyNumber.tr(context: context)}${insuranceCardDetailsModel.insurancePolicyNo}".toText12(isBold: true, color: AppColors.lightGrayColor),
// ],
// ),
],
),
isShowButtons ? AppCustomChipWidget(

@ -199,11 +199,12 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
],
),
SizedBox(width: 4.h),
Utils.buildSvgWithAssets(icon: AppAssets.arrowRight, height: 22.h, width: 22.w)
Transform.flip(flipX: appState.isArabic(), child: Utils.buildSvgWithAssets(icon: AppAssets.arrowRight, height: 22.h, width: 22.w))
],
).onPress(() {
Navigator.of(context).push(
CustomPageRoute(
direction: AxisDirection.down,
page: FamilyMedicalScreen(),
),
);

@ -43,6 +43,7 @@ class _FamilyMedicalScreenState extends State<FamilyMedicalScreen> {
AppState appState = getIt.get<AppState>();
return CollapsingListView(
isClose: true,
title: LocaleKeys.familyTitle.tr(context: context),
bottomChild: appState.getAuthenticatedUser()!.isParentUser!
? Container(

@ -20,6 +20,8 @@ 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';
import 'dart:ui' as ui;
class MyInvoicesDetailsPage extends StatefulWidget {
GetInvoiceDetailsResponseModel getInvoiceDetailsResponseModel;
GetInvoicesListResponseModel getInvoicesListResponseModel;
@ -147,7 +149,7 @@ class _MyInvoicesDetailsPageState extends State<MyInvoicesDetailsPage> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
(getIt<AppState>().isArabic() ? widget.getInvoiceDetailsResponseModel.doctorNameN! : widget.getInvoiceDetailsResponseModel.doctorName!).toText16(isBold: true),
(getIt<AppState>().isArabic() ? widget.getInvoiceDetailsResponseModel.doctorNameN ?? LocaleKeys.doctor.tr(context: context) : widget.getInvoiceDetailsResponseModel.doctorName!).toText16(isBold: true),
SizedBox(height: 8.h),
Wrap(
direction: Axis.horizontal,
@ -155,23 +157,28 @@ class _MyInvoicesDetailsPageState extends State<MyInvoicesDetailsPage> {
runSpacing: 6.h,
children: [
AppCustomChipWidget(
labelText: "${LocaleKeys.invoiceNo}: ${widget.getInvoiceDetailsResponseModel.invoiceNo!}",
labelText: "${LocaleKeys.invoiceNo.tr(context: context)}: ${widget.getInvoiceDetailsResponseModel.invoiceNo!}",
labelPadding: EdgeInsetsDirectional.only(start: 6.w, end: 6.w),
isEnglishOnly: true,
),
AppCustomChipWidget(
labelText: (widget.getInvoiceDetailsResponseModel.clinicDescription!.length > 15
labelText: ((getIt<AppState>().isArabic() ? widget.getInvoiceDetailsResponseModel.clinicDescriptionN : widget.getInvoiceDetailsResponseModel.clinicDescription ?? "")!.length > 15
? '${widget.getInvoiceDetailsResponseModel.clinicDescription!.substring(0, 12)}...'
: widget.getInvoiceDetailsResponseModel.clinicDescription!),
: getIt<AppState>().isArabic() ? widget.getInvoiceDetailsResponseModel.clinicDescriptionN : widget.getInvoiceDetailsResponseModel.clinicDescription ?? ""),
labelPadding: EdgeInsetsDirectional.only(start: 4.w, end: 4.w),
),
AppCustomChipWidget(
labelText: widget.getInvoiceDetailsResponseModel.projectName!,
labelPadding: EdgeInsetsDirectional.only(start: 6.w, end: 6.w),
),
AppCustomChipWidget(
labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: 6.w),
icon: AppAssets.doctor_calendar_icon,
labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(widget.getInvoiceDetailsResponseModel.appointmentDate), false),
Directionality(
textDirection: ui.TextDirection.ltr,
child: AppCustomChipWidget(
labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: 6.w),
icon: AppAssets.doctor_calendar_icon,
labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(widget.getInvoiceDetailsResponseModel.appointmentDate), false),
isEnglishOnly: true,
),
),
],
),
@ -196,12 +203,12 @@ class _MyInvoicesDetailsPageState extends State<MyInvoicesDetailsPage> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Insurance Details".toText16(isBold: true),
LocaleKeys.insurance.tr(context: context).toText16(isBold: true),
SizedBox(height: 16.h),
widget.getInvoiceDetailsResponseModel.groupName!.toText14(isBold: true),
(getIt<AppState>().isArabic() ? widget.getInvoiceDetailsResponseModel.groupNameN : widget.getInvoiceDetailsResponseModel.groupName)!.toText14(isBold: true),
Row(
children: [
Expanded(child: widget.getInvoiceDetailsResponseModel.companyName!.toText14(isBold: true)),
Expanded(child: (widget.getInvoiceDetailsResponseModel.companyName ?? "").toText14(isBold: true)),
],
),
SizedBox(height: 12.h),
@ -210,6 +217,7 @@ class _MyInvoicesDetailsPageState extends State<MyInvoicesDetailsPage> {
AppCustomChipWidget(
labelText: "Insurance ID: ${widget.getInvoiceDetailsResponseModel.insuranceID ?? "-"}",
labelPadding: EdgeInsetsDirectional.only(start: 6.w, end: 6.w),
isEnglishOnly: true,
),
],
),
@ -254,9 +262,9 @@ class _MyInvoicesDetailsPageState extends State<MyInvoicesDetailsPage> {
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)),
Expanded(flex: 1, child: '${consultation.quantity ?? '-'}'.toText12(fontWeight: FontWeight.w500, isCenter: true, isEnglishOnly: true)),
Expanded(flex: 2, child: (NumberFormat.decimalPattern().format(consultation.price) ?? '-').toText12(fontWeight: FontWeight.w500, isCenter: true, isEnglishOnly: true)),
Expanded(flex: 2, child: (NumberFormat.decimalPattern().format(consultation.total) ?? '-').toText12(fontWeight: FontWeight.w500, isCenter: true, isEnglishOnly: true)),
],
),
),
@ -290,7 +298,8 @@ class _MyInvoicesDetailsPageState extends State<MyInvoicesDetailsPage> {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
LocaleKeys.amountBeforeTax.tr(context: context).toText14(isBold: true),
Utils.getPaymentAmountWithSymbol(widget.getInvoiceDetailsResponseModel.listConsultation!.first.totalShare.toString().toText16(isBold: true), AppColors.blackColor, 13,
Utils.getPaymentAmountWithSymbol(
NumberFormat.decimalPattern().format(widget.getInvoiceDetailsResponseModel.listConsultation!.first.totalShare).toString().toText16(isBold: true, isEnglishOnly: true), AppColors.blackColor, 13,
isSaudiCurrency: true),
],
).paddingSymmetrical(24.h, 0.h),
@ -299,7 +308,12 @@ class _MyInvoicesDetailsPageState extends State<MyInvoicesDetailsPage> {
children: [
LocaleKeys.vat15.tr(context: context).toText14(isBold: true, color: AppColors.greyTextColor),
Utils.getPaymentAmountWithSymbol(
widget.getInvoiceDetailsResponseModel.listConsultation!.first.totalVATAmount!.toString().toText14(isBold: true, color: AppColors.greyTextColor), AppColors.greyTextColor, 13,
NumberFormat.decimalPattern()
.format(widget.getInvoiceDetailsResponseModel.listConsultation!.first.totalVATAmount!)
.toString()
.toText14(isBold: true, color: AppColors.greyTextColor, isEnglishOnly: true),
AppColors.greyTextColor,
13,
isSaudiCurrency: true),
],
).paddingSymmetrical(24.h, 0.h),
@ -308,7 +322,11 @@ class _MyInvoicesDetailsPageState extends State<MyInvoicesDetailsPage> {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
LocaleKeys.discount.tr(context: context).toText14(isBold: true),
Utils.getPaymentAmountWithSymbol(widget.getInvoiceDetailsResponseModel.listConsultation!.first.discountAmount!.toString().toText14(isBold: true, color: AppColors.primaryRedColor),
Utils.getPaymentAmountWithSymbol(
NumberFormat.decimalPattern()
.format(widget.getInvoiceDetailsResponseModel.listConsultation!.first.discountAmount!)
.toString()
.toText14(isBold: true, color: AppColors.primaryRedColor, isEnglishOnly: true),
AppColors.primaryRedColor, 13,
isSaudiCurrency: true),
],
@ -318,7 +336,9 @@ class _MyInvoicesDetailsPageState extends State<MyInvoicesDetailsPage> {
children: [
LocaleKeys.paid.tr(context: context).toText14(isBold: true),
Utils.getPaymentAmountWithSymbol(
widget.getInvoiceDetailsResponseModel.listConsultation!.first.grandTotal!.toString().toText14(isBold: true, color: AppColors.textColor), AppColors.textColor, 13,
NumberFormat.decimalPattern().format(widget.getInvoiceDetailsResponseModel.listConsultation!.first.grandTotal!).toString().toText14(isBold: true, color: AppColors.textColor, isEnglishOnly: true),
AppColors.textColor,
13,
isSaudiCurrency: true),
],
).paddingSymmetrical(24.h, 0.h),

@ -14,6 +14,8 @@ 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 'dart:ui' as ui;
class InvoiceListCard extends StatelessWidget {
final GetInvoicesListResponseModel getInvoicesListResponseModel;
Function? onTap;
@ -94,7 +96,7 @@ class InvoiceListCard extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
(getIt<AppState>().isArabic() ? getInvoicesListResponseModel.doctorNameN! : getInvoicesListResponseModel.doctorName!).toText16(isBold: true),
(getIt<AppState>().isArabic() ? getInvoicesListResponseModel.doctorNameN! : getInvoicesListResponseModel.doctorName ?? "HMG Doctor").toText16(isBold: true),
SizedBox(height: 8.h),
Wrap(
direction: Axis.horizontal,
@ -102,8 +104,9 @@ class InvoiceListCard extends StatelessWidget {
runSpacing: 6.h,
children: [
AppCustomChipWidget(
labelText: "${LocaleKeys.invoiceNo}: ${getInvoicesListResponseModel.invoiceNo!}",
labelText: "${LocaleKeys.invoiceNo.tr(context: context)}: ${getInvoicesListResponseModel.invoiceNo!}",
labelPadding: EdgeInsetsDirectional.only(start: 6.w, end: 6.w),
isEnglishOnly: true,
),
AppCustomChipWidget(
labelText:
@ -114,10 +117,14 @@ class InvoiceListCard extends StatelessWidget {
labelText: getInvoicesListResponseModel.projectName!,
labelPadding: EdgeInsetsDirectional.only(start: 6.w, end: 6.w),
),
AppCustomChipWidget(
labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: 6.w),
icon: AppAssets.doctor_calendar_icon,
labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(getInvoicesListResponseModel.appointmentDate), false),
Directionality(
textDirection: ui.TextDirection.ltr,
child: AppCustomChipWidget(
labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: 6.w),
icon: AppAssets.doctor_calendar_icon,
labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(getInvoicesListResponseModel.appointmentDate), false),
isEnglishOnly: true,
),
),
],
),

@ -2,6 +2,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
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';
@ -9,6 +10,7 @@ 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/notifications/notifications_view_model.dart';
import 'package:hmg_patient_app_new/features/todo_section/todo_section_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/presentation/notifications/notification_details_page.dart';
@ -79,7 +81,8 @@ class _NotificationsListPageState extends State<NotificationsListPage> {
child: GestureDetector(
onTap: () {
notificationsVM.markAsRead(notificationID: notificationsVM.notificationsList[index].id ?? 0);
Navigator.push(
getIt.get<TodoSectionViewModel>().getPatientDashboard();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => NotificationDetailsPage(
@ -213,18 +216,18 @@ class _NotificationsListPageState extends State<NotificationsListPage> {
}).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),
],
);
}),

@ -154,6 +154,7 @@ class _PrescriptionDetailPageState extends State<PrescriptionDetailPage> {
icon: AppAssets.rating_icon,
iconColor: AppColors.ratingColorYellow,
labelText: LocaleKeys.ratingValue.tr(namedArgs: {'rating': widget.prescriptionsResponseModel.decimalDoctorRate.toString()}, context: context),
isEnglishOnly: true,
),
AppCustomChipWidget(
labelText: widget.prescriptionsResponseModel.name ?? "",

@ -68,7 +68,7 @@ class PrescriptionItemView extends StatelessWidget {
labelText: "${LocaleKeys.dailyDoses.tr(context: context)}: ${isLoading ? "" : prescriptionVM.prescriptionDetailsList[index].doseDailyQuantity}",
).toShimmer2(isShow: isLoading),
AppCustomChipWidget(
labelText: "${LocaleKeys.days.tr(context: context)}: ${isLoading ? "" : prescriptionVM.prescriptionDetailsList[index].days}",
labelText: "${LocaleKeys.days.tr(context: context)}: ${isLoading ? "" : prescriptionVM.prescriptionDetailsList[index].days}", isEnglishOnly: true,
).toShimmer2(isShow: isLoading),
],
).paddingSymmetrical(16.h, 0.h),

@ -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';

@ -158,28 +158,64 @@ class _RadiologyResultPageState extends State<RadiologyResultPage> {
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");
}),
],
),
),
],
),

@ -1,4 +1,3 @@
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/utils/date_util.dart';
@ -8,6 +7,8 @@ import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/appointment_details_resp_model.dart';
import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart';
import 'dart:ui' as ui;
class BuildDoctorRow extends StatelessWidget {
bool isForClinic = false;
AppointmentDetails? appointmentDetails;
@ -49,6 +50,7 @@ class BuildDoctorRow extends StatelessWidget {
icon: AppAssets.ic_date_filter,
labelText:
DateUtil.formatDateToDate(DateUtil.convertStringToDate(appointmentDetails!.appointmentDate), false),
isEnglishOnly: true,
),
AppCustomChipWidget(
@ -70,10 +72,14 @@ class BuildDoctorRow extends StatelessWidget {
labelText:
appointmentDetails!.clinicName.toString(),
),
AppCustomChipWidget(
labelPadding: EdgeInsetsDirectional.only(start: -8.w, end: 6.w),
icon: AppAssets.ic_date_filter,
labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(appointmentDetails!.appointmentDate), false),
Directionality(
textDirection: ui.TextDirection.ltr,
child: AppCustomChipWidget(
labelPadding: EdgeInsetsDirectional.only(start: -8.w, end: 6.w),
icon: AppAssets.ic_date_filter,
labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(appointmentDetails!.appointmentDate), false),
isEnglishOnly: true,
),
),
],
),

@ -175,9 +175,13 @@ class _UserInfoSelectionPageState extends State<UserInfoSelectionPage> {
int? displayAge = viewModel.selectedAge ?? userAgeFromDOB;
String ageText = displayAge != null ? "$displayAge ${LocaleKeys.years.tr(context: context)}" : LocaleKeys.notSet.tr(context: context);
String heightText = viewModel.selectedHeight != null ? "${viewModel.selectedHeight!.round()} ${viewModel.isHeightCm ? 'cm' : 'ft'}" : LocaleKeys.notSet.tr(context: context);
String heightText = (viewModel.selectedHeight != null && viewModel.selectedHeight != 0)
? "${viewModel.selectedHeight!.round()} ${viewModel.isHeightCm ? 'cm' : 'ft'}"
: LocaleKeys.notSet.tr(context: context);
String weightText = viewModel.selectedWeight != null ? "${viewModel.selectedWeight!.round()} ${viewModel.isWeightKg ? 'kg' : 'lbs'}" : LocaleKeys.notSet.tr(context: context);
String weightText = (viewModel.selectedWeight != null && viewModel.selectedWeight != 0)
? "${viewModel.selectedWeight!.round()} ${viewModel.isWeightKg ? 'kg' : 'lbs'}"
: LocaleKeys.notSet.tr(context: context);
return Column(
children: [

@ -149,6 +149,7 @@ class _ThreeColumnDatePickerState extends State<ThreeColumnDatePicker> {
fontWeight: selected ? FontWeight.w600 : FontWeight.w500,
color: selected ? AppColors.textColor : AppColors.greyTextColor.withValues(alpha: 0.9),
height: 1.0,
fontFamily: "Poppins",
letterSpacing: selected ? -0.02 * 30 : -0.02 * 18,
),
);

@ -35,7 +35,7 @@ class AncillaryOrderPaymentPage extends StatefulWidget {
final int orderNo;
final int projectID;
final List<AncillaryOrderProcDetail> selectedProcedures;
final double totalAmount;
final num totalAmount;
const AncillaryOrderPaymentPage({
super.key,

@ -24,6 +24,8 @@ import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:provider/provider.dart';
import 'dart:ui' as ui;
class AncillaryOrderDetailsList extends StatefulWidget {
final int appointmentNoVida;
final int orderNo;
@ -114,12 +116,13 @@ class _AncillaryOrderDetailsListState extends State<AncillaryOrderDetailsList> {
}
}
double _getTotalAmount() {
double total = 0.0;
num _getTotalAmount() {
num total = 0.0;
for (var proc in selectedProcedures) {
total += (proc.patientShareWithTax ?? 0);
}
return total;
// return 1234.50;
}
@override
@ -253,8 +256,9 @@ class _AncillaryOrderDetailsListState extends State<AncillaryOrderDetailsList> {
children: [
AppCustomChipWidget(
// icon: AppAssets.file_icon,
labelText: "MRN: ${patientMRN ?? 'N/A'}",
labelText: "${LocaleKeys.fileno.tr(context: context)}: ${patientMRN ?? 'N/A'}",
iconSize: 12.w,
isEnglishOnly: true,
),
// National ID
@ -263,20 +267,23 @@ class _AncillaryOrderDetailsListState extends State<AncillaryOrderDetailsList> {
// icon: AppAssets.card_user,
labelText: "ID: $nationalID",
iconSize: 12.w,
isEnglishOnly: true,
),
// Appointment Number
if (orderData.appointmentNo != null)
AppCustomChipWidget(
// icon: AppAssets.calendar,
labelText: "Appt #: ${orderData.appointmentNo}",
labelText: "${LocaleKeys.appointment.tr(context: context)}: ${orderData.appointmentNo}",
iconSize: 12.w,
isEnglishOnly: true,
),
// Order Number
if (orderData.ancillaryOrderProcDetailsList?.firstOrNull?.orderNo != null)
AppCustomChipWidget(
labelText: "Order #: ${orderData.ancillaryOrderProcDetailsList!.first.orderNo}",
isEnglishOnly: true,
),
// Blood Group
@ -297,12 +304,14 @@ class _AncillaryOrderDetailsListState extends State<AncillaryOrderDetailsList> {
backgroundColor: AppColors.successColor.withValues(alpha: 0.15),
iconSize: 12.w,
labelPadding: EdgeInsetsDirectional.only(start: -6.w, end: 8.w),
isEnglishOnly: true,
),
// Policy Number
if (orderData.insurancePolicyNo != null && orderData.insurancePolicyNo!.isNotEmpty)
AppCustomChipWidget(
labelText: "Policy: ${orderData.insurancePolicyNo}",
labelText: "${LocaleKeys.policyNumber.tr(context: context)}: ${orderData.insurancePolicyNo}",
isEnglishOnly: true,
),
AppCustomChipWidget(
@ -317,8 +326,12 @@ class _AncillaryOrderDetailsListState extends State<AncillaryOrderDetailsList> {
labelText: "Clinic: ${orderData.clinicName!}",
),
if (orderData.clinicName != null && orderData.clinicName!.isNotEmpty)
AppCustomChipWidget(
labelText: "Date: ${DateFormat('MMM dd, yyyy').format(orderData.appointmentDate!)}",
Directionality(
textDirection: ui.TextDirection.ltr,
child: AppCustomChipWidget(
labelText: "${LocaleKeys.date.tr(context: context)}: ${DateFormat('MMM dd yyyy').format(orderData.appointmentDate!)}",
isEnglishOnly: true,
),
),
],
),
@ -557,7 +570,7 @@ class _AncillaryOrderDetailsListState extends State<AncillaryOrderDetailsList> {
Row(
children: [
Utils.getPaymentAmountWithSymbol(
(procedure.patientShare ?? 0).toStringAsFixed(2).toText13(weight: FontWeight.w600),
(procedure.patientShare ?? 0).toStringAsFixed(2).toText14(weight: FontWeight.w600, isEnglishOnly: true),
AppColors.textColorLight,
13,
isSaudiCurrency: true,
@ -576,7 +589,7 @@ class _AncillaryOrderDetailsListState extends State<AncillaryOrderDetailsList> {
Row(
children: [
Utils.getPaymentAmountWithSymbol(
(procedure.patientTaxAmount ?? 0).toStringAsFixed(2).toText13(weight: FontWeight.w600),
(procedure.patientTaxAmount ?? 0).toStringAsFixed(2).toText12(fontWeight: FontWeight.w600, isEnglishOnly: true),
AppColors.textColorLight,
13,
isSaudiCurrency: true,
@ -595,7 +608,7 @@ class _AncillaryOrderDetailsListState extends State<AncillaryOrderDetailsList> {
Row(
children: [
Utils.getPaymentAmountWithSymbol(
(procedure.patientShareWithTax ?? 0).toStringAsFixed(2).toText13(weight: FontWeight.w600),
(procedure.patientShareWithTax ?? 0).toStringAsFixed(2).toText12(fontWeight: FontWeight.w600, isEnglishOnly: true),
AppColors.textColorLight,
13,
isSaudiCurrency: true,
@ -646,7 +659,7 @@ class _AncillaryOrderDetailsListState extends State<AncillaryOrderDetailsList> {
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Utils.getPaymentAmountWithSymbol(_getTotalAmount().toStringAsFixed(2).toText24(isBold: true), AppColors.blackColor, 17, isSaudiCurrency: true),
Utils.getPaymentAmountWithSymbol(NumberFormat.decimalPattern().format(_getTotalAmount()).toText24(isBold: true, isEnglishOnly: true), AppColors.blackColor, 17, isSaudiCurrency: true),
],
),
],

@ -15,6 +15,8 @@ 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 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'dart:ui' as ui;
class AncillaryOrdersList extends StatelessWidget {
final List<AncillaryOrderItem> orders;
final Function(AncillaryOrderItem order)? onCheckIn;
@ -173,20 +175,26 @@ class AncillaryOrderCard extends StatelessWidget {
if (order.orderNo != null || isLoading)
AppCustomChipWidget(
// icon: AppAssets.calendar,
labelText: "${LocaleKeys.orderNumber.tr(context: context)}${order.orderNo ?? '-'}",
).toShimmer2(isShow: isLoading),
labelText: "${LocaleKeys.orderNumber.tr(context: context)}${order.orderNo ?? '-'}",
isEnglishOnly: true)
.toShimmer2(isShow: isLoading),
// Appointment Date
if (order.appointmentDate != null || isLoading)
AppCustomChipWidget(
icon: AppAssets.appointment_calendar_icon,
labelText: isLoading ? "Date: Jan 20, 2024" : DateFormat('MMM dd, yyyy').format(order.appointmentDate!),
).toShimmer2(isShow: isLoading),
Directionality(
textDirection: ui.TextDirection.ltr,
child: AppCustomChipWidget(
icon: AppAssets.appointment_calendar_icon,
labelText: isLoading ? "Date: Jan 20, 2024" : DateFormat('MMM dd, yyyy').format(order.appointmentDate!),
isEnglishOnly: true,
).toShimmer2(isShow: isLoading),
),
// Appointment Number
if (order.appointmentNo != null || isLoading)
AppCustomChipWidget(
labelText: isLoading ? "Appt# : 98765" : "Appt #: ${order.appointmentNo}",
labelText: isLoading ? "Appt# : 98765" : "${LocaleKeys.appointment.tr(context: context)}: ${order.appointmentNo}",
isEnglishOnly: true,
).toShimmer2(isShow: isLoading),
// Invoice Number

@ -16,6 +16,8 @@ import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
import 'package:hmg_patient_app_new/widgets/graph/custom_graph.dart';
import 'package:provider/provider.dart';
import 'dart:ui' as ui;
/// Which vital sign is being shown in the details screen.
enum VitalSignMetric {
bmi,
@ -139,15 +141,13 @@ class _VitalSignDetailsPageState extends State<VitalSignDetailsPage> {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
title.toText28(isBold: true, color: AppColors.textColor, letterSpacing: -1),
],
),
SizedBox(height: 8.h),
(latestDate != null
? LocaleKeys.resultOf.tr(namedArgs: {'date': latestDate.toString().split(' ').first})
: LocaleKeys.resultOfNoDate.tr(context: context))
.toText11(weight: FontWeight.w500, color: AppColors.greyTextColor),
.toText11(weight: FontWeight.w500, color: AppColors.greyTextColor, isEnglishOnly: true),
],
),
Row(
@ -430,10 +430,14 @@ class _VitalSignDetailsPageState extends State<VitalSignDetailsPage> {
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
dp.displayTime.toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500),
valueText.toText12(
color: AppColors.textColor,
fontWeight: FontWeight.w600,
dp.displayTime.toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500, isEnglishOnly: true),
Directionality(
textDirection: ui.TextDirection.ltr,
child: valueText.toText12(
color: AppColors.textColor,
fontWeight: FontWeight.w600,
isEnglishOnly: true
),
),
],
),
@ -756,7 +760,7 @@ class _VitalSignDetailsPageState extends State<VitalSignDetailsPage> {
top: 8.0,
right: isLast ? 16.h : 0,
),
child: label.toText8(fontWeight: FontWeight.w500),
child: label.toText10(weight: FontWeight.w500, isEnglishOnly: true),
);
}

@ -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();
}
}

@ -43,7 +43,7 @@ class AppColors {
// Doctor Rating Colors
static const Color ratingStarIconColor = Color(0xFFFFA726); // Orange-amber for star icons
static const Color ratingFiveStarColor = Color(0xFF4CAF50); // Green for 5 stars
static const Color ratingFiveStarColor = Color(0xFF18C273); // Green for 5 stars
static const Color ratingFourStarColor = Color(0xFF8BC34A); // Light green for 4 stars
static const Color ratingThreeStarColor = Color(0xFFC0A000); // Dark yellow/olive for 3 stars
static const Color ratingTwoStarColor = Color(0xFFD84315); // Dark orange-red for 2 stars

@ -192,7 +192,7 @@ class CustomGraph extends StatelessWidget {
return LineTooltipItem(
'${dataPoint.actualValue} ${dataPoint.unitOfMeasurement ?? ""} - ${dataPoint.displayTime}',
TextStyle(color: Colors.black, fontSize: 12.f, fontWeight: FontWeight.w500),
TextStyle(color: Colors.black, fontSize: 12.f, fontWeight: FontWeight.w500, fontFamily: "Poppins"),
);
}).toList();
},

@ -159,8 +159,8 @@ class TextInputWidget extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildLabelText(labelColor).paddingOnly(
right: (appState.getLanguageCode() == "ar" ? 10 : 0),
left: (appState.getLanguageCode() == "en" ? 10 : 0),
right: (appState.isArabic() ? 10 : 10),
left: (!appState.isArabic() ? 10 : 10),
),
Row(
children: [
@ -230,7 +230,8 @@ class TextInputWidget extends StatelessWidget {
language: appState.getLanguageCode()!,
initialDate: DateTime.now(),
showCalendarToggle: isHideSwitcher == true ? false : true,
fontFamily: appState.getLanguageCode() == "ar" ? "GESSTwo" : "Poppins",
// fontFamily: appState.getLanguageCode() == "ar" ? "GESSTwo" : "Poppins",
fontFamily: "Poppins",
okWidget: Padding(padding: EdgeInsets.only(right: 8.h), child: Utils.buildSvgWithAssets(icon: AppAssets.confirm, width: 24.h, height: 24.h)),
cancelWidget: Padding(padding: EdgeInsets.only(right: 8.h), child: Utils.buildSvgWithAssets(icon: AppAssets.cancel, iconColor: Colors.white, width: 24.h, height: 24.h)),
onCalendarTypeChanged: (bool value) {

Loading…
Cancel
Save