pull/212/head
haroon amjad 4 days ago
parent 9c51f53a4d
commit 453cfc07e1

@ -1658,5 +1658,16 @@
"doctorAddedToFavourite": "تمت إضافة إلى قائمة المفضلة",
"doctorRemovedFromFavourite": "تمت إزالة من قائمة الأطباء المفضلين",
"addNewFavorite": "إضافة مفضلة جديدة",
"favourites": "المفضلة"
"favourites": "المفضلة",
"pendingAncillaryOrders": "مدفوعات طلبات الاضافية",
"liveCarePermissions": "يتطلب لايف كير أذونات الكاميرا والميكروفون وإشعارات، يرجى السماح لها بالمتابعة.",
"containsImage": "يحتوي على صورة",
"servicesSelected": "الخدمة (الخدمات) المختارة",
"selectMedicalFileFromFamily": "اختر ملف طبي من عائلتك",
"anyFileFromHMG": "أي ملف طبي نشط من مجموعة حبيب الطبية",
"noDistance": "المسافة غير متوفرة",
"enterAmount": "يرجى إدخال المبلغ للمتابعة.",
"selectHospitalContinue": "يرجى اختيار المستشفى للمتابعة.",
"year": "سنة",
"notifyPrescription": "أبلغني قبل وقت الاستهلاك"
}

@ -1309,7 +1309,7 @@
"rejectedYourFamilyMemberRequest": "{status} your family member request",
"notAvailable": "N/A",
"selectAProfile": "Please select a profile",
"switchFamilyFile": "Switch from the below list of medical file",
"switchFamilyFile": "Switch from the below list of medical files",
"medicalFiles": "Medical Files",
"addANewFamilyMember": "Add a new family member",
"viewInvoiceDetails": "View invoice details",
@ -1650,5 +1650,16 @@
"doctorAddedToFavourite": "Added to favorites list",
"doctorRemovedFromFavourite": "Removed from favorites list",
"favourites": "Favourites",
"addNewFavorite": "Add new favourite"
"addNewFavorite": "Add new favourite",
"pendingAncillaryOrders": "Pending ancillary orders",
"liveCarePermissions": "LiveCare requires Camera, Microphone & Notifications permissions to enable virtual consultation between patient & doctor, Open app settings to allow them.",
"containsImage": "Contains Image",
"servicesSelected": "Service(s) Selected",
"selectMedicalFileFromFamily": "Select a medical file from your family",
"anyFileFromHMG": "Any active medical file from HMG",
"noDistance": "Distance not available",
"enterAmount": "Please enter amount to continue.",
"selectHospitalContinue": "Please select hospital to continue.",
"year": "Year",
"notifyPrescription": "Notify me before the consumption time"
}

@ -24,7 +24,7 @@ extension CapExtension on String {
extension EmailValidator on String {
Widget get toWidget => Text(this);
Widget toText8({Color? color, FontWeight? fontWeight, bool isBold = false, int? maxlines, FontStyle? fontStyle, TextOverflow? textOverflow}) => Text(
Widget toText8({bool isEnglishOnly = false, Color? color, FontWeight? fontWeight, bool isBold = false, int? maxlines, FontStyle? fontStyle, TextOverflow? textOverflow}) => Text(
this,
maxLines: maxlines,
overflow: textOverflow,
@ -34,6 +34,7 @@ extension EmailValidator on String {
fontWeight: fontWeight ?? (isBold ? FontWeight.bold : FontWeight.normal),
color: color ?? AppColors.blackColor,
letterSpacing: 0,
fontFamily: isEnglishOnly ? "Poppins" : getIt.get<AppState>().getLanguageCode() == "ar" ? 'GESSTwo' : 'Poppins',
),
);

@ -692,6 +692,7 @@ class AuthenticationRepoImp implements AuthenticationRepo {
@override
Future<Either<Failure, GenericApiModel<dynamic>>> getPatientBloodType() async {
// Map<String, dynamic> requestBody = {"PatientType": 1, "PatientTypeID": 1, "TokenID": "@dm!n", "PatientID": 5957754};
Map<String, dynamic> requestBody = {};
try {
GenericApiModel<dynamic>? apiResponse;

@ -101,7 +101,10 @@ class AuthenticationViewModel extends ChangeNotifier {
var healthId;
int getDeviceLastLogin = 1;
bool isInitialLoginNavigated = false;
Future<void> onLoginPressed() async {
setIsInitialLoginNavigated(false);
try {
LoaderBottomSheet.showLoader();
//TODO: We will remove this delay
@ -111,7 +114,7 @@ class AuthenticationViewModel extends ChangeNotifier {
if (data != null) {
await _handleExistingImeiData(data);
} else {
await _handleNewImeiRegistration();
await handleNewImeiRegistration();
}
} catch (e) {
log("Error in onLoginPressed: $e");
@ -199,6 +202,11 @@ class AuthenticationViewModel extends ChangeNotifier {
}
}
setIsInitialLoginNavigated(bool isInitialLoginNavigated) {
this.isInitialLoginNavigated = isInitialLoginNavigated;
notifyListeners();
}
void onTermAccepted() {
isTermsAccepted = !isTermsAccepted;
notifyListeners();
@ -216,7 +224,7 @@ class AuthenticationViewModel extends ChangeNotifier {
_appState.deviceToken = await Utils.getStringFromPrefs(CacheConst.pushToken);
}
Future<void> selectDeviceImei({required Function(dynamic data) onSuccess, Function(String)? onError}) async {
Future<void> selectDeviceImei({bool isNavigate = true, required Function(dynamic data) onSuccess, Function(String)? onError}) async {
// LoadingUtils.showFullScreenLoading();
// String firebaseToken = _appState.deviceToken;
String firebaseToken = await Utils.getStringFromPrefs(CacheConst.pushToken);
@ -231,7 +239,9 @@ class AuthenticationViewModel extends ChangeNotifier {
// LoadingUtils.hideFullScreenLoader();
// await _errorHandlerService.handleError(failure: failure);
LoaderBottomSheet.hideLoader();
_navigationService.pushPage(page: LoginScreen());
if (isNavigate) {
_navigationService.pushPage(page: LoginScreen());
}
},
(apiResponse) {
// LoadingUtils.hideFullScreenLoader();
@ -263,10 +273,13 @@ class AuthenticationViewModel extends ChangeNotifier {
}
}
Future<void> _handleNewImeiRegistration() async {
await selectDeviceImei(onSuccess: (dynamic respData) async {
try {
if (respData != null) {
Future<void> handleNewImeiRegistration({bool isNavigate = true}) async {
print("handleNewImeiRegistration called");
await selectDeviceImei(
isNavigate: isNavigate,
onSuccess: (dynamic respData) async {
try {
if (respData != null) {
dynamic data = await SelectDeviceByImeiRespModelElement.fromJson(respData.toJson());
_appState.setSelectDeviceByImeiRespModelElement(data);
LoaderBottomSheet.hideLoader();
@ -274,19 +287,24 @@ class AuthenticationViewModel extends ChangeNotifier {
// TODO: Navigate to SavedLogin when available
// SelectDeviceByImeiRespModelElement savedData =
// SelectDeviceByImeiRespModelElement.fromJson(respData);
_navigationService.pushPage(page: SavedLogin());
// _navigationService.pushPage(page: LoginScreen());
} else {
print("print login........");
LoaderBottomSheet.hideLoader();
_navigationService.pushPage(page: LoginScreen());
}
} catch (e) {
log("Error processing IMEI registration response: $e");
LoaderBottomSheet.hideLoader();
_navigationService.pushPage(page: LoginScreen());
}
}, onError: (String error) {
if (!isInitialLoginNavigated) {
_navigationService.pushPage(page: SavedLogin());
}
// _navigationService.pushPage(page: LoginScreen());
} else {
if (isNavigate) {
LoaderBottomSheet.hideLoader();
_navigationService.pushPage(page: LoginScreen());
}
}
} catch (e) {
if (isNavigate) {
log("Error processing IMEI registration response: $e");
LoaderBottomSheet.hideLoader();
_navigationService.pushPage(page: LoginScreen());
}
}
}, onError: (String error) {
LoaderBottomSheet.hideLoader();
_dialogService.showErrorBottomSheet(message: error, onOkPressed: () {});
});
@ -722,6 +740,7 @@ class AuthenticationViewModel extends ChangeNotifier {
}
Future<void> navigateToHomeScreen() async {
setIsInitialLoginNavigated(true);
getPatientBloodTypeNew();
Navigator.pushAndRemoveUntil(
_navigationService.navigatorKey.currentContext!,
@ -1174,7 +1193,7 @@ class AuthenticationViewModel extends ChangeNotifier {
(apiResponse) {
if (apiResponse.messageStatus == 1 && apiResponse.data != null) {
// Extract blood type from response
String? bloodType = apiResponse.data['GetPatientBloodType'];
String? bloodType = apiResponse.data['GetPatientBloodType'][0]["BloodType"];
if (bloodType != null && bloodType.isNotEmpty) {
_appState.setUserBloodGroup = bloodType;
log("Blood type updated from new API: $bloodType");

@ -334,7 +334,7 @@ class BookAppointmentsViewModel extends ChangeNotifier {
void filterDoctors(String query) {
if (query.isEmpty) {
filteredDoctorList = List.from(doctorsList);
// _groupDoctorsList();
_groupDoctorsList();
setIsNearestAppointmentSelected(isNearestAppointmentSelected);
notifyListeners();
return;

@ -848,6 +848,9 @@ class LabViewModel extends ChangeNotifier {
Future<void> getAiOverviewLabOrders({required PatientLabOrdersResponseModel labOrder, required String loadingText}) async {
// LoadingUtils.showFullScreenLoader(loadingText: "Loading and analysing your data,\nPlease be patient and let the AI do the magic. \nPlease be patient, This might take some time.");
// LoadingUtils.showFullScreenLoader(loadingText: loadingText);
isLabAIAnalysisNeedsToBeShown = true;
notifyListeners();
LoaderBottomSheet.showLoader(
loadingText: loadingText,
showCloseButton: true,
@ -875,26 +878,29 @@ class LabViewModel extends ChangeNotifier {
final result = await labRepo.getPatientAiOverViewLabOrders(results);
result.fold(
(failure) async {
LoadingUtils.hideFullScreenLoader();
LoaderBottomSheet.hideLoader();
if (isLabAIAnalysisNeedsToBeShown) {
await errorHandlerService.handleError(failure: failure);
}
},
(apiResponse) {
LoadingUtils.hideFullScreenLoader();
LoaderBottomSheet.hideLoader();
if (apiResponse.messageStatus == 2) {
} else if (apiResponse.messageStatus == 1) {
if (isLabAIAnalysisNeedsToBeShown) {
labOrdersResponseByAi = apiResponse.data;
navigationService.push(
MaterialPageRoute(builder: (_) => LabAiAnalysisDetailedPage()),
CustomPageRoute(
direction: AxisDirection.down,
page: LabAiAnalysisDetailedPage(),
),
);
}
}
},
);
LoadingUtils.hideFullScreenLoader();
// LoadingUtils.hideFullScreenLoader();
}
Future<void> getAiOverviewSingleLabResult({required String langId, required LabResult recentLabResult, required String loadingText}) async {

@ -13,13 +13,13 @@ class TodoSectionViewModel extends ChangeNotifier {
String? notificationsCount = "0";
initializeTodoSectionViewModel() async {
if (isAncillaryOrdersNeedReloading) {
patientAncillaryOrdersList.clear();
isAncillaryOrdersLoading = true;
// if (isAncillaryOrdersNeedReloading) {
patientAncillaryOrdersList.clear();
isAncillaryOrdersLoading = true;
isAncillaryDetailsProceduresLoading = true;
notificationsCount = "0";
getPatientOnlineAncillaryOrderList();
}
// }
getPatientDashboard();
}
@ -63,13 +63,14 @@ class TodoSectionViewModel extends ChangeNotifier {
}
Future<void> getPatientOnlineAncillaryOrderList({Function(dynamic)? onSuccess, Function(String)? onError}) async {
if (!isAncillaryOrdersNeedReloading) {
return;
}
// if (!isAncillaryOrdersNeedReloading) {
// return;
// }
patientAncillaryOrdersList.clear();
isAncillaryOrdersLoading = true;
notifyListeners();
final result = await todoSectionRepo.getOnlineAncillaryOrderList();
result.fold(

@ -1651,5 +1651,16 @@ abstract class LocaleKeys {
static const doctorRemovedFromFavourite = 'doctorRemovedFromFavourite';
static const addNewFavorite = 'addNewFavorite';
static const favourites = 'favourites';
static const pendingAncillaryOrders = 'pendingAncillaryOrders';
static const liveCarePermissions = 'liveCarePermissions';
static const containsImage = 'containsImage';
static const servicesSelected = 'servicesSelected';
static const selectMedicalFileFromFamily = 'selectMedicalFileFromFamily';
static const anyFileFromHMG = 'anyFileFromHMG';
static const noDistance = 'noDistance';
static const enterAmount = 'enterAmount';
static const selectHospitalContinue = 'selectHospitalContinue';
static const year = 'year';
static const notifyPrescription = 'notifyPrescription';
}

@ -130,7 +130,7 @@ void main() async {
Locale('ar', 'SA'),
],
path: 'assets/langs',
assetLoader: RemoteFileLoader(),
// assetLoader: RemoteFileLoader(),
fallbackLocale: Locale('en', 'US'),
child: MultiProvider(providers: <SingleChildWidget>[
ChangeNotifierProvider<LabViewModel>(

@ -874,8 +874,9 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
?
(widget.patientAppointmentHistoryResponseModel.isLiveCareAppointment! ||
widget.patientAppointmentHistoryResponseModel.isExecludeDoctor! ||
Utils.isClinicAllowedForRebook(widget.patientAppointmentHistoryResponseModel.clinicID))
? CustomButton(
!Utils.isClinicAllowedForRebook(widget.patientAppointmentHistoryResponseModel.clinicID))
? SizedBox.shrink()
: CustomButton(
text: LocaleKeys.rebookAppointment.tr(context: context),
onPressed: () {
openDoctorScheduleCalendar();
@ -892,7 +893,6 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
iconColor: Colors.white,
iconSize: 18.h,
).paddingSymmetrical(16.h, 24.h)
: SizedBox.shrink()
: CustomButton(
text: AppointmentType.getNextActionText(widget.patientAppointmentHistoryResponseModel.nextAction),
onPressed: () {

@ -191,7 +191,7 @@ class _MyAppointmentsPageState extends State<MyAppointmentsPage> {
children: [
AppCustomChipWidget(
labelText:
"${myAppointmentsVM.patientAppointmentsViewList[index].patientDoctorAppointmentList!.length} Appointments"),
"${myAppointmentsVM.patientAppointmentsViewList[index].patientDoctorAppointmentList!.length} ${LocaleKeys.appointments.tr(context: context)}", isEnglishOnly: true,),
Icon(isExpanded ? Icons.expand_less : Icons.expand_more),
],
),

@ -1,3 +1,4 @@
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';
@ -7,6 +8,7 @@ import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/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/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart';
@ -95,7 +97,7 @@ class HospitalListItem extends StatelessWidget {
child: Row(
children: [
AppCustomChipWidget(
labelText: "Distance not available",
labelText: LocaleKeys.noDistance.tr(),
textColor: AppColors.blackColor,
),
// SizedBox(

@ -66,6 +66,7 @@ class _SavedLogin extends State<SavedLogin> {
appBar: CustomAppBar(
onBackPressed: () {
Navigator.of(context).pop();
authVm.setIsInitialLoginNavigated(true);
},
onLanguageChanged: (value) {
context.setLocale(value == 'en' ? Locale('en', 'US') : Locale('ar', 'SA'));

@ -75,14 +75,20 @@ class ImmediateLiveCarePaymentDetails extends StatelessWidget {
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}".toText16(isBold: true),
"${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}".toText16(isBold: true, isEnglishOnly: true),
SizedBox(height: 8.h),
Wrap(
direction: Axis.horizontal,
spacing: 3.h,
runSpacing: 4.h,
children: [
AppCustomChipWidget(labelText: "${appState.getAuthenticatedUser()!.age} ${LocaleKeys.yearsOld.tr(context: context)}"),
AppCustomChipWidget(
richText: Row(
children: [
"${appState.getAuthenticatedUser()!.age} ".toText10(color: AppColors.blackColor, isEnglishOnly: true),
LocaleKeys.yearsOld.tr(context: context).toText10(color: AppColors.blackColor),
],
),),
AppCustomChipWidget(labelText: "${LocaleKeys.gender.tr(context: context)}: ${appState.getAuthenticatedUser()?.gender == 1 ? LocaleKeys.malE.tr(context: context) : LocaleKeys.femaleGender.tr(context: context)}"),
],
),
@ -208,7 +214,7 @@ class ImmediateLiveCarePaymentDetails extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
LocaleKeys.amountBeforeTax.tr(context: context).toText14(isBold: true),
Utils.getPaymentAmountWithSymbol(immediateLiveCareVM.liveCareImmediateAppointmentFeesList.amount!.toText16(isBold: true), AppColors.blackColor, 13,
Utils.getPaymentAmountWithSymbol(immediateLiveCareVM.liveCareImmediateAppointmentFeesList.amount!.toText16(isBold: true, isEnglishOnly: true), AppColors.blackColor, 13,
isSaudiCurrency: immediateLiveCareVM.liveCareImmediateAppointmentFeesList.currency!.toLowerCase() == "sar" ||
immediateLiveCareVM.liveCareImmediateAppointmentFeesList.currency!.toLowerCase() == "ريال"),
],
@ -218,7 +224,7 @@ class ImmediateLiveCarePaymentDetails extends StatelessWidget {
children: [
LocaleKeys.vat15.tr(context: context).toText14(isBold: true, color: AppColors.greyTextColor),
Utils.getPaymentAmountWithSymbol(
immediateLiveCareVM.liveCareImmediateAppointmentFeesList.tax!.toText14(isBold: true, color: AppColors.greyTextColor), AppColors.greyTextColor, 13,
immediateLiveCareVM.liveCareImmediateAppointmentFeesList.tax!.toText14(isBold: true, color: AppColors.greyTextColor, isEnglishOnly: true), AppColors.greyTextColor, 13,
isSaudiCurrency: (immediateLiveCareVM.liveCareImmediateAppointmentFeesList.currency!.toLowerCase() == "sar" ||
immediateLiveCareVM.liveCareImmediateAppointmentFeesList.currency!.toLowerCase() == "ريال")),
],
@ -228,7 +234,7 @@ class ImmediateLiveCarePaymentDetails extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(width: 200.h, child: Utils.getPaymentMethods()),
Utils.getPaymentAmountWithSymbol(immediateLiveCareVM.liveCareImmediateAppointmentFeesList.total!.toText24(isBold: true), AppColors.blackColor, 17,
Utils.getPaymentAmountWithSymbol(immediateLiveCareVM.liveCareImmediateAppointmentFeesList.total!.toText24(isBold: true, isEnglishOnly: true), AppColors.blackColor, 17,
isSaudiCurrency: (immediateLiveCareVM.liveCareImmediateAppointmentFeesList.currency!.toLowerCase() == "sar" ||
immediateLiveCareVM.liveCareImmediateAppointmentFeesList.currency!.toLowerCase() == "ريال")),
],
@ -374,10 +380,11 @@ class ImmediateLiveCarePaymentDetails extends StatelessWidget {
final permanent = missing.where((p) => (statuses[p]?.isPermanentlyDenied ?? false) || (statuses[p]?.isRestricted ?? false)).toList();
if (permanent.isNotEmpty) {
final names = permanent.map((p) => LiveCarePermissionService.instance.friendlyName(p)).join(' and ');
final message = permanent.length == 1 ? '$names permission is permanently denied. Open app settings to allow it.' : '$names permissions are permanently denied. Open app settings to allow them.';
// final message = permanent.length == 1 ? '$names permission is permanently denied. Open app settings to allow it.' : '$names permissions are permanently denied. Open app settings to allow them.';
final message = LocaleKeys.liveCarePermissions.tr();
await LiveCarePermissionService.instance.showOpenSettingsDialog(
context,
title: "Permissions Required",
title: LocaleKeys.permissionsProfile.tr(),
message: message,
);
return false;

@ -27,10 +27,11 @@ class LiveCareClinicCard extends StatelessWidget {
GetLiveCareClinicListResponseModel liveCareClinicListResponseModel;
bool isLoading;
ImmediateLiveCareViewModel immediateLiveCareViewModel;
late AppState appState;
@override
Widget build(BuildContext context) {
AppState appState = getIt.get<AppState>();
appState = getIt.get<AppState>();
return Container(
padding: EdgeInsets.all(16.h),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
@ -219,19 +220,24 @@ class LiveCareClinicCard extends StatelessWidget {
icon: AppAssets.appointment_time_icon,
iconColor: AppColors.textColor,
labelText: subTitle.split("to").first.trim(),
isEnglishOnly: true,
),
SizedBox(width: 8.w),
Utils.buildSvgWithAssets(
icon: AppAssets.arrow_forward,
height: 24.h,
width: 24.h,
iconColor: AppColors.textColor,
Transform.flip(
flipX: appState.isArabic(),
child: Utils.buildSvgWithAssets(
icon: AppAssets.arrow_forward,
height: 24.h,
width: 24.h,
iconColor: AppColors.textColor,
),
),
SizedBox(width: 8.w),
AppCustomChipWidget(
icon: AppAssets.appointment_time_icon,
iconColor: AppColors.textColor,
labelText: subTitle.split("to")[1].trim(),
isEnglishOnly: true,
),
],
),

@ -1064,24 +1064,27 @@ 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;
}
// 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) {
regionalViewModel.setBottomSheetState(AppointmentViaRegionState.HOSPITAL_SELECTION);
bottomSheetType = RegionBottomSheetType.REGION_FOR_DENTAL_AND_LASER;
}
// if (clinic.clinicID == 253) {
// bottomSheetType = RegionBottomSheetType.REGION_FOR_DENTAL_AND_LASER;
// }
openRegionListBottomSheet(context, bottomSheetType);
}
}
@ -1122,10 +1125,19 @@ class _SelectClinicPageState extends State<SelectClinicPage> {
regionalViewModel.handleLastStepForRegion();
} else if (regionalViewModel.regionBottomSheetType == RegionBottomSheetType.FOR_CLINIIC) {
regionalViewModel.setBottomSheetState(AppointmentViaRegionState.DOCTOR_SELECTION);
regionalViewModel.handleLastStepForClinic();
var appointmentsViewModel = Provider.of<BookAppointmentsViewModel>(context, listen: false);
if (appointmentsViewModel.selectedClinic.clinicID == 253) {
appointmentsViewModel.setProjectID(regionalViewModel.selectedHospital?.patientDoctorAppointmentList!.first.iD?.toString() ?? "");
appointmentsViewModel.resetLaserData();
appointmentsViewModel.getLaserClinic();
regionalViewModel.handleLastStepForClinicForDentalAndLaser(appointmentsViewModel.selectedClinic.clinicID ?? -1);
} else {
regionalViewModel.handleLastStepForClinic();
}
} else if (regionalViewModel.regionBottomSheetType == RegionBottomSheetType.REGION_FOR_DENTAL_AND_LASER) {
var appointmentsViewModel = Provider.of<BookAppointmentsViewModel>(context, listen: false);
regionalViewModel.setBottomSheetState(AppointmentViaRegionState.DOCTOR_SELECTION);
appointmentsViewModel.setProjectID(regionalViewModel.selectedHospital?.hospitalList.first.iD?.toString() ?? "");
regionalViewModel.handleLastStepForClinicForDentalAndLaser(appointmentsViewModel.selectedClinic.clinicID ?? -1);
}
},
@ -1157,12 +1169,18 @@ class _SelectClinicPageState extends State<SelectClinicPage> {
}
}
if (bookAppointmentsViewModel.selectedClinic.clinicID == 253) {
{
bookAppointmentsViewModel.resetLaserData();
bookAppointmentsViewModel.getLaserClinic();
}
}
// if (bookAppointmentsViewModel.selectedClinic.clinicID == 253) {
// // {
// // bookAppointmentsViewModel.resetLaserData();
// // bookAppointmentsViewModel.getLaserClinic();
// // Navigator.push(
// // context,
// // CustomPageRoute(
// // page: LaserAppointment(),
// // ),
// // );
// // }
// }
bookAppointmentsViewModel.setProjectID(id);
return SizedBox.shrink();
} else {

@ -105,16 +105,17 @@ class DoctorCard extends StatelessWidget {
SizedBox(
child: (isLoading
? "Consultant Cardiologist"
: getIt.get<AppState>().isArabic()
: (getIt.get<AppState>().isArabic() && doctorsListResponseModel.specialityN != null)
? doctorsListResponseModel.specialityN!.isNotEmpty
? (doctorsListResponseModel.specialityN!.first.length > 32
? '${doctorsListResponseModel.specialityN!.first.substring(0, 32)}...'
: doctorsListResponseModel.specialityN!.first)
: ""
: doctorsListResponseModel.speciality!.isNotEmpty
: doctorsListResponseModel.speciality != null ?
doctorsListResponseModel.speciality!.isNotEmpty
? (doctorsListResponseModel.speciality!.first.length > 32
? '${doctorsListResponseModel.speciality!.first.substring(0, 32)}...'
: doctorsListResponseModel.speciality!.first)
: doctorsListResponseModel.speciality!.first) : ""
: "")
.toString()
.toText12(fontWeight: FontWeight.w500, color: AppColors.textColor, maxLine: 2, isEnglishOnly: true)

@ -131,6 +131,7 @@ class DoctorRatingDialog extends StatelessWidget {
Text(
averageRating.toString(),
style: TextStyle(
fontFamily: "Poppins",
fontSize: 48.f,
fontWeight: FontWeight.w700,
color: averageRating == 0 || averageRating == 0.0 ? AppColors.textColor : AppColors.whiteColor,
@ -168,7 +169,7 @@ class DoctorRatingDialog extends StatelessWidget {
// color: averageRating == 0 || averageRating == 0.0 ? AppColors.textColor : AppColors.whiteColor,
// ),
// ),
),
).paddingSymmetrical(12.h, 0.h),
],
),
),
@ -236,6 +237,7 @@ class DoctorRatingDialog extends StatelessWidget {
'$percent%',
textAlign: TextAlign.right,
style: TextStyle(
fontFamily: "Poppins",
fontSize: 14,
fontWeight: FontWeight.w600,
color: AppColors.ratingPercentageTextColor,

@ -1,5 +1,6 @@
import 'dart:developer';
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';
@ -9,6 +10,7 @@ import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/hospital_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart';
@ -107,7 +109,7 @@ class CmcHospitalListItem extends StatelessWidget {
Visibility(
visible: (hospital.distanceInKilometers == null || hospital.distanceInKilometers == 0),
child: AppCustomChipWidget(
labelText: " Distance not available",
labelText: LocaleKeys.noDistance.tr(),
textColor: AppColors.blackColor,
),
),

@ -286,10 +286,13 @@ class FeedbackPage extends StatelessWidget {
children: [
AppCustomChipWidget(labelText: contactUsViewModel.patientFeedbackSelectedAppointment!.clinicName!).toShimmer2(isShow: false),
AppCustomChipWidget(labelText: contactUsViewModel.patientFeedbackSelectedAppointment!.projectName!).toShimmer2(isShow: false),
AppCustomChipWidget(
icon: AppAssets.appointment_calendar_icon,
labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(contactUsViewModel.patientFeedbackSelectedAppointment!.appointmentDate), false),
).toShimmer2(isShow: false),
Directionality(
textDirection: ui.TextDirection.ltr,
child: AppCustomChipWidget(
icon: AppAssets.appointment_calendar_icon,
labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(contactUsViewModel.patientFeedbackSelectedAppointment!.appointmentDate), false),
isEnglishOnly: true).toShimmer2(isShow: false),
),
],
),
],

@ -23,6 +23,8 @@ import 'package:provider/provider.dart';
import 'widgets/select-medical_file.dart';
import 'dart:ui' as ui;
class RechargeWalletPage extends StatefulWidget {
const RechargeWalletPage({super.key});
@ -153,7 +155,7 @@ class _RechargeWalletPageState extends State<RechargeWalletPage> {
titleWidget: Consumer<HabibWalletViewModel>(builder: (context, habibWalletVM, child) {
return habibWalletVM.currentIndex != 0
? IconButton(
icon: Utils.buildSvgWithAssets(icon: AppAssets.arrow_back, width: 24.h, height: 24.h),
icon: Transform.flip(flipX: appState.isArabic(), child: Utils.buildSvgWithAssets(icon: AppAssets.arrow_back, width: 24.h, height: 24.h)),
padding: EdgeInsets.zero,
onPressed: () => habibWalletVM.setCurrentIndex(0),
highlightColor: Colors.transparent,
@ -250,7 +252,7 @@ class _RechargeWalletPageState extends State<RechargeWalletPage> {
if (amountTextController.text.isEmpty) {
showCommonBottomSheetWithoutHeight(
context,
child: Utils.getErrorWidget(loadingText: "Please enter amount to continue."),
child: Utils.getErrorWidget(loadingText: LocaleKeys.enterAmount.tr(context: context)),
callBackFunc: () {
textFocusNode.requestFocus();
},
@ -260,7 +262,7 @@ class _RechargeWalletPageState extends State<RechargeWalletPage> {
} else if (habibWalletVM.selectedHospital == null) {
showCommonBottomSheetWithoutHeight(
context,
child: Utils.getErrorWidget(loadingText: "Please select hospital to continue."),
child: Utils.getErrorWidget(loadingText: LocaleKeys.selectHospitalForAdvancePayment.tr(context: context)),
callBackFunc: () {
textFocusNode.requestFocus();
},

@ -1,12 +1,18 @@
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/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/my_appointments/models/resp_models/hospital_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart';
import 'dart:ui' as ui;
class HospitalListItemAdvancePayment extends StatelessWidget {
final HospitalsModel hospitalModel;
@ -32,7 +38,7 @@ class HospitalListItemAdvancePayment extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
spacing: 8.h,
children: [hospitalName],
children: [hospitalName, distanceInfo],
),
),
Transform.flip(
@ -68,4 +74,45 @@ class HospitalListItemAdvancePayment extends StatelessWidget {
)
],
);
Widget get distanceInfo => Row(
spacing: 4.w,
children: [
Visibility(
visible: (hospitalModel.distanceInKilometers != 0),
child: Directionality(
textDirection: ui.TextDirection.ltr,
child: AppCustomChipWidget(
labelText: "${hospitalModel.distanceInKilometers ?? ""} KMs",
deleteIcon: AppAssets.location_red,
deleteIconSize: Size(9, 12),
backgroundColor: AppColors.secondaryLightRedColor,
textColor: AppColors.errorColor,
isEnglishOnly: true,
),
),
),
Visibility(
visible: (hospitalModel.distanceInKilometers == 0),
child: Row(
children: [
AppCustomChipWidget(
labelText: LocaleKeys.noDistance.tr(),
textColor: AppColors.blackColor,
),
// SizedBox(
// width: 8.h,
// )
],
)),
// Visibility(
// visible: !isLocationEnabled,
// child: AppCustomChipWidget(
// labelText: "Location turned off",
// deleteIcon: AppAssets.location_unavailable,
// deleteIconSize: Size(9.w, 12.h),
// textColor: AppColors.blackColor,
// )),
],
);
}

@ -78,9 +78,10 @@ class _MultiPageBottomSheetState extends State<MultiPageBottomSheet> {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Enter File Number".toText20(weight: FontWeight.w600),
LocaleKeys.pleaseEnterAFileNumber.tr(context: context).toText20(weight: FontWeight.w600),
SizedBox(height: 12.h),
TextInputWidget(
fontFamily: "Poppins",
labelText: LocaleKeys.fileNumber.tr(),
hintText: "xxxxxxxxx",
controller: fileNumberEditingController,
@ -140,10 +141,15 @@ class _MultiPageBottomSheetState extends State<MultiPageBottomSheet> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.myMedicalFile.tr(context: context).toText16(color: AppColors.textColor, weight: FontWeight.w500),
"${LocaleKeys.fileno.tr(context: context)}: ${appState.getAuthenticatedUser()!.patientId}".toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500),
Row(
children: [
"${LocaleKeys.fileno.tr(context: context)}: ".toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500),
appState.getAuthenticatedUser()!.patientId.toString().toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500, isEnglishOnly: true),
],
),
],
),
Utils.buildSvgWithAssets(icon: AppAssets.forward_chevron_icon, iconColor: AppColors.textColor, width: 15.h, height: 15.h),
Transform.flip(flipX: appState.isArabic(), child: Utils.buildSvgWithAssets(icon: AppAssets.forward_chevron_icon, iconColor: AppColors.textColor, width: 15.h, height: 15.h)),
],
).paddingAll(16.h),
).onPress(() {
@ -167,10 +173,10 @@ class _MultiPageBottomSheetState extends State<MultiPageBottomSheet> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.familyTitle.tr(context: context).toText16(color: AppColors.textColor, weight: FontWeight.w500),
"Select a medical file from your family".toText14(color: AppColors.greyTextColor, weight: FontWeight.w500),
LocaleKeys.selectMedicalFileFromFamily.tr(context: context).toText14(color: AppColors.greyTextColor, weight: FontWeight.w500),
],
),
Utils.buildSvgWithAssets(icon: AppAssets.forward_chevron_icon, iconColor: AppColors.textColor, width: 15.h, height: 15.h),
Transform.flip(flipX: appState.isArabic(), child: Utils.buildSvgWithAssets(icon: AppAssets.forward_chevron_icon, iconColor: AppColors.textColor, width: 15.h, height: 15.h)),
],
).paddingAll(16.h),
).onPress(() {
@ -205,10 +211,10 @@ class _MultiPageBottomSheetState extends State<MultiPageBottomSheet> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.otherAccount.tr(context: context).toText16(color: AppColors.textColor, weight: FontWeight.w500),
"Any active medical file from HMG".toText14(color: AppColors.greyTextColor, weight: FontWeight.w500),
LocaleKeys.anyFileFromHMG.tr(context: context).toText14(color: AppColors.greyTextColor, weight: FontWeight.w500),
],
),
Utils.buildSvgWithAssets(icon: AppAssets.forward_chevron_icon, iconColor: AppColors.textColor, width: 15.h, height: 15.h),
Transform.flip(flipX: appState.isArabic(), child: Utils.buildSvgWithAssets(icon: AppAssets.forward_chevron_icon, iconColor: AppColors.textColor, width: 15.h, height: 15.h)),
],
).paddingAll(16.h),
).onPress(() {

@ -1,34 +1,157 @@
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/location_util.dart';
import 'package:hmg_patient_app_new/core/utils/doctor_response_mapper.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/habib_wallet/habib_wallet_view_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/hospital_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/habib_wallet/widgets/hospital_list_item.dart';
import 'package:hmg_patient_app_new/theme/colors.dart' show AppColors;
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart';
class SelectHospitalBottomSheet extends StatelessWidget {
class SelectHospitalBottomSheet extends StatefulWidget {
const SelectHospitalBottomSheet({super.key});
@override
State<SelectHospitalBottomSheet> createState() => _SelectHospitalBottomSheetState();
}
class _SelectHospitalBottomSheetState extends State<SelectHospitalBottomSheet> {
late HabibWalletViewModel habibWalletVM;
final TextEditingController searchText = TextEditingController();
bool sortByLocation = false;
bool isLoading = false;
List<HospitalsModel> displayList = [];
SelectHospitalBottomSheet({super.key});
@override
void initState() {
super.initState();
final appState = getIt.get<AppState>();
sortByLocation = (appState.userLat != 0.0) && (appState.userLong != 0.0);
WidgetsBinding.instance.addPostFrameCallback((_) {
_updateDisplayList();
});
}
void _updateDisplayList() {
final appState = getIt.get<AppState>();
final hospitals = List<HospitalsModel>.from(habibWalletVM.advancePaymentHospitals);
if (sortByLocation && appState.userLat != 0.0 && appState.userLong != 0.0) {
hospitals.sort((a, b) {
final distA = (a.latitude != null && a.longitude != null)
? DoctorMapper.calculateDistance(appState.userLat, appState.userLong, double.parse(a.latitude!), double.parse(a.longitude!))
: double.infinity;
final distB = (b.latitude != null && b.longitude != null)
? DoctorMapper.calculateDistance(appState.userLat, appState.userLong, double.parse(b.latitude!), double.parse(b.longitude!))
: double.infinity;
return distA.compareTo(distB);
});
}
setState(() {
displayList = hospitals;
isLoading = false;
});
}
void _refreshHospitalListAfterApi() {
void listener() {
if (habibWalletVM.advancePaymentHospitals.isNotEmpty) {
habibWalletVM.removeListener(listener);
_updateDisplayList();
}
}
habibWalletVM.addListener(listener);
habibWalletVM.getProjectsList();
}
void _handleSortByLocationToggle(bool value) {
if (value) {
final locationUtils = getIt.get<LocationUtils>();
locationUtils.getLocation(
isShowConfirmDialog: true,
onSuccess: (latLng) {
setState(() {
sortByLocation = true;
isLoading = true;
});
_refreshHospitalListAfterApi();
},
onFailure: () {
showCommonBottomSheetWithoutHeight(
title: LocaleKeys.notice.tr(context: context),
context,
child: Utils.getWarningWidget(
loadingText: LocaleKeys.giveLocationPermissionForNearestList.tr(context: context),
isShowActionButtons: true,
onCancelTap: () {
Navigator.of(context).pop();
},
onConfirmTap: () async {
Navigator.of(context).pop();
openAppSettings();
}),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
setState(() {
sortByLocation = false;
});
},
onLocationDeniedForever: () {
showCommonBottomSheetWithoutHeight(
title: LocaleKeys.notice.tr(context: context),
context,
child: Utils.getWarningWidget(
loadingText: LocaleKeys.giveLocationPermissionForNearestList.tr(context: context),
isShowActionButtons: true,
onCancelTap: () {
Navigator.of(context).pop();
},
onConfirmTap: () async {
Navigator.of(context).pop();
openAppSettings();
}),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
setState(() {
sortByLocation = false;
});
},
);
} else {
final appState = getIt.get<AppState>();
appState.resetLocation();
setState(() {
sortByLocation = false;
isLoading = true;
});
_refreshHospitalListAfterApi();
}
}
@override
Widget build(BuildContext context) {
habibWalletVM = Provider.of<HabibWalletViewModel>(context, listen: false);
if (displayList.isEmpty && habibWalletVM.advancePaymentHospitals.isNotEmpty) {
displayList = List.from(habibWalletVM.advancePaymentHospitals);
}
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Text(
// LocaleKeys.selectHospital.tr(),
// style: TextStyle(
// fontSize: 21,
// fontWeight: FontWeight.w600,
// color: AppColors.blackColor,
// ),
// ),
Text(
LocaleKeys.selectHospitalForAdvancePayment.tr(context: context),
style: TextStyle(
@ -38,48 +161,55 @@ class SelectHospitalBottomSheet extends StatelessWidget {
),
),
SizedBox(height: 16.h),
// TextInputWidget(
// labelText: LocaleKeys.search.tr(),
// hintText: "Search Hospital".tr(),
// controller: searchText,
// onChange: (value) {
// // appointmentsViewModel.filterHospitalListByString(value, regionalViewModel.selectedRegionId , regionalViewModel.selectedFacilityType ==
// // FacilitySelection.HMG.name);
// },
// isEnable: true,
// prefix: null,
// autoFocus: false,
// isBorderAllowed: false,
// keyboardType: TextInputType.text,
// isAllowLeadingIcon: true,
// selectionType: SelectionTypeEnum.search,
// padding: EdgeInsets.symmetric(
// vertical: ResponsiveExtension(10).h,
// horizontal: ResponsiveExtension(15).h,
// ),
// ),
// SizedBox(height: 24.h),
// TypeSelectionWidget(
// hmcCount: "0",
// hmgCount: "0",
// ),
// SizedBox(height: 21.h),
SizedBox(
Padding(
padding: EdgeInsets.symmetric(horizontal: 4.w),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Utils.buildSvgWithAssets(icon: AppAssets.location, iconColor: AppColors.greyTextColor, width: 18.h, height: 18.h),
SizedBox(width: 8.w),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.sortByLocation.tr(context: context).toText14(isBold: true),
LocaleKeys.sortByNearestLocation.tr(context: context).toText11(color: AppColors.textColorLight, weight: FontWeight.w500),
],
),
],
),
Switch(
value: sortByLocation,
onChanged: _handleSortByLocationToggle,
activeThumbColor: AppColors.successColor,
activeTrackColor: AppColors.successColor.withValues(alpha: 0.15),
),
],
),
),
SizedBox(height: 8.h),
isLoading
? SizedBox(
height: MediaQuery.sizeOf(context).height * .4,
child: Center(child: Utils.getLoadingWidget()),
)
: SizedBox(
height: MediaQuery.sizeOf(context).height * .4,
child: ListView.separated(
itemBuilder: (_, index) {
return HospitalListItemAdvancePayment(
hospitalModel: habibWalletVM.advancePaymentHospitals[index],
isLocationEnabled: false,
hospitalModel: displayList[index],
isLocationEnabled: sortByLocation,
).onPress(() {
habibWalletVM.setSelectedHospital(habibWalletVM.advancePaymentHospitals[index]);
habibWalletVM.setSelectedHospital(displayList[index]);
Navigator.of(context).pop();
});
},
separatorBuilder: (_, __) => SizedBox(
height: 16.h,
),
itemCount: habibWalletVM.advancePaymentHospitals.length),
itemCount: displayList.length),
)
],
);

@ -55,6 +55,7 @@ import 'package:hmg_patient_app_new/presentation/notifications/notifications_lis
import 'package:hmg_patient_app_new/presentation/profile_settings/profile_settings.dart';
import 'package:hmg_patient_app_new/presentation/rate_appointment/rate_appointment_doctor.dart';
import 'package:hmg_patient_app_new/presentation/todo_section/ancillary_procedures_details_page.dart';
import 'package:hmg_patient_app_new/presentation/todo_section/todo_page.dart';
import 'package:hmg_patient_app_new/presentation/todo_section/widgets/ancillary_orders_list.dart';
import 'package:hmg_patient_app_new/routes/app_routes.dart';
import 'package:hmg_patient_app_new/services/cache_service.dart';
@ -65,6 +66,7 @@ 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/common_bottom_sheet.dart';
import 'package:hmg_patient_app_new/widgets/countdown_timer.dart';
import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:hmg_patient_app_new/widgets/routes/spring_page_route_builder.dart';
import 'package:provider/provider.dart';
@ -117,7 +119,12 @@ class _LandingPageState extends State<LandingPage> {
showQuickLogin(context);
});
}
scheduleMicrotask(() {
scheduleMicrotask(() async {
if (!appState.isAuthenticated) {
// LoaderBottomSheet.showLoader();
await authVM.handleNewImeiRegistration(isNavigate: false);
}
if (appState.isAuthenticated) {
habibWalletVM.initHabibWalletProvider();
habibWalletVM.getPatientBalanceAmount();
@ -205,13 +212,15 @@ class _LandingPageState extends State<LandingPage> {
);
},
name: ('${appState.getAuthenticatedUser()!.firstName!} ${appState.getAuthenticatedUser()!.lastName!}'),
imageUrl: appState.getAuthenticatedUser()?.gender == 1 ? AppAssets.maleImg : AppAssets.femaleImg,
// imageUrl: appState.getAuthenticatedUser()?.gender == 1 ? AppAssets.maleImg : AppAssets.femaleImg,
imageUrl: appState.getAuthenticatedUser()?.gender == 1
? ((appState.getAuthenticatedUser()?.age ?? 0) < 7 ? AppAssets.babyBoyImg : AppAssets.maleImg)
: ((appState.getAuthenticatedUser()?.age ?? 0) < 7 ? AppAssets.babyGirlImg : AppAssets.femaleImg),
).expanded
: CustomButton(
text: LocaleKeys.loginOrRegister.tr(context: context),
onPressed: () async {
await authVM.onLoginPressed();
// Navigator.pushReplacementNamed(
// // context,
// context,
@ -449,7 +458,8 @@ class _LandingPageState extends State<LandingPage> {
loop: false,
itemWidth: MediaQuery.of(context).size.width - 48.h,
indicatorLayout: PageIndicatorLayout.COLOR,
axisDirection: getIt.get<AppState>().isArabic() ? AxisDirection.left : AxisDirection.right,
// axisDirection: getIt.get<AppState>().isArabic() ? AxisDirection.left : AxisDirection.right,
axisDirection: appState.isArabic() ? AxisDirection.left : AxisDirection.right,
controller: _controller,
itemHeight: 255.h + 20,
// extra space for shadow
@ -583,6 +593,46 @@ class _LandingPageState extends State<LandingPage> {
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r),
child: Column(
children: [
todoSectionViewModel.patientAncillaryOrdersList.isNotEmpty
? Container(
height: 50.h,
decoration: ShapeDecoration(
color: AppColors.eReferralCardColor.withAlpha(50),
shape: SmoothRectangleBorder(
borderRadius: BorderRadius.only(topLeft: Radius.circular(24), topRight: Radius.circular(24)),
smoothness: 1,
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
LocaleKeys.pendingAncillaryOrders
.tr(context: context)
.toText14(color: AppColors.eReferralCardColor, weight: FontWeight.w500)
.paddingSymmetrical(24.h, 0.h),
CustomButton(
text: LocaleKeys.view.tr(context: context),
onPressed: () {
getIt.get<TodoSectionViewModel>().setIsAncillaryOrdersNeedReloading(true);
Navigator.of(context).push(
CustomPageRoute(
page: ToDoPage(),
),
);
},
backgroundColor: AppColors.eReferralCardColor,
borderColor: AppColors.eReferralCardColor,
textColor: AppColors.whiteColor,
fontSize: 10.f,
fontWeight: FontWeight.w500,
borderRadius: 8,
padding: EdgeInsets.fromLTRB(15, 0, 15, 0),
height: 30.h,
).paddingSymmetrical(24.h, 0.h),
],
),
)
: SizedBox.shrink(),
SizedBox(
height: 92.h + 32.h - 4.h,
child: RawScrollbar(
@ -837,11 +887,11 @@ class _LandingPageState extends State<LandingPage> {
);
}
if (todoSectionViewModel.patientAncillaryOrdersList.isNotEmpty) {
return _buildAncillaryOrderCardWrapper(
todoSectionViewModel.patientAncillaryOrdersList.first,
);
}
// if (todoSectionViewModel.patientAncillaryOrdersList.isNotEmpty) {
// return _buildAncillaryOrderCardWrapper(
// todoSectionViewModel.patientAncillaryOrdersList.first,
// );
// }
return _buildAppointmentCardWrapper(
myAppointmentsViewModel.patientAppointmentsHistoryList[1],
@ -854,9 +904,9 @@ class _LandingPageState extends State<LandingPage> {
final hasAncillaryOrders = todoSectionViewModel.patientAncillaryOrdersList.isNotEmpty;
if (hasQueueOrLiveCare && hasAncillaryOrders) {
return _buildAncillaryOrderCardWrapper(
todoSectionViewModel.patientAncillaryOrdersList.first,
);
// return _buildAncillaryOrderCardWrapper(
// todoSectionViewModel.patientAncillaryOrdersList.first,
// );
}
return _buildAppointmentCardWrapper(

@ -8,6 +8,7 @@ import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_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/book_appointment/book_appointment_page.dart';
import 'package:hmg_patient_app_new/presentation/home/data/service_card_data.dart';
@ -128,6 +129,7 @@ class LargeServiceCard extends StatelessWidget {
switch (serviceCardData.serviceName) {
case "livecare":
{
getIt.get<MyAppointmentsViewModel>().getPatientFavouriteDoctors();
getIt.get<BookAppointmentsViewModel>().onTabChanged(1);
Navigator.of(getIt.get<NavigationService>().navigatorKey.currentContext!).push(
CustomPageRoute(

@ -357,13 +357,12 @@ class _HhcProceduresPageState extends State<HhcProceduresPage> {
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.selectedServices.tr(context: context).toText12(
color: AppColors.textColorLight,
fontWeight: FontWeight.w600,
),
"${hmgServicesViewModel.selectedHhcServices.length} service(s) selected".toText14(
isBold: true,
weight: FontWeight.bold,
LocaleKeys.selectedServices.tr(context: context).toText12(color: AppColors.textColorLight, fontWeight: FontWeight.w600),
Row(
children: [
("${hmgServicesViewModel.selectedHhcServices.length} ").toText14(isBold: true, weight: FontWeight.bold, isEnglishOnly: true),
LocaleKeys.servicesSelected.tr(context: context).toText14(isBold: true, weight: FontWeight.bold),
],
),
],
),

@ -135,10 +135,10 @@ class PatientInsuranceCard extends StatelessWidget {
],
),
SizedBox(height: 12.h),
insuranceCardDetailsModel.groupName!.toText12(isBold: true),
insuranceCardDetailsModel.groupName!.toText12(isBold: true, isEnglishOnly: true),
Row(
children: [
(insuranceCardDetailsModel.companyName!.length > 40 ? "${insuranceCardDetailsModel.companyName!.substring(0, 40)}..." : insuranceCardDetailsModel.companyName!).toText12(isBold: true),
(insuranceCardDetailsModel.companyName!.length > 40 ? "${insuranceCardDetailsModel.companyName!.substring(0, 40)}..." : insuranceCardDetailsModel.companyName!).toText12(isBold: true, isEnglishOnly: true),
SizedBox(
width: 6.h,
),
@ -149,7 +149,7 @@ class PatientInsuranceCard extends StatelessWidget {
borderRadius: 50.r,
),
child: ((insuranceCardDetailsModel.subCategoryDesc ?? "").length > 10 ? (insuranceCardDetailsModel.subCategoryDesc ?? "").substring(0, 10) : (insuranceCardDetailsModel.subCategoryDesc ?? ""))
.toText8(isBold: true, color: AppColors.whiteColor),
.toText8(isBold: true, color: AppColors.whiteColor, isEnglishOnly: true),
),
],
),

File diff suppressed because one or more lines are too long

@ -30,6 +30,7 @@ class _LabAiAnalysisDetailedPageState extends State<LabAiAnalysisDetailedPage> {
Widget build(BuildContext context) {
labProvider = Provider.of<LabViewModel>(context, listen: false);
return CollapsingListView(
isClose: true,
title: LocaleKeys.aiAnalysis.tr(context: context),
child: Consumer<LabViewModel>(
builder: (context, model, child) {
@ -415,7 +416,7 @@ class _LabAiAnalysisDetailedPageState extends State<LabAiAnalysisDetailedPage> {
Widget _buildCombinedLabCard(AiGeneratedAttribute attr) {
return Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: false),
padding: EdgeInsets.all(16.h),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
@ -502,7 +503,11 @@ class _LabAiAnalysisDetailedPageState extends State<LabAiAnalysisDetailedPage> {
Container(
padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 4.h),
decoration: BoxDecoration(color: _getResultFlagColor(attr.calculatedResultFlag), borderRadius: BorderRadius.circular(4.r)),
child: ("${LocaleKeys.calculatedValue.tr()}: ${attr.resultValue!}").toText12(fontWeight: FontWeight.w600, color: _getResultTextColor(attr.calculatedResultFlag)),
child: ("${LocaleKeys.calculatedValue.tr()}: ${attr.resultValue!}").toText12(
fontWeight: FontWeight.w600,
color: _getResultTextColor(attr.calculatedResultFlag),
isEnglishOnly: true
),
),
SizedBox(width: 8.h),
Container(
@ -534,7 +539,7 @@ class _LabAiAnalysisDetailedPageState extends State<LabAiAnalysisDetailedPage> {
mainAxisAlignment: MainAxisAlignment.center,
children: [
LocaleKeys.calculationFormula.tr().toText16(weight: FontWeight.w600),
(attr.calculationFormula ?? "").toText12(fontWeight: FontWeight.w500, color: AppColors.textColorLight),
(attr.calculationFormula ?? "").toText12(fontWeight: FontWeight.w500, color: AppColors.textColorLight, isEnglishOnly: true),
],
),
),

@ -40,7 +40,7 @@ class LabOrderResultItem extends StatelessWidget {
// ...labOrder!.testDetails!.map((detail) {
Padding(
padding: EdgeInsets.only(bottom: 8.h),
child: '${tests!.description}'.toText14(weight: FontWeight.w500),
child: '${tests!.description}'.toText14(weight: FontWeight.w500, isEnglishOnly: true),
),
// (tests!.packageShortDescription ?? "").toText12(fontWeight: FontWeight.w500, color: AppColors.textColorLight),

@ -28,18 +28,54 @@ import '../../../core/common_models/data_points.dart';
import '../../../widgets/common_bottom_sheet.dart' show showCommonBottomSheetWithoutHeight;
import 'dart:ui' as ui;
class LabResultDetails extends StatelessWidget {
class LabResultDetails extends StatefulWidget {
final LabResult recentLabResult;
final String? testDescription;
const LabResultDetails({super.key, required this.recentLabResult, required this.testDescription});
@override
State<LabResultDetails> createState() => _LabResultDetailsState();
}
class _LabResultDetailsState extends State<LabResultDetails> {
final GlobalKey _aiAnalysisKey = GlobalKey();
LabOrderResponseByAi? _previousAiData;
LabResult get recentLabResult => widget.recentLabResult;
String? get testDescription => widget.testDescription;
@override
Widget build(BuildContext context) {
LabViewModel labViewModel = Provider.of<LabViewModel>(context, listen: false);
final appState = getIt.get<AppState>();
return Scaffold(
body: Consumer<LabViewModel>(builder: (context, labVM, child) {
// Detect changes in labOrderResponseByAi
WidgetsBinding.instance.addPostFrameCallback((_) {
if (labVM.labOrderResponseByAi != null && _previousAiData == null) {
// AI data just became available scroll to it
final ctx = _aiAnalysisKey.currentContext;
if (ctx != null) {
Scrollable.ensureVisible(
ctx,
duration: const Duration(milliseconds: 400),
curve: Curves.easeOut,
);
}
} else if (labVM.labOrderResponseByAi == null && _previousAiData != null) {
// AI data just became null scroll to top
final scrollable = Scrollable.maybeOf(context);
scrollable?.position.animateTo(
0,
duration: const Duration(milliseconds: 400),
curve: Curves.easeOut,
);
}
_previousAiData = labVM.labOrderResponseByAi;
});
return Column(
children: [
Expanded(
@ -110,7 +146,7 @@ class LabResultDetails extends StatelessWidget {
selector: (_, model) => model.labOrderResponseByAi,
builder: (_, aiData, __) {
if (aiData != null) {
return AiAnalysisWidget(data: aiData).paddingOnly(bottom: 16.h);
return AiAnalysisWidget(key: _aiAnalysisKey, data: aiData).paddingOnly(bottom: 16.h);
}
return const SizedBox.shrink();
},
@ -187,7 +223,7 @@ class LabResultDetails extends StatelessWidget {
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
(recentLabResult.testCode ?? "").toText28(isBold: true, color: AppColors.textColor, letterSpacing: -2),
(recentLabResult.testCode ?? "").toText28(isBold: true, color: AppColors.textColor, letterSpacing: -2, isEnglishOnly: true),
Visibility(
visible: recentLabResult.checkIfGraphShouldBeDisplayed() == true,
child: Column(
@ -224,12 +260,16 @@ class LabResultDetails extends StatelessWidget {
mainAxisSize: MainAxisSize.max,
children: [
Flexible(
child: ("${recentLabResult.resultValue} ${recentLabResult.uOM}" ?? "").toText28(
isBold: true,
color: context.read<LabViewModel>().getColor(
recentLabResult.calculatedResultFlag ?? "",
),
letterSpacing: -2),
child: Directionality(
textDirection: ui.TextDirection.ltr,
child: ("${recentLabResult.resultValue} ${recentLabResult.uOM}" ?? "").toText28(
isBold: true,
color: context.read<LabViewModel>().getColor(
recentLabResult.calculatedResultFlag ?? "",
),
letterSpacing: -2,
isEnglishOnly: true),
),
),
SizedBox(
width: 4.h,
@ -386,7 +426,7 @@ class LabResultDetails extends StatelessWidget {
return SizedBox.shrink();
// }
},
graphColor: AppColors.graphGridColor,
graphColor: AppColors.textColor.withAlpha(90),
graphShadowColor: AppColors.graphGridColor.withOpacity(.5),
graphGridColor: graphColor.withOpacity(.4),
bottomLabelFormatter: (value, data) {
@ -443,7 +483,7 @@ class LabResultDetails extends StatelessWidget {
// itemCount: labmodel.isLabResultsHistoryShowMore ? (labmodel.filteredGraphValues.length < 3 ? labmodel.filteredGraphValues : 3) : labmodel.filteredGraphValues.length,
itemCount: !labmodel.isLabResultsHistoryShowMore ? (labmodel.mainLabResults.length < 3 ? labmodel.mainLabResults.length : 3) : labmodel.mainLabResults.length,
itemBuilder: (context, index) {
var data = labmodel.mainLabResults.reversed.toList()[index];
var data = labmodel.mainLabResults.toList()[index];
return LabHistoryItem(
dayNameAndDate: labmodel.getFormattedDate(DateUtil.convertStringToDate(data.verifiedOnDateTime)),
result: data.resultValue??"",

@ -24,6 +24,8 @@ import 'package:provider/provider.dart';
import 'widgets/patient_sick_leave_card.dart';
import 'dart:ui' as ui;
class PatientSickleavesListPage extends StatefulWidget {
const PatientSickleavesListPage({super.key});
@ -153,14 +155,26 @@ class _PatientSickleavesListPageState extends State<PatientSickleavesListPage> {
spacing: 6.h,
runSpacing: 6.h,
children: [
AppCustomChipWidget(
labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(model.patientSickLeaveList[index].appointmentDate), false),
Directionality(
textDirection: ui.TextDirection.ltr,
child: AppCustomChipWidget(
labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(model.patientSickLeaveList[index].appointmentDate), false),
isEnglishOnly: true,
),
),
AppCustomChipWidget(
labelText: model.isSickLeavesSortByClinic ? model.patientSickLeaveList[index].projectName! : model.patientSickLeaveList[index].clinicName!,
),
AppCustomChipWidget(
labelText: "${model.patientSickLeaveList[index].sickLeaveDays} Days",
richText: Row(
mainAxisSize: MainAxisSize.min,
children: [
"${model.patientSickLeaveList[index].sickLeaveDays} ".toText10(isEnglishOnly: true),
LocaleKeys.days.tr(context: context).toText10()
],
),
// labelText: "${model.patientSickLeaveList[index].sickLeaveDays} ${LocaleKeys.days.tr(context: context)}",
isEnglishOnly: true,
),
],
),

@ -21,6 +21,8 @@ import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:open_filex/open_filex.dart';
import 'package:provider/provider.dart';
import 'dart:ui' as ui;
class PatientSickLeaveCard extends StatelessWidget {
PatientSickLeaveCard({super.key, required this.patientSickLeavesResponseModel, this.isLoading = false, this.isSickLeaveListPage = false});
@ -72,11 +74,15 @@ class PatientSickLeaveCard extends StatelessWidget {
spacing: 3.h,
runSpacing: 4.h,
children: [
AppCustomChipWidget(
icon: AppAssets.doctor_calendar_icon,
labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(patientSickLeavesResponseModel.appointmentDate), false),
labelPadding: EdgeInsetsDirectional.only(start: -4.h, end: 8.h),
).toShimmer2(isShow: isLoading),
Directionality(
textDirection: ui.TextDirection.ltr,
child: AppCustomChipWidget(
icon: AppAssets.doctor_calendar_icon,
labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(patientSickLeavesResponseModel.appointmentDate), false),
labelPadding: EdgeInsetsDirectional.only(start: -4.h, end: 8.h),
isEnglishOnly: true,
).toShimmer2(isShow: isLoading),
),
AppCustomChipWidget(labelText: isLoading ? "Pending Activation" : patientSickLeavesResponseModel.clinicName!).toShimmer2(isShow: isLoading),
],
),

@ -311,7 +311,8 @@ class _FamilyCardsState extends State<FamilyCards> {
crossAxisCount: 2,
crossAxisSpacing: 10.w,
mainAxisSpacing: 10.h,
childAspectRatio: widget.isShowDetails ? 0.56.h : 0.74.h,
// childAspectRatio: widget.isShowDetails ? 0.56.h : 0.74.h,
childAspectRatio: 0.7.h,
),
padding: EdgeInsets.only(bottom: 20.h),
itemBuilder: (context, index) {

@ -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/app_state.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';
@ -18,6 +19,7 @@ import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
import 'package:provider/provider.dart';
import 'package:intl/intl.dart';
import 'dart:ui' as ui;
class NotificationsListPage extends StatefulWidget {
const NotificationsListPage({super.key});
@ -134,16 +136,20 @@ class _NotificationsListPageState extends State<NotificationsListPage> {
color: AppColors.greyColor,
borderRadius: BorderRadius.circular(8),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.access_time, size: 12.w, color: AppColors.textColor),
SizedBox(width: 4.w),
_formatTime(notificationsVM.notificationsList[index].isSentOn).toText10(
weight: FontWeight.w500,
color: AppColors.textColor,
),
],
child: Directionality(
textDirection: ui.TextDirection.ltr,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.access_time, size: 12.w, color: AppColors.textColor),
SizedBox(width: 4.w),
_formatTime(notificationsVM.notificationsList[index].isSentOn).toText10(
weight: FontWeight.w500,
color: AppColors.textColor,
isEnglishOnly: true
),
],
),
),
),
SizedBox(width: 8.w),
@ -154,25 +160,32 @@ class _NotificationsListPageState extends State<NotificationsListPage> {
color: AppColors.greyColor,
borderRadius: BorderRadius.circular(8),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.calendar_today, size: 12.w, color: AppColors.textColor),
SizedBox(width: 4.w),
_formatDate(notificationsVM.notificationsList[index].isSentOn).toText10(
weight: FontWeight.w500,
color: AppColors.textColor,
),
],
child: Directionality(
textDirection: ui.TextDirection.ltr,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.calendar_today, size: 12.w, color: AppColors.textColor),
SizedBox(width: 4.w),
_formatDate(notificationsVM.notificationsList[index].isSentOn).toText10(
weight: FontWeight.w500,
color: AppColors.textColor,
isEnglishOnly: true
),
],
),
),
),
Spacer(),
// Arrow icon
Utils.buildSvgWithAssets(
icon: AppAssets.arrow_forward,
width: 16.w,
height: 16.h,
iconColor: AppColors.greyTextColor,
Transform.flip(
flipX: getIt.get<AppState>().isArabic(),
child: Utils.buildSvgWithAssets(
icon: AppAssets.arrow_forward,
width: 16.w,
height: 16.h,
iconColor: AppColors.greyTextColor,
),
),
],
),
@ -194,7 +207,7 @@ class _NotificationsListPageState extends State<NotificationsListPage> {
children: [
Icon(Icons.image_outlined, size: 12.w, color: AppColors.textColor),
SizedBox(width: 4.w),
'Contains Image'.toText10(
LocaleKeys.containsImage.toText10(
weight: FontWeight.w500,
color: AppColors.textColor,
),

@ -98,7 +98,7 @@ class PrescriptionItemView extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.setReminder.tr(context: context).toText13(isBold: true),
"Notify me before the consumption time".toText10(color: AppColors.textColorLight, isEnglishOnly: true),
LocaleKeys.notifyPrescription.tr(context: context).toText10(color: AppColors.textColorLight),
],
).toShimmer2(isShow: isLoading).expanded,
Switch(

@ -42,6 +42,8 @@ import 'package:provider/provider.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:in_app_review/in_app_review.dart';
import 'dart:ui' as ui;
class ProfileSettings extends StatefulWidget {
const ProfileSettings({super.key});
@ -297,11 +299,11 @@ class ProfileSettingsState extends State<ProfileSettings> {
children: [
actionItem(AppAssets.call_fill, LocaleKeys.contactUs.tr(context: context), () {
launchUrl(Uri.parse("tel://" + "+966 92 006 6666"));
}, trailingLabel: "92 006 6666"),
}, trailingLabel: "92 006 6666", isEnglishOnly: true),
1.divider,
actionItem(AppAssets.permission, LocaleKeys.permissionsProfile.tr(context: context), () {
openAppSettings();
}, trailingLabel: getCurrentPermissions()),
}, trailingLabel: getCurrentPermissions(), isEnglishOnly: true),
actionItem(AppAssets.feedbackFill, LocaleKeys.feedback.tr(context: context), () {
contactUsViewModel.setSelectedFeedbackType(
FeedbackType(id: 5, nameEN: "Not classified", nameAR: 'غير محدد'),
@ -392,7 +394,7 @@ class ProfileSettingsState extends State<ProfileSettings> {
}
Widget actionItem(String icon, String label, VoidCallback onPress,
{String trailingLabel = "", bool? switchValue, ValueChanged<bool>? onSwitchChanged, bool isExternalLink = false, bool isShowLoading = false}) {
{String trailingLabel = "", bool? switchValue, ValueChanged<bool>? onSwitchChanged, bool isExternalLink = false, bool isShowLoading = false, bool isEnglishOnly = false}) {
return SizedBox(
height: 56.h,
child: Row(
@ -403,7 +405,7 @@ class ProfileSettingsState extends State<ProfileSettings> {
if (trailingLabel.isNotEmpty)
ConstrainedBox(
constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width * 0.35),
child: trailingLabel.toText14(color: AppColors.greyTextColor, weight: FontWeight.w500, textOverflow: TextOverflow.ellipsis, maxlines: 1).toShimmer2(isShow: isShowLoading),
child: isEnglishOnly ? Directionality(textDirection: ui.TextDirection.ltr, child: trailingLabel.toText14(color: AppColors.greyTextColor, weight: FontWeight.w500, textOverflow: TextOverflow.ellipsis, maxlines: 1, isEnglishOnly: isEnglishOnly).toShimmer2(isShow: isShowLoading)) : trailingLabel.toText14(color: AppColors.greyTextColor, weight: FontWeight.w500, textOverflow: TextOverflow.ellipsis, maxlines: 1, isEnglishOnly: isEnglishOnly).toShimmer2(isShow: isShowLoading),
),
switchValue != null
? Switch(

@ -146,6 +146,7 @@ class _RadiologyOrdersPageState extends State<RadiologyOrdersPage> {
model.filterRadiologyReports('');
});
},
isEnglishOnly: true
// chipType: ChipTypeEnum.alert,
// isSelected: true,
)
@ -433,7 +434,7 @@ class _RadiologyOrdersPageState extends State<RadiologyOrdersPage> {
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"${group.procedureName.toString().trim() ?? ""}".toText14(weight: FontWeight.w500),
"${group.procedureName.toString().trim() ?? ""}".toText14(weight: FontWeight.w500, isEnglishOnly: true),
// "Lorem ipsum text".toText12(fontWeight: FontWeight.w500, color: AppColors.textColorLight),
SizedBox(height: 16.h),
CustomButton(

@ -78,8 +78,9 @@ class _SearchRadiologyContentContentState extends State<SearchRadiologyContent>
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextInputWidget(
labelText: "Search radiology results",
hintText: "Type test description",
fontFamily: "Poppins",
labelText: LocaleKeys.search.tr(context: context),
hintText: "",
controller: searchEditingController,
isEnable: true,
prefix: null,
@ -93,7 +94,7 @@ class _SearchRadiologyContentContentState extends State<SearchRadiologyContent>
),
SizedBox(height: ResponsiveExtension(20).h),
if (filteredSuggestions.isNotEmpty) ...[
"Suggestions".toText16(isBold: true),
LocaleKeys.suggestions.tr(context: context).toText16(isBold: true),
],
],
),
@ -146,8 +147,8 @@ class SuggestionChip extends StatelessWidget {
child: label.toText12(
// color: isSelected ? Colors.white : Colors.black87,
color: AppColors.textColor,
fontWeight: FontWeight.w500,
),
fontWeight: FontWeight.w500,
isEnglishOnly: true),
),
);
}

@ -49,14 +49,13 @@ class HeightSelectionPage extends StatelessWidget {
},
child: Container(
alignment: Alignment.center,
color: Colors.transparent,
color: Colors.white,
child: Text(
'CM',
style: TextStyle(
fontWeight: FontWeight.w700,
fontSize: 14.f,
color: viewModel.isHeightCm ? AppColors.textColor : AppColors.textColor.withValues(alpha: 0.6),
),
color: viewModel.isHeightCm ? AppColors.primaryRedColor : AppColors.textColor.withValues(alpha: 0.6), fontFamily: "Poppins"),
),
),
),
@ -71,14 +70,13 @@ class HeightSelectionPage extends StatelessWidget {
},
child: Container(
alignment: Alignment.center,
color: Colors.transparent,
color: Colors.white,
child: Text(
'FT',
style: TextStyle(
fontWeight: FontWeight.w700,
fontSize: 14.f,
color: !viewModel.isHeightCm ? AppColors.textColor : AppColors.textColor.withValues(alpha: 0.6),
),
color: !viewModel.isHeightCm ? AppColors.primaryRedColor : AppColors.textColor.withValues(alpha: 0.6), fontFamily: "Poppins"),
),
),
),
@ -133,8 +131,7 @@ class HeightSelectionPage extends StatelessWidget {
style: TextStyle(
fontSize: 90.f,
color: AppColors.textColor,
height: 1,
),
height: 1, fontFamily: "Poppins"),
),
TextSpan(
text: viewModel.isHeightCm ? 'cm' : 'ft',

@ -57,13 +57,14 @@ class WeightSelectionPage extends StatelessWidget {
},
child: Container(
alignment: Alignment.center,
color: Colors.transparent,
color: Colors.white,
child: Text(
'KG',
style: TextStyle(
fontWeight: FontWeight.w700,
fontSize: 14.f,
color: isKg ? AppColors.textColor : AppColors.textColor.withValues(alpha: 0.6),
color: isKg ? AppColors.primaryRedColor : AppColors.textColor.withValues(alpha: 0.6),
fontFamily: "Poppins"
),
),
),
@ -86,7 +87,8 @@ class WeightSelectionPage extends StatelessWidget {
style: TextStyle(
fontWeight: FontWeight.w700,
fontSize: 14.f,
color: !isKg ? AppColors.textColor : AppColors.textColor.withValues(alpha: 0.6),
color: !isKg ? AppColors.primaryRedColor : AppColors.textColor.withValues(alpha: 0.6),
fontFamily: "Poppins"
),
),
),
@ -133,12 +135,12 @@ class WeightSelectionPage extends StatelessWidget {
children: [
Text(
viewModel.selectedWeight!.round().toString(),
style: TextStyle(fontSize: 100.f, color: AppColors.textColor, height: 1),
style: TextStyle(fontSize: 100.f, color: AppColors.textColor, height: 1, fontFamily: "Poppins"),
),
SizedBox(width: 8.w),
Text(
isKg ? 'kg' : 'lbs',
style: TextStyle(fontWeight: FontWeight.w700, fontSize: 24.f),
style: TextStyle(fontWeight: FontWeight.w700, fontSize: 24.f, fontFamily: "Poppins"),
).paddingOnly(bottom: 10.h),
],
),

@ -135,6 +135,7 @@ class _HeightScaleState extends State<HeightScale> {
color: AppColors.greyTextColor,
fontWeight: FontWeight.w500,
height: 1,
fontFamily: "Poppins"
),
textAlign: TextAlign.right,
),

@ -154,6 +154,7 @@ class _WeightScaleState extends State<WeightScale> {
color: AppColors.greyTextColor,
fontWeight: FontWeight.w500,
height: 1,
fontFamily: "Poppins"
),
textAlign: TextAlign.center,
maxLines: 1,

@ -109,7 +109,7 @@ class _DateRangeSelectorState extends State<DateRangeSelector> {
viewHeaderStyle: DateRangePickerViewHeaderStyle(
backgroundColor: AppColors.whiteColor,
textStyle: TextStyle(
fontSize: 14.f,
fontSize: 12.f,
fontWeight: FontWeight.w600,
letterSpacing: -0.46,
color: AppColors.textColor,
@ -121,17 +121,25 @@ class _DateRangeSelectorState extends State<DateRangeSelector> {
selectionShape: DateRangePickerSelectionShape.rectangle,
selectionRadius: 12.h,
selectionColor: AppColors.transparent,
selectionTextStyle: TextStyle(
fontFamily: "Poppins",
),
startRangeSelectionColor: AppColors.primaryRedColor,
endRangeSelectionColor: AppColors.primaryRedColor,
rangeSelectionColor:
AppColors.primaryRedColor.withOpacity(0.1),
rangeTextStyle: TextStyle(
fontFamily: "Poppins",
),
todayHighlightColor: Colors.transparent,
monthCellStyle: DateRangePickerMonthCellStyle(
textStyle: TextStyle(
fontFamily: "Poppins",
fontSize: 12.f,
color: AppColors.textColor,
),
todayTextStyle: TextStyle(
fontFamily: "Poppins",
color: AppColors.textColor,
fontWeight: FontWeight.bold,
),
@ -318,6 +326,7 @@ class _DateRangeSelectorState extends State<DateRangeSelector> {
width: 1,
),
borderRadius: BorderRadius.circular(10)),
isEnglishOnly: true,
).onPress((){
_calendarController.selectedRange = null;
model.currentlySelectedRange = Range.LAST_6MONTH;
@ -325,7 +334,13 @@ class _DateRangeSelectorState extends State<DateRangeSelector> {
}),
AppCustomChipWidget(
labelText: "Year ${model.getCurrentYear}",
richText: Row(
children: [
"${LocaleKeys.year.tr(context: context)} ".toText10(),
model.getCurrentYear.toString().toText10(isEnglishOnly: true),
],
),
labelText: "${LocaleKeys.year.tr(context: context)} ${model.getCurrentYear}",
backgroundColor: model.currentlySelectedRange == Range.THIS_YEAR
? AppColors.primaryRedColor.withOpacity(0.1)
: AppColors.whiteColor,
@ -337,6 +352,7 @@ class _DateRangeSelectorState extends State<DateRangeSelector> {
width: 1,
),
borderRadius: BorderRadius.circular(10)),
isEnglishOnly: true,
).onPress((){
_calendarController.selectedRange = null;
model.currentlySelectedRange = Range.THIS_YEAR;

@ -281,7 +281,17 @@ class CustomGraph extends StatelessWidget {
begin: Alignment.centerLeft,
end: Alignment.centerRight,
),
dotData: FlDotData(show: showLinePoints),
dotData: FlDotData(
show: true,
getDotPainter: (spot, percent, barData, idx) {
return FlDotCirclePainter(
radius: 6,
color: resolvedGraphColor,
strokeWidth: 2,
strokeColor: Colors.white,
);
},
),
belowBarData: BarAreaData(
show: showShadow,
applyCutOffY: cutOffY != null,
@ -317,7 +327,17 @@ class CustomGraph extends StatelessWidget {
begin: Alignment.centerLeft,
end: Alignment.centerRight,
),
dotData: FlDotData(show: showLinePoints),
dotData: FlDotData(
show: true,
getDotPainter: (spot, percent, barData, idx) {
return FlDotCirclePainter(
radius: 6,
color: secondaryGraphColor ?? AppColors.blueColor,
strokeWidth: 2,
strokeColor: Colors.white,
);
},
),
belowBarData: BarAreaData(show: false),
),
);

@ -315,6 +315,7 @@ class TextInputWidget extends StatelessWidget {
autofocus: autoFocus,
textInputAction: TextInputAction.done,
cursorHeight: isWalletAmountInput! ? 40.h : 20.h,
maxLength: isWalletAmountInput! ? 5 : 100,
onTapOutside: (event) {
FocusManager.instance.primaryFocus?.unfocus();
},
@ -332,6 +333,7 @@ class TextInputWidget extends StatelessWidget {
locale: const Locale('en', 'US'), // Force English locale for text style
),
decoration: InputDecoration(
counterText: "",
isDense: true,
hintText: hintText,
hintStyle: TextStyle(fontSize: 14.f, height: 21 / 16, fontWeight: FontWeight.w500, color: hintColor != null ? AppColors.textColor : Color(0xff898A8D), letterSpacing: -0.75),

Loading…
Cancel
Save