Merge branch 'master' into dev_aamir

pull/221/head
aamir-csol 16 hours ago
commit 7a0caa05c3

@ -34,7 +34,6 @@ android {
defaultConfig {
applicationId = "com.cloudsolutions.HMGPatientApp"
// minSdk = 24
// minSdk = 26
minSdk = 29
targetSdk = 35
compileSdk = 36

File diff suppressed because one or more lines are too long

@ -1249,7 +1249,7 @@
"quickLinks": "روابط سريعة",
"viewMedicalFileLandingPage": "عرض الملف الطبي",
"immediateLiveCareRequest": "طلب لايف كير فوري",
"yourTurnIsAfterPatients": "دورك بعد {count} مريض.",
"yourTurnIsAfterPatients": "دورك بعد {count} مريض. يرجى الانتظار حتى يحين دورك، وسيناديك الطبيب قريباً.",
"dontHaveHHCOrders": "ليس لديك أي أوامر رعاية صحية منزلية حتى الآن.",
"hhcOrders": "أوامر الرعاية الصحية المنزلية",
"requestedServices": "الخدمات المطلوبة",
@ -1578,7 +1578,7 @@
"noFreeSlot": "لا توجد مواعيد متاحة في التاريخ المحدد. يرجى اختيار تاريخ آخر أو إعادة المحاولة لاحقاً.",
"noThanksIKnowTheClinic": "لا، شكراً. أنا أعرف العيادة.",
"unableToSendOTP": "تعذر إرسال رمز التحقق لمرة واحدة",
"loadingAIAnalysis": "جارٍ تحليل نتائج المختبر، يرجى التحلي بالصبر والسماح للذكاء الاصطناعي بالقيام بالمهمة، قد يستغرق هذا بعض الوقت.",
"loadingAIAnalysis": "نقوم بتحليل نتائجك، يرجى التحلي بالصبر والسماح للذكاء الاصطناعي بالقيام بالمهمة، قد يستغرق هذا بعض الوقت.",
"symptoms": "أعراض",
"insuranceInActive": "التأمين غير نشط",
"insuranceInActiveContactSupport": "لديك تأمين ساري المفعول، ولكنه غير مُفعّل حاليًا في مجموعة حبيب الطبية. يُرجى التواصل مع خدمة عملاء مجموعة حبيب الطبية.",
@ -1689,5 +1689,7 @@
"openGallery": "افتح المعرض",
"openFiles": "فتح الملفات",
"generateAiAnalysisRadResult": "بإنشاء تحليل الذكاء الاصطناعي لهذا التقرير",
"grantLocationPermission": "يرجى منح إذن الوصول إلى الموقع من إعدادات التطبيق للحصول على نتائج أفضل."
"grantLocationPermission": "يرجى منح إذن الوصول إلى الموقع من إعدادات التطبيق للحصول على نتائج أفضل.",
"NoBookedAppointments": "لا توجد مواعيد محجوزة",
"aiDisclaimerRad": "سيتم مشاركة بيانات نتائج الأشعة الخاصة بك بشكل آمن مع محلل الذكاء الاصطناعي لدينا لتحليلها. يساعد هذا في توفير رؤى صحية مخصصة. هل ترغب في المتابعة؟"
}

@ -1572,7 +1572,7 @@
"contextDependent": "Context Dependent",
"calculatedValue": "Calculated Value",
"calculationFormula": "Calculation Formula",
"loadingAIAnalysis": "Analysing your lab results, Please be patient and let the AI do the magic, This might take some time.",
"loadingAIAnalysis": "Analysing your results, Please be patient and let the AI do the magic, This might take some time.",
"symptoms": "Symptoms",
"insuranceInActive": "Insurance Inactive",
"insuranceInActiveContactSupport": "You have a valid insurance but it is currently inactive in HMG. Please contact HMG customer support to activate it.",
@ -1681,5 +1681,7 @@
"openGallery": "Open Gallery",
"openFiles": "Open Files",
"generateAiAnalysisRadResult": "Generate AI analysis for this result",
"grantLocationPermission": "Please grant location permission from app settings to see better results."
"grantLocationPermission": "Please grant location permission from app settings to see better results.",
"NoBookedAppointments": "No Booked Appointments",
"aiDisclaimerRad": "Your radiology result data will be securely shared with our AI Analyzer for analysis. This helps provide personalized health insights. Do you want to proceed?"
}

@ -826,8 +826,8 @@ var FILTERED_PRODUCTS = 'products?categoryids=';
var GET_DOCTOR_LIST_CALCULATION = "Services/Doctors.svc/REST/GetCallculationDoctors";
var GET_ALL_APPOINTMENTS_FOR_DENTAL_CLINIC = "Services/Patients.svc/REST/GetDentalAppointments";
// var GET_ALL_APPOINTMENTS_FOR_DENTAL_CLINIC = "Services/Patients.svc/REST/GetDentalAppointments";
var GET_ALL_APPOINTMENTS_FOR_DENTAL_CLINIC ='Services/Patients.svc/REST/GetAllInvoices';
var GET_DENTAL_APPOINTMENT_INVOICE = "Services/Patients.svc/REST/HIS_eInvoiceForDentalByAppointmentNo";
var SEND_DENTAL_APPOINTMENT_INVOICE_EMAIL = "Services/Notifications.svc/REST/SendInvoiceForDental";

@ -415,4 +415,6 @@ class AppAnimations {
static const String ambulance = '$lottieBasePath/ambulance.json';
static const String ambulanceAlert = '$lottieBasePath/ambulance_alert.json';
static const String rrtAmbulance = '$lottieBasePath/rrt_ambulance.json';
static const String hourGlass = '$lottieBasePath/HourGlass.json';
}

@ -155,6 +155,7 @@ extension SmoothContainerExtension on ShapeBorder {
BorderRadius? customBorder,
bool hasShadow = false,
bool hasDenseShadow = false,
List<BoxShadow>? isCustomShadow,
}) {
final bgColor = backgroundColor ?? color;
return ShapeDecoration(
@ -174,7 +175,7 @@ extension SmoothContainerExtension on ShapeBorder {
offset: const Offset(1, 0),
)
]
: [],
: isCustomShadow ?? [],
);
}
}

@ -402,7 +402,11 @@ class BookAppointmentsViewModel extends ChangeNotifier {
refreshDoctorsList() {
setIsDoctorsListLoading(true);
getDoctorsList(isNearest: isNearestAppointmentSelected);
if(selectedClinic.clinicID == 17) {
getDentalChiefComplaintDoctorsList(projectID: currentlySelectedHospitalFromRegionFlow != null ? int.parse(currentlySelectedHospitalFromRegionFlow!) : 0);
} else {
getDoctorsList(isNearest: isNearestAppointmentSelected);
}
}
setIsNearestAppointmentSelected(bool isNearestAppointmentSelected) {
@ -861,8 +865,8 @@ class BookAppointmentsViewModel extends ChangeNotifier {
}
initialSlotDuration = apiResponse.data["InitialSlotDuration"];
freeSlotsResponse = apiResponse.data['FreeTimeSlots'];
// isWaitingAppointmentAvailable = apiResponse.data["IsAllowToBookWaitingAppointment"];
isWaitingAppointmentAvailable = true;
isWaitingAppointmentAvailable = apiResponse.data["IsAllowToBookWaitingAppointment"];
// isWaitingAppointmentAvailable = true;
freeSlotsResponse.forEach((element) {
// date = (isLiveCareSchedule != null && isLiveCareSchedule)
@ -1044,7 +1048,8 @@ class BookAppointmentsViewModel extends ChangeNotifier {
);
LoaderBottomSheet.showLoader(
loadingText: LocaleKeys.reschedulingAppo.tr(context: navigationService.navigatorKey.currentContext!),
// loadingText: LocaleKeys.reschedulingAppo.tr(context: navigationService.navigatorKey.currentContext!),
loadingText: LocaleKeys.loadingText.tr(context: navigationService.navigatorKey.currentContext!),
);
await cancelAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel).then((val) async {
LoaderBottomSheet.hideLoader();
@ -1466,7 +1471,10 @@ class BookAppointmentsViewModel extends ChangeNotifier {
}
Future<void> getDentalChiefComplaintDoctorsList({int projectID = 0, Function(dynamic)? onSuccess, Function(String)? onError}) async {
setIsNearestAppointmentSelected(false);
doctorsList.clear();
notifyListeners();
projectID = currentlySelectedHospitalFromRegionFlow != null ? int.parse(currentlySelectedHospitalFromRegionFlow!) : projectID;
final result = await bookAppointmentsRepo.getDentalChiefComplaintDoctorsList(projectID, selectedChiefComplaintID);
@ -1485,6 +1493,7 @@ class BookAppointmentsViewModel extends ChangeNotifier {
// clearSearchFilters();
// getFiltersFromDoctorList();
_groupDoctorsList();
setIsNearestAppointmentSelected(isNearestAppointmentSelected);
notifyListeners();
if (onSuccess != null) {
onSuccess(apiResponse);

@ -713,7 +713,7 @@ class EmergencyServicesViewModel extends ChangeNotifier {
appointments = response.data;
if (appointments?.isEmpty == true) {
haveAnAppointment = false;
dialogService.showErrorBottomSheet(message: "Unable to Fetch Appointment");
dialogService.showErrorBottomSheet(message: LocaleKeys.NoBookedAppointments.tr());
}
notifyListeners();
});

@ -676,9 +676,9 @@ class MyAppointmentsViewModel extends ChangeNotifier {
Future<void> getPatientFavouriteDoctors({bool forceRefresh = false, Function(dynamic)? onSuccess, Function(String)? onError}) async {
// If data is already fetched and not forcing refresh, skip API call
// if (isFavouriteDoctorsDataFetched && !forceRefresh) {
// return;
// }
if (isFavouriteDoctorsDataFetched && !forceRefresh) {
return;
}
isPatientFavouriteDoctorsLoading = true;
patientFavouriteDoctorsList.clear();

@ -1,88 +1,93 @@
import 'dart:convert';
class GetInvoicesListResponseModel {
String? setupId;
int? projectID;
int? patientID;
int? projectId;
int? patientId;
int? appointmentNo;
String? appointmentDate;
String? appointmentDateN;
int? clinicID;
int? doctorID;
dynamic appointmentDateN;
int? clinicId;
int? doctorId;
int? invoiceNo;
int? status;
String? arrivedOn;
String? doctorName;
String? doctorNameN;
String? clinicName;
num? decimalDoctorRate;
String? doctorImageURL;
num? doctorRate;
num? patientNumber;
double? decimalDoctorRate;
String? doctorImageUrl;
int? doctorRate;
int? patientNumber;
String? projectName;
GetInvoicesListResponseModel(
{this.setupId,
this.projectID,
this.patientID,
this.appointmentNo,
this.appointmentDate,
this.appointmentDateN,
this.clinicID,
this.doctorID,
this.invoiceNo,
this.status,
this.arrivedOn,
this.doctorName,
this.doctorNameN,
this.clinicName,
this.decimalDoctorRate,
this.doctorImageURL,
this.doctorRate,
this.patientNumber,
this.projectName});
GetInvoicesListResponseModel({
this.setupId,
this.projectId,
this.patientId,
this.appointmentNo,
this.appointmentDate,
this.appointmentDateN,
this.clinicId,
this.doctorId,
this.invoiceNo,
this.status,
this.arrivedOn,
this.doctorName,
this.doctorNameN,
this.clinicName,
this.decimalDoctorRate,
this.doctorImageUrl,
this.doctorRate,
this.patientNumber,
this.projectName,
});
factory GetInvoicesListResponseModel.fromRawJson(String str) => GetInvoicesListResponseModel.fromJson(json.decode(str));
String toRawJson() => json.encode(toJson());
GetInvoicesListResponseModel.fromJson(Map<String, dynamic> json) {
setupId = json['SetupId'];
projectID = json['ProjectID'];
patientID = json['PatientID'];
appointmentNo = json['AppointmentNo'];
appointmentDate = json['AppointmentDate'];
appointmentDateN = json['AppointmentDateN'];
clinicID = json['ClinicID'];
doctorID = json['DoctorID'];
invoiceNo = json['InvoiceNo'];
status = json['Status'];
arrivedOn = json['ArrivedOn'];
doctorName = json['DoctorName'];
doctorNameN = json['DoctorNameN'];
clinicName = json['ClinicName'];
decimalDoctorRate = json['DecimalDoctorRate'];
doctorImageURL = json['DoctorImageURL'];
doctorRate = json['DoctorRate'];
patientNumber = json['PatientNumber'];
projectName = json['ProjectName'];
}
factory GetInvoicesListResponseModel.fromJson(Map<String, dynamic> json) => GetInvoicesListResponseModel(
setupId: json["SetupId"],
projectId: json["ProjectID"],
patientId: json["PatientID"],
appointmentNo: json["AppointmentNo"],
appointmentDate: json["AppointmentDate"],
appointmentDateN: json["AppointmentDateN"],
clinicId: json["ClinicID"],
doctorId: json["DoctorID"],
invoiceNo: json["InvoiceNo"],
status: json["Status"],
arrivedOn: json["ArrivedOn"],
doctorName: json["DoctorName"],
doctorNameN: json["DoctorNameN"],
clinicName: json["ClinicName"],
decimalDoctorRate: json["DecimalDoctorRate"]?.toDouble(),
doctorImageUrl: json["DoctorImageURL"],
doctorRate: json["DoctorRate"],
patientNumber: json["PatientNumber"],
projectName: json["ProjectName"],
);
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['SetupId'] = this.setupId;
data['ProjectID'] = this.projectID;
data['PatientID'] = this.patientID;
data['AppointmentNo'] = this.appointmentNo;
data['AppointmentDate'] = this.appointmentDate;
data['AppointmentDateN'] = this.appointmentDateN;
data['ClinicID'] = this.clinicID;
data['DoctorID'] = this.doctorID;
data['InvoiceNo'] = this.invoiceNo;
data['Status'] = this.status;
data['ArrivedOn'] = this.arrivedOn;
data['DoctorName'] = this.doctorName;
data['DoctorNameN'] = this.doctorNameN;
data['ClinicName'] = this.clinicName;
data['DecimalDoctorRate'] = this.decimalDoctorRate;
data['DoctorImageURL'] = this.doctorImageURL;
data['DoctorRate'] = this.doctorRate;
data['PatientNumber'] = this.patientNumber;
data['ProjectName'] = this.projectName;
return data;
}
Map<String, dynamic> toJson() => {
"SetupId": setupId,
"ProjectID": projectId,
"PatientID": patientId,
"AppointmentNo": appointmentNo,
"AppointmentDate": appointmentDate,
"AppointmentDateN": appointmentDateN,
"ClinicID": clinicId,
"DoctorID": doctorId,
"InvoiceNo": invoiceNo,
"Status": status,
"ArrivedOn": arrivedOn,
"DoctorName": doctorName,
"DoctorNameN": doctorNameN,
"ClinicName": clinicName,
"DecimalDoctorRate": decimalDoctorRate,
"DoctorImageURL": doctorImageUrl,
"DoctorRate": doctorRate,
"PatientNumber": patientNumber,
"ProjectName": projectName,
};
}

@ -38,7 +38,7 @@ class MyInvoicesRepoImp implements MyInvoicesRepo {
},
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
final list = response['List_DentalAppointments'];
final list = response['List_AllInvoices'];
final invoicesList = list.map((item) => GetInvoicesListResponseModel.fromJson(item as Map<String, dynamic>)).toList().cast<GetInvoicesListResponseModel>();

@ -1681,5 +1681,7 @@ abstract class LocaleKeys {
static const openFiles = 'openFiles';
static const generateAiAnalysisRadResult = 'generateAiAnalysisRadResult';
static const grantLocationPermission = 'grantLocationPermission';
static const NoBookedAppointments = 'NoBookedAppointments';
static const aiDisclaimerRad = 'aiDisclaimerRad';
}

@ -10,6 +10,7 @@ import 'package:flutter/services.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/theme/colors.dart';
import 'package:hmg_patient_app_new/features/ask_doctor/ask_doctor_view_model.dart';
import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart';
import 'package:hmg_patient_app_new/features/blood_donation/blood_donation_view_model.dart';
@ -50,6 +51,7 @@ import 'package:hmg_patient_app_new/routes/app_routes.dart';
import 'package:hmg_patient_app_new/services/logger_service.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart';
import 'package:hmg_patient_app_new/theme/app_theme.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/date_range_selector/viewmodel/date_range_view_model.dart' show DateRangeSelectorRangeViewModel;
import 'package:provider/provider.dart';
import 'package:provider/single_child_widget.dart';

@ -393,8 +393,8 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
),
const Spacer(),
Switch(
// activeThumbColor: AppColors.successColor,
activeTrackColor: AppColors.successColor.withValues(alpha: .15),
activeThumbColor: AppColors.successColor,
// activeTrackColor: AppColors.successColor.withValues(alpha: .15),
value: widget.patientAppointmentHistoryResponseModel.hasReminder!,
onChanged: (newValue) async {
CalenderUtilsNew calender = CalenderUtilsNew.instance;
@ -612,7 +612,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
isLocked: false,
).toShimmer2()
: MedicalFileCard(
label: !((myAppointmentsVM.appointmentRatedResponseModel!).isAppointmentRated ?? true)
label: !((myAppointmentsVM.appointmentRatedResponseModel!).isAllowedToRate ?? false)
? LocaleKeys.ratingSubmitted.tr(context: context)
: LocaleKeys.doctorRatingAppointment.tr(context: context),
textColor: AppColors.blackColor,
@ -620,9 +620,9 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
svgIcon: AppAssets.appointmentRatingIcon,
isLargeText: true,
iconSize: 36.w,
isLocked: !(myAppointmentsVM.appointmentRatedResponseModel!.isAppointmentRated ?? true),
isLocked: !(myAppointmentsVM.appointmentRatedResponseModel!.isAllowedToRate ?? false),
).onPress(() {
if(!(myAppointmentsVM.appointmentRatedResponseModel!.isAppointmentRated ?? true)) {
if ((myAppointmentsVM.appointmentRatedResponseModel!.isAllowedToRate ?? true)) {
showCommonBottomSheetWithoutHeight(
context,
title: LocaleKeys.doctorRating.tr(context: context),

@ -15,6 +15,7 @@ import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.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:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:lottie/lottie.dart';
import 'package:provider/provider.dart';
class AppointmentQueuePage extends StatelessWidget {
@ -32,13 +33,14 @@ class AppointmentQueuePage extends StatelessWidget {
children: [
Expanded(
child: CollapsingListView(
title: LocaleKeys.queueing.tr(context: context),
title: LocaleKeys.queueing.tr(context: context),
child: RefreshIndicator(
color: AppColors.primaryRedColor,
onRefresh: () async {
await myAppointmentsVM.getPatientAppointmentQueueDetails();
},
child: SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
child: Padding(
padding: EdgeInsets.all(24.0),
child: Column(
@ -59,13 +61,21 @@ class AppointmentQueuePage extends StatelessWidget {
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AppCustomChipWidget(
labelText: myAppointmentsVM.currentQueueStatus == 0 ? LocaleKeys.inQueue.tr(context: context) : LocaleKeys.yourTurn.tr(context: context),
backgroundColor: Utils.getCardBorderColor(myAppointmentsVM.currentQueueStatus).withValues(alpha: 0.20),
textColor: Utils.getCardBorderColor(myAppointmentsVM.currentQueueStatus),
),
Utils.buildSvgWithAssets(icon: AppAssets.waiting_icon, width: 24.h, height: 24.h),
Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.greyColor,
borderRadius: 10.h,
hasShadow: false,
),
padding: EdgeInsets.all(6.h),
child: Lottie.asset(AppAnimations.hourGlass, repeat: true, reverse: false, frameRate: FrameRate(60), width: 40.h, height: 40.h, fit: BoxFit.fill)),
],
).toShimmer2(isShow: myAppointmentsVM.isAppointmentQueueDetailsLoading),
SizedBox(height: 10.h),
@ -189,9 +199,9 @@ class AppointmentQueuePage extends StatelessWidget {
],
),
),
),
),
),
),
),
Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(

@ -205,7 +205,7 @@ class AppointmentCard extends StatelessWidget {
richText: isLoading
? 'Cardiology'.toText10().toShimmer2(isShow: isLoading)
: "${DateUtil.formatDateToDate(DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate), false)} ${DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate), false)}"
.toText10(isEnglishOnly: true),
.toText10(isEnglishOnly: true, isBold: true),
).toShimmer2(isShow: isLoading),
),
@ -243,42 +243,123 @@ class AppointmentCard extends StatelessWidget {
(patientAppointmentHistoryResponseModel.isExecludeDoctor ?? false) ||
!Utils.isClinicAllowedForRebook(patientAppointmentHistoryResponseModel.clinicID ?? 0))) &&
AppointmentType.isArrived(patientAppointmentHistoryResponseModel)) {
return CustomButton(
text: isFromMedicalReport ? LocaleKeys.selectAppointment.tr(context: context) : LocaleKeys.viewDetails.tr(context: context),
onPressed: () {
if (isFromMedicalReport) {
if (isForFeedback) {
contactUsViewModel!.setPatientFeedbackSelectedAppointment(patientAppointmentHistoryResponseModel);
if (((patientAppointmentHistoryResponseModel.isLiveCareAppointment ?? false) &&
DateTime.now().difference(DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate)).inDays <= 15)) {
return Row(
children: [
Expanded(
flex: 6,
child: CustomButton(
text: LocaleKeys.askDoctor.tr(context: context),
onPressed: () async {
LoaderBottomSheet.showLoader(loadingText: LocaleKeys.checkingDoctorAvailability.tr(context: context));
await myAppointmentsViewModel.isDoctorAvailable(
projectID: patientAppointmentHistoryResponseModel.projectID,
doctorId: patientAppointmentHistoryResponseModel.doctorID,
clinicId: patientAppointmentHistoryResponseModel.clinicID,
onSuccess: (value) async {
if (value) {
await myAppointmentsViewModel.getAskDoctorRequestTypes(onSuccess: (val) {
LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight(
context,
title: LocaleKeys.askDoctor.tr(context: context),
child: AskDoctorRequestTypeSelect(
askDoctorRequestTypeList: myAppointmentsViewModel.askDoctorRequestTypeList,
myAppointmentsViewModel: myAppointmentsViewModel,
patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel,
),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
});
} else {
print("Doctor is not available");
}
});
},
backgroundColor: AppColors.secondaryLightRedColor,
borderColor: AppColors.secondaryLightRedColor,
textColor: AppColors.primaryRedColor,
fontSize: (isFoldable || isTablet) ? 12.f : 14.f,
fontWeight: FontWeight.w600,
borderRadius: 12.r,
padding: EdgeInsets.symmetric(horizontal: 10.w),
// height: isTablet || isFoldable ? 46.h : 40.h,
height: 40.h,
icon: AppAssets.ask_doctor_icon,
iconColor: AppColors.primaryRedColor,
iconSize: 16.h,
),
),
SizedBox(width: 8.h),
Expanded(
flex: 1,
child: Container(
height: (isFoldable || isTablet) ? 50.h : 40.h,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.textColor,
borderRadius: 10.h,
side: BorderSide(
color: AppColors.textColor,
width: 1.2,
),
),
child: Transform.flip(
flipX: appState.isArabic(),
child: Utils.buildSvgWithAssets(
icon: AppAssets.forward_arrow_icon,
iconColor: AppColors.whiteColor,
width: 24.w,
height: 24.h,
fit: BoxFit.contain,
),
),
).toShimmer2(isShow: isLoading).onPress(() {
_goToDetails(context);
}),
),
],
);
} else {
return CustomButton(
text: isFromMedicalReport ? LocaleKeys.selectAppointment.tr(context: context) : LocaleKeys.viewDetails.tr(context: context),
onPressed: () {
if (isFromMedicalReport) {
if (isForFeedback) {
contactUsViewModel!.setPatientFeedbackSelectedAppointment(patientAppointmentHistoryResponseModel);
} else {
medicalFileViewModel!.setSelectedMedicalReportAppointment(patientAppointmentHistoryResponseModel);
}
Navigator.pop(context, false);
} else {
medicalFileViewModel!.setSelectedMedicalReportAppointment(patientAppointmentHistoryResponseModel);
Navigator.of(context)
.push(
CustomPageRoute(
page: AppointmentDetailsPage(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel),
),
)
.then((_) {
myAppointmentsViewModel.initAppointmentsViewModel();
myAppointmentsViewModel.getPatientAppointments(true, false);
});
}
Navigator.pop(context, false);
} else {
Navigator.of(context)
.push(
CustomPageRoute(
page: AppointmentDetailsPage(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel),
),
)
.then((_) {
myAppointmentsViewModel.initAppointmentsViewModel();
myAppointmentsViewModel.getPatientAppointments(true, false);
});
}
},
backgroundColor: AppColors.secondaryLightRedColor,
borderColor: AppColors.secondaryLightRedColor,
textColor: AppColors.primaryRedColor,
fontSize: (isFoldable || isTablet) ? 12.f : 14.f,
fontWeight: FontWeight.w600,
borderRadius: 12.r,
padding: EdgeInsets.symmetric(horizontal: 10.w),
// height: isTablet || isFoldable ? 46.h : 40.h,
height: 40.h,
icon: isFromMedicalReport ? AppAssets.checkmark_icon : null,
iconColor: AppColors.primaryRedColor,
iconSize: 16.h,
);
},
backgroundColor: AppColors.secondaryLightRedColor,
borderColor: AppColors.secondaryLightRedColor,
textColor: AppColors.primaryRedColor,
fontSize: (isFoldable || isTablet) ? 12.f : 14.f,
fontWeight: FontWeight.w600,
borderRadius: 12.r,
padding: EdgeInsets.symmetric(horizontal: 10.w),
// height: isTablet || isFoldable ? 46.h : 40.h,
height: 40.h,
icon: isFromMedicalReport ? AppAssets.checkmark_icon : null,
iconColor: AppColors.primaryRedColor,
iconSize: 16.h,
);
}
} else {
if (isFromMedicalReport) {
if (isForEyeMeasurements) {
@ -309,7 +390,6 @@ class AppointmentCard extends StatelessWidget {
);
}
}
return Row(
children: [
Expanded(
@ -415,6 +495,10 @@ class AppointmentCard extends StatelessWidget {
}
return CustomButton(
borderSide: BorderSide(
color: AppColors.textColor,
width: 1.2,
),
text: LocaleKeys.rebookSameDoctor.tr(context: context),
onPressed: () => openDoctorScheduleCalendar(context),
backgroundColor: AppColors.transparent,

@ -168,7 +168,7 @@ class AppointmentCheckinBottomSheet extends StatelessWidget {
// page: AppointmentQueuePage(),
// ),
// );
}, isFullScreen: false);
}, isFullScreen: false, isAutoDismiss: true, isCloseButtonVisible: false);
},
onError: (error) {
LoaderBottomSheet.hideLoader();

@ -8,6 +8,7 @@ import 'package:hmg_patient_app_new/core/utils/date_util.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/authentication/login.dart';
@ -89,15 +90,11 @@ class _SavedLogin extends State<SavedLogin> {
: SizedBox(),
SizedBox(height: 24.h),
Container(
padding: EdgeInsets.all(16.h),
decoration: BoxDecoration(
color: AppColors.whiteColor,
border: Border.all(color: AppColors.whiteColor),
borderRadius: BorderRadius.circular(24.h),
boxShadow: [
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 20.h, hasShadow: false, isCustomShadow: [
BoxShadow(color: Color(0x0D000000), blurRadius: 16.h, offset: Offset(0, 0), spreadRadius: 5.h),
],
),
]),
child: Column(
children: [
// Last login info - show WhatsApp only if isOther AND loginType is SMS

@ -215,8 +215,8 @@ class ImmediateLiveCarePaymentDetails extends StatelessWidget {
children: [
LocaleKeys.amountBeforeTax.tr(context: context).toText14(isBold: true),
Utils.getPaymentAmountWithSymbol((immediateLiveCareVM.liveCareImmediateAppointmentFeesList.amount ?? "").toText16(isBold: true, isEnglishOnly: true), AppColors.blackColor, 13,
isSaudiCurrency: immediateLiveCareVM.liveCareImmediateAppointmentFeesList.currency!.toLowerCase() == "sar" ||
immediateLiveCareVM.liveCareImmediateAppointmentFeesList.currency!.toLowerCase() == "ريال"),
isSaudiCurrency: (immediateLiveCareVM.liveCareImmediateAppointmentFeesList.currency ?? "sar").toLowerCase() == "sar" ||
(immediateLiveCareVM.liveCareImmediateAppointmentFeesList.currency ?? "ريال").toLowerCase() == "ريال"),
],
).paddingSymmetrical(24.h, 0.h),
Row(
@ -224,9 +224,9 @@ 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, isEnglishOnly: true), AppColors.greyTextColor, 13,
isSaudiCurrency: (immediateLiveCareVM.liveCareImmediateAppointmentFeesList.currency!.toLowerCase() == "sar" ||
immediateLiveCareVM.liveCareImmediateAppointmentFeesList.currency!.toLowerCase() == "ريال")),
(immediateLiveCareVM.liveCareImmediateAppointmentFeesList.tax ?? "0.0").toText14(isBold: true, color: AppColors.greyTextColor, isEnglishOnly: true), AppColors.greyTextColor, 13,
isSaudiCurrency: ((immediateLiveCareVM.liveCareImmediateAppointmentFeesList.currency ?? "sar").toLowerCase() == "sar" ||
(immediateLiveCareVM.liveCareImmediateAppointmentFeesList.currency ?? "ريال").toLowerCase() == "ريال")),
],
).paddingSymmetrical(24.h, 0.h),
SizedBox(height: 17.h),
@ -234,9 +234,9 @@ class ImmediateLiveCarePaymentDetails extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(width: 200.h, child: Utils.getPaymentMethods()),
Utils.getPaymentAmountWithSymbol(immediateLiveCareVM.liveCareImmediateAppointmentFeesList.total!.toText24(isBold: true, isEnglishOnly: true), AppColors.blackColor, 17,
isSaudiCurrency: (immediateLiveCareVM.liveCareImmediateAppointmentFeesList.currency!.toLowerCase() == "sar" ||
immediateLiveCareVM.liveCareImmediateAppointmentFeesList.currency!.toLowerCase() == "ريال")),
Utils.getPaymentAmountWithSymbol((immediateLiveCareVM.liveCareImmediateAppointmentFeesList.total ?? "0.0").toText24(isBold: true, isEnglishOnly: true), AppColors.blackColor, 17,
isSaudiCurrency: ((immediateLiveCareVM.liveCareImmediateAppointmentFeesList.currency ?? "sar").toLowerCase() == "sar" ||
(immediateLiveCareVM.liveCareImmediateAppointmentFeesList.currency ?? "ريال").toLowerCase() == "ريال")),
],
).paddingSymmetrical(24.h, 0.h),
(immediateLiveCareVM.liveCareImmediateAppointmentFeesList.total == "0" || immediateLiveCareVM.liveCareImmediateAppointmentFeesList.total == "0.0")

@ -264,7 +264,7 @@ class _ImmediateLiveCarePaymentPageState extends State<ImmediateLiveCarePaymentP
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
LocaleKeys.amountBeforeTax.tr().toText14(isBold: true),
Utils.getPaymentAmountWithSymbol(immediateLiveCareViewModel.liveCareImmediateAppointmentFeesList.amount!.toString().toText16(isBold: true), AppColors.blackColor, 13,
Utils.getPaymentAmountWithSymbol((immediateLiveCareViewModel.liveCareImmediateAppointmentFeesList.amount ?? "0.0").toString().toText16(isBold: true), AppColors.blackColor, 13,
isSaudiCurrency: true),
],
).paddingSymmetrical(24.h, 0.h),
@ -273,7 +273,7 @@ class _ImmediateLiveCarePaymentPageState extends State<ImmediateLiveCarePaymentP
children: [
LocaleKeys.vat15.tr().toText14(isBold: true, color: AppColors.greyTextColor),
Utils.getPaymentAmountWithSymbol(
immediateLiveCareViewModel.liveCareImmediateAppointmentFeesList.tax!.toString().toText14(isBold: true, color: AppColors.greyTextColor), AppColors.greyTextColor, 13,
(immediateLiveCareViewModel.liveCareImmediateAppointmentFeesList.tax ?? "0.0").toString().toText14(isBold: true, color: AppColors.greyTextColor), AppColors.greyTextColor, 13,
isSaudiCurrency: true),
],
).paddingSymmetrical(24.h, 0.h),
@ -282,7 +282,7 @@ class _ImmediateLiveCarePaymentPageState extends State<ImmediateLiveCarePaymentP
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"".toText14(isBold: true),
Utils.getPaymentAmountWithSymbol(immediateLiveCareViewModel.liveCareImmediateAppointmentFeesList.total!.toString().toText24(isBold: true), AppColors.blackColor, 17,
Utils.getPaymentAmountWithSymbol((immediateLiveCareViewModel.liveCareImmediateAppointmentFeesList.total ?? "0.0").toString().toText24(isBold: true), AppColors.blackColor, 17,
isSaudiCurrency: true),
],
).paddingSymmetrical(24.h, 0.h),
@ -466,7 +466,7 @@ class _ImmediateLiveCarePaymentPageState extends State<ImmediateLiveCarePaymentP
//TODO: Need to pass dynamic params to the payment request instead of static values
browser?.openPaymentBrowser(
num.parse(immediateLiveCareViewModel.liveCareImmediateAppointmentFeesList.total!),
num.parse(immediateLiveCareViewModel.liveCareImmediateAppointmentFeesList.total ?? "0.0"),
"LiveCare Payment",
transID,
"12",
@ -547,7 +547,7 @@ class _ImmediateLiveCarePaymentPageState extends State<ImmediateLiveCarePaymentP
// customerEmail: projectViewModel.authenticatedUserObject.user.emailAddress,
customerEmail: "CustID_${appState.getAuthenticatedUser()!.patientId.toString()}@HMG.com",
orderDescription: "LiveCare Payment",
orderAmount: double.parse(immediateLiveCareViewModel.liveCareImmediateAppointmentFeesList.total!),
orderAmount: double.parse((immediateLiveCareViewModel.liveCareImmediateAppointmentFeesList.total ?? "0.0")),
merchantReference: transID,
merchantIdentifier: payfortViewModel.payfortProjectDetailsRespModel!.merchantIdentifier,
applePayAccessCode: payfortViewModel.payfortProjectDetailsRespModel!.accessCode,

@ -17,6 +17,7 @@ import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.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:hmg_patient_app_new/widgets/countdown_timer.dart';
import 'package:lottie/lottie.dart';
import 'package:provider/provider.dart';
import 'package:url_launcher/url_launcher.dart';
@ -97,17 +98,28 @@ class _ImmediateLiveCarePendingRequestPageState extends State<ImmediateLiveCareP
SizedBox(width: 8.w),
AppCustomChipWidget(
icon: AppAssets.appointment_calendar_icon,
labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(immediateLiveCareViewModel.patientLiveCareHistoryList[0].arrivalTime), false)),
labelText: DateUtil.formatDateToDate(
DateUtil.convertStringToDate(
immediateLiveCareViewModel.patientLiveCareHistoryList.isNotEmpty ? immediateLiveCareViewModel.patientLiveCareHistoryList[0].arrivalTime : ""),
false)),
],
),
Utils.buildSvgWithAssets(icon: AppAssets.waiting_icon, width: 24.h, height: 24.h),
Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.greyColor,
borderRadius: 10.h,
hasShadow: false,
),
padding: EdgeInsets.all(6.h),
child: Lottie.asset(AppAnimations.hourGlass, repeat: true, reverse: false, frameRate: FrameRate(60), width: 40.h, height: 40.h, fit: BoxFit.fill)),
// Lottie.asset(AppAnimations.pending_loading_animation, repeat: true, reverse: false, frameRate: FrameRate(60), width: 80.h, height: 80.h, fit: BoxFit.cover),
],
),
SizedBox(height: 8.h),
SizedBox(height: 8.h),
LocaleKeys.yourTurnIsAfterPatients
.tr(namedArgs: {'count': (immediateLiveCareViewModel.patientLiveCareHistoryList[0].patCount ?? 0).toString()}, context: context).toText14(isBold: true),
LocaleKeys.yourTurnIsAfterPatients.tr(namedArgs: {
'count': (immediateLiveCareViewModel.patientLiveCareHistoryList.isNotEmpty ? immediateLiveCareViewModel.patientLiveCareHistoryList[0].patCount ?? 0 : 0).toString()
}, context: context).toText14(isBold: true),
// "Your turn is after ${immediateLiveCareViewModel.patientLiveCareHistoryList[0].patCount} patients.".toText16(isBold: true),
SizedBox(height: 8.h),
],
@ -127,7 +139,7 @@ class _ImmediateLiveCarePendingRequestPageState extends State<ImmediateLiveCareP
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Expected waiting time: ".toText16(isBold: true),
LocaleKeys.waitingTime.tr(context: context).toText16(isBold: true),
SizedBox(height: 8.h),
ValueListenableBuilder<Duration>(
valueListenable: immediateLiveCareVM.durationNotifier,

@ -317,7 +317,8 @@ class _ReviewAppointmentPageState extends State<ReviewAppointmentPage> {
void initiateBookAppointment() async {
// LoadingUtils.showFullScreenLoader(barrierDismissible: true, isSuccessDialog: false, loadingText: bookAppointmentsViewModel.isPatientRescheduleAppointment ? LocaleKeys.reschedulingAppo.tr(context: context) : LocaleKeys.bookingYourAppointment.tr(context: context));
LoaderBottomSheet.showLoader(loadingText: bookAppointmentsViewModel.isPatientRescheduleAppointment ? LocaleKeys.reschedulingAppo.tr(context: context) : LocaleKeys.bookingYourAppointment.tr(context: context));
// LoaderBottomSheet.showLoader(loadingText: bookAppointmentsViewModel.isPatientRescheduleAppointment ? LocaleKeys.reschedulingAppo.tr(context: context) : LocaleKeys.bookingYourAppointment.tr(context: context));
LoaderBottomSheet.showLoader(loadingText: LocaleKeys.loadingText.tr(context: context));
myAppointmentsViewModel.setIsAppointmentDataToBeLoaded(true);
if (bookAppointmentsViewModel.isLiveCareSchedule) {

@ -1079,7 +1079,8 @@ class _SelectClinicPageState extends State<SelectClinicPage> {
// }
var bottomSheetType = RegionBottomSheetType.FOR_CLINIIC;
if (clinic.clinicID == 17) {
regionalViewModel.setBottomSheetState(AppointmentViaRegionState.HOSPITAL_SELECTION);
// regionalViewModel.setBottomSheetState(AppointmentViaRegionState.HOSPITAL_SELECTION);
// bottomSheetType = RegionBottomSheetType.REGION_FOR_DENTAL_AND_LASER;
bottomSheetType = RegionBottomSheetType.REGION_FOR_DENTAL_AND_LASER;
}
// if (clinic.clinicID == 253) {

@ -44,7 +44,7 @@ class _NearestErPageState extends State<NearestErPage> {
children: [
TextInputWidget(
labelText: LocaleKeys.search.tr(),
hintText: 'Type any facility name',
hintText: '',
controller: searchText,
onChange: (value) {
debouncer.run(() {

@ -59,7 +59,7 @@ class NearestERItem extends StatelessWidget {
Expanded(
child: (nearestERItem.projectName?.toText16(
color: AppColors.textColor,
weight: FontWeight.w600,
isBold: true
) ??
SizedBox.shrink()).toShimmer2(isShow: isLoading),
),
@ -84,7 +84,7 @@ class NearestERItem extends StatelessWidget {
Directionality(
textDirection: ui.TextDirection.ltr,
child: AppCustomChipWidget(
labelText: "Expected waiting time: ${nearestERItem.getTime()} mins",
labelText: "${LocaleKeys.waitingTime.tr(context: context)} ${nearestERItem.getTime()} ${LocaleKeys.mins.tr(context: context)}",
icon: AppAssets.waiting_time_clock,
iconHasColor: false,
labelPadding: EdgeInsetsDirectional.only(start: 4.h, end: 0.h),
@ -109,14 +109,14 @@ class NearestERItem extends StatelessWidget {
borderColor: AppColors.secondaryLightRedColor,
textColor: AppColors.primaryRedColor,
iconColor: AppColors.primaryRedColor,
height: 40.h,
height: 46.h,
fontSize: 14.f,
isBold: true,
).toShimmer2(isShow: isLoading),
),
SizedBox(width: 8.h),
SizedBox(
height: 40.h,
height: 46.h,
width: 40.h,
child: CustomButton(
text: '',
@ -124,12 +124,11 @@ class NearestERItem extends StatelessWidget {
icon: AppAssets.call_fill,
onPressed: () {
context.read<EmergencyServicesViewModel>().openDialer( nearestERItem.phonenumber??"");
},
backgroundColor: AppColors.greyColor,
iconColor: AppColors.textColor,
borderColor: AppColors.greyColor,
height: 40.h,
height: 46.h,
).toShimmer2(isShow: isLoading),
),
],

@ -74,7 +74,8 @@ 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(isBold: true, color: AppColors.greyTextColor, isEnglishOnly: true),
"${LocaleKeys.fileno.tr(context: context)}: ${_appState.getAuthenticatedUser()!.patientId!}"
.toText14(isBold: true, color: AppColors.greyTextColor, isEnglishOnly: true),
],
).expanded,
Utils.buildSvgWithAssets(icon: AppAssets.habiblogo, width: 24.h, height: 24.h, applyThemeColor: false),
@ -84,8 +85,15 @@ class _HabibWalletState extends State<HabibWalletPage> {
LocaleKeys.balanceAmount.tr(context: context).toText14(isBold: true, color: Colors.white),
SizedBox(height: 4.h),
Consumer<HabibWalletViewModel>(builder: (context, habibWalletVM, child) {
return Utils.getPaymentAmountWithSymbol2(num.parse(NumberFormat.decimalPattern().format(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,
letterSpacing: -1)
.toShimmer2(isShow: habibWalletVM.isWalletAmountLoading, radius: 12.h, width: 80.h, height: 24.h);
}),
],
@ -140,7 +148,7 @@ class _HabibWalletState extends State<HabibWalletPage> {
children: [
Expanded(child: habibWalletVM.habibWalletBalanceList[index].projectDescription!.toText16(isBold: true, color: AppColors.textColor)),
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.w600,),
textColor: AppColors.textColor, iconColor: AppColors.textColor, iconSize: 18.h, isExpanded: false, fontSize: 28.f, fontWeight: FontWeight.w600, letterSpacing: -1),
],
).paddingSymmetrical(0, 12.h);
},

@ -69,6 +69,7 @@ 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:lottie/lottie.dart';
import 'package:provider/provider.dart';
import 'package:smooth_corner/smooth_corner.dart';
@ -264,15 +265,15 @@ class _LandingPageState extends State<LandingPage> {
borderColor: AppColors.secondaryLightRedColor,
textColor: AppColors.primaryRedColor,
fontSize: 14.f,
fontWeight: FontWeight.w600,
borderRadius: 12.r,
fontWeight: FontWeight.w700,
borderRadius: 12.r,
padding: EdgeInsets.fromLTRB(12.h, 0, 12.h, 0),
height: 40.h,
),
Consumer<TodoSectionViewModel>(builder: (context, todoSectionVM, child) {
return Row(
mainAxisSize: MainAxisSize.min,
spacing: 18.h,
// spacing: 18.h,
children: [
Stack(clipBehavior: Clip.none, children: [
if (appState.isAuthenticated)
@ -292,7 +293,7 @@ class _LandingPageState extends State<LandingPage> {
}),
(appState.isAuthenticated && (int.parse(todoSectionVM.notificationsCount ?? "0") > 0))
? Positioned(
right: appState.isArabic() ? 8.w : -8.w,
// right: appState.isArabic() ? 8.w : -8.w,
top: -8.h,
// left: 4.h,
// bottom: 4.h,
@ -318,6 +319,7 @@ class _LandingPageState extends State<LandingPage> {
)
: SizedBox.shrink(),
]),
SizedBox(width: 24.w,),
Utils.buildSvgWithAssets(icon: AppAssets.location, height: 24.h, width: 24.w).onPress(() {
// openIndoorNavigationBottomSheet(context);
showCommonBottomSheetWithoutHeight(
@ -328,6 +330,7 @@ class _LandingPageState extends State<LandingPage> {
isFullScreen: false,
);
}),
// Utils.buildSvgWithAssets(icon: AppAssets.contact_icon, height: 24.h, width: 24.h).onPress(() {
// showCommonBottomSheetWithoutHeight(
// context,
@ -338,10 +341,10 @@ class _LandingPageState extends State<LandingPage> {
// );
// }),
!appState.isAuthenticated
? Utils.buildSvgWithAssets(icon: appState.isArabic() ? AppAssets.enLangIcon : AppAssets.arLangIcon, height: 24.h, width: 24.h).onPress(() {
?Row(children: [ SizedBox(width: 24.w,), Utils.buildSvgWithAssets(icon: appState.isArabic() ? AppAssets.enLangIcon : AppAssets.arLangIcon, height: 24.h, width: 24.h).onPress(() {
context.setLocale(appState.isArabic() ? Locale('en', 'US') : Locale('ar', 'SA'));
})
: SizedBox.shrink()
})])
: SizedBox()
],
);
}),
@ -483,29 +486,37 @@ class _LandingPageState extends State<LandingPage> {
)
: SizedBox(
height: 255.h + 20 + 30, // itemHeight + shadow padding (10 top + 10 bottom) + pagination dots space
child: Swiper(
itemCount: myAppointmentsVM.isMyAppointmentsLoading
? 3
: myAppointmentsVM.patientAppointmentsHistoryList.length < 3
? myAppointmentsVM.patientAppointmentsHistoryList.length
: 3,
layout: SwiperLayout.STACK,
loop: false,
itemWidth: MediaQuery.of(context).size.width - 48.h,
indicatorLayout: PageIndicatorLayout.COLOR,
axisDirection: appState.isArabic() ? AxisDirection.right : AxisDirection.left,
controller: _controller,
itemHeight: 255.h + 20,
// extra space for shadow
pagination: SwiperPagination(
alignment: Alignment.bottomCenter,
margin: EdgeInsets.only(top: 220.h + 20 + 8 + 24),
builder: DotSwiperPaginationBuilder(color: Color(0xffD9D9D9), activeColor: AppColors.blackBgColor),
),
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: getIndexSwiperCard(index),
child: Builder(
builder: (context) {
final int swiperItemCount = myAppointmentsVM.isMyAppointmentsLoading
? 3
: myAppointmentsVM.patientAppointmentsHistoryList.length < 3
? myAppointmentsVM.patientAppointmentsHistoryList.length
: 3;
final bool isArabic = appState.isArabic();
return Swiper(
itemCount: swiperItemCount,
layout: SwiperLayout.STACK,
loop: false,
itemWidth: MediaQuery.of(context).size.width - 48.h,
indicatorLayout: PageIndicatorLayout.COLOR,
axisDirection: isArabic ? AxisDirection.right : AxisDirection.left,
controller: _controller,
index: isArabic ? swiperItemCount - 1 : 0,
itemHeight: 255.h + 20,
// extra space for shadow
pagination: SwiperPagination(
alignment: Alignment.bottomCenter,
margin: EdgeInsets.only(top: 220.h + 20 + 8 + 24),
builder: DotSwiperPaginationBuilder(color: Color(0xffD9D9D9), activeColor: AppColors.blackBgColor),
),
itemBuilder: (BuildContext context, int index) {
final int actualIndex = isArabic ? (swiperItemCount - 1 - index) : index;
return Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: getIndexSwiperCard(actualIndex),
);
},
);
},
),
@ -612,7 +623,7 @@ class _LandingPageState extends State<LandingPage> {
LocaleKeys.quickLinks.tr(context: context).toText16(isBold: true),
Row(
children: [
LocaleKeys.viewMedicalFile.tr(context: context).toText12(color: AppColors.primaryRedColor, isBold: true),
LocaleKeys.viewMedicalFile.tr(context: context).toText14(color: AppColors.primaryRedColor, isBold: true),
SizedBox(width: 2.h),
Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 14.h),
],
@ -1004,17 +1015,21 @@ class _LandingPageState extends State<LandingPage> {
Widget _buildQueueHeader(int currentStatus) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AppCustomChipWidget(
labelText: currentStatus == 0 ? LocaleKeys.inQueue.tr() : LocaleKeys.yourTurn.tr(),
backgroundColor: Utils.getCardBorderColor(currentStatus).withValues(alpha: 0.20),
textColor: Utils.getCardBorderColor(currentStatus),
),
Utils.buildSvgWithAssets(
icon: AppAssets.waiting_icon,
width: 24.h,
height: 24.h,
),
Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.greyColor,
borderRadius: 10.h,
hasShadow: false,
),
padding: EdgeInsets.all(6.h),
child: Lottie.asset(AppAnimations.hourGlass, repeat: true, reverse: false, frameRate: FrameRate(60), width: 40.h, height: 40.h, fit: BoxFit.fill)),
],
);
}
@ -1148,6 +1163,7 @@ class _LandingPageState extends State<LandingPage> {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AppCustomChipWidget(
labelText: liveCareData.stringCallStatus,
@ -1162,13 +1178,42 @@ class _LandingPageState extends State<LandingPage> {
false,
),
),
SizedBox(width: 8.w),
AppCustomChipWidget(
richText: ValueListenableBuilder<Duration>(
valueListenable: immediateLiveCareViewModel.durationNotifier,
builder: (context, duration, child) {
final hours = duration.inHours.toString().padLeft(2, '0');
final minutes = duration.inMinutes.remainder(60).toString().padLeft(2, '0');
final seconds = duration.inSeconds.remainder(60).toString().padLeft(2, '0');
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
'$hours:$minutes:$seconds'.toText10(isBold: true),
],
);
},
),
// labelText: DateUtil.formatDateToDate(
// DateUtil.convertStringToDate(liveCareData.arrivalTime),
// false,
// ),
),
],
),
Utils.buildSvgWithAssets(
icon: AppAssets.waiting_icon,
width: 24.h,
height: 24.h,
),
Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.greyColor,
borderRadius: 10.h,
hasShadow: false,
),
padding: EdgeInsets.all(6.h),
child: Lottie.asset(AppAnimations.hourGlass, repeat: true, reverse: false, frameRate: FrameRate(60), width: 40.h, height: 40.h, fit: BoxFit.fill)),
// Utils.buildSvgWithAssets(
// icon: AppAssets.waiting_icon,
// width: 24.h,
// height: 24.h,
// ),
],
);
}

@ -1,6 +1,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_state.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
@ -76,13 +78,14 @@ class HabibWalletCard extends StatelessWidget {
// ],
// ),
SizedBox(height: 4.h),
Row(
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Consumer<HabibWalletViewModel>(builder: (context, habibWalletVM, child) {
return Row(
Consumer<HabibWalletViewModel>(builder: (context, habibWalletVM, child) {
return Row(
mainAxisSize: MainAxisSize.max,
children: [
Row(
children: [
Utils.buildSvgWithAssets(
icon: AppAssets.saudi_riyal_icon,
@ -98,58 +101,70 @@ class HabibWalletCard extends StatelessWidget {
.toText32(isBold: true, isEnglishOnly: true)
.toShimmer2(isShow: habibWalletVM.isWalletAmountLoading, radius: 12.h, width: 80.h, height: 40.h),
],
);
}),
Padding(
padding: EdgeInsets.symmetric(horizontal: 35.h),
child: Row(
children: [
LocaleKeys.viewDetails.tr(context: context).toText12(color: AppColors.primaryRedColor, isBold: true),
Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h),
],
).onPress(() {
Navigator.of(context).push(
CustomPageRoute(
page: HabibWalletPage(),
),
);
}),
),
],
),
SizedBox(
// width: 50.h,
child: Utils.getPaymentMethods(),
),
),
Spacer(),
Utils.getPaymentMethods(),
],
);
}),
],
),
SizedBox(height: 16.h),
CustomButton(
height: 40.h,
icon: AppAssets.recharge_icon,
iconColor: AppColors.infoColor,
iconSize: 24.h,
backgroundColor: AppColors.infoColor.withAlpha(15),
textColor: AppColors.infoColor,
text: LocaleKeys.recharge.tr(context: context),
borderWidth: 0.w,
fontWeight: FontWeight.w600,
borderColor: AppColors.infoColor.withAlpha(15),
padding: EdgeInsets.fromLTRB(4, 0, 12, 0),
fontSize: 14.f,
onPressed: () {
Navigator.of(context).push(CustomPageRoute(page: RechargeWalletPage()));
},
Row(
children: [
Expanded(
flex: 6,
child: CustomButton(
height: 40.h,
icon: AppAssets.recharge_icon,
iconColor: AppColors.infoColor,
iconSize: 24.h,
backgroundColor: AppColors.infoColor.withAlpha(15),
textColor: AppColors.infoColor,
text: LocaleKeys.recharge.tr(context: context),
borderWidth: 0.w,
fontWeight: FontWeight.w600,
borderColor: AppColors.infoColor.withAlpha(15),
padding: EdgeInsets.fromLTRB(4, 0, 12, 0),
fontSize: 14.f,
onPressed: () {
Navigator.of(context).push(CustomPageRoute(page: RechargeWalletPage()));
},
),
),
SizedBox(width: 8.h),
Expanded(
flex: 1,
child: Container(
height: (isFoldable || isTablet) ? 50.h : 40.h,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.textColor,
borderRadius: 10.h,
side: BorderSide(
color: AppColors.textColor,
width: 1.2,
),
),
child: Transform.flip(
flipX: getIt.get<AppState>().isArabic(),
child: Utils.buildSvgWithAssets(
icon: AppAssets.forward_arrow_icon,
iconColor: AppColors.whiteColor,
width: 24.w,
height: 24.h,
fit: BoxFit.contain,
),
),
).onPress(() {
Navigator.of(context).push(
CustomPageRoute(
page: HabibWalletPage(),
),
);
}),
),
],
),
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// SizedBox(
// width: 200.h,
// child: Utils.getPaymentMethods(),
// ),
// ],
// ),
],
),
),

File diff suppressed because one or more lines are too long

@ -45,11 +45,14 @@ class _LabAiAnalysisDetailedPageState extends State<LabAiAnalysisDetailedPage> {
if (analysis.summary != null && analysis.summary!.isNotEmpty) {
expandableItems.add(
ExpandableListItem(
backgroundColor: Colors.transparent,
expandedBackgroundColor:Colors.transparent ,
title: LocaleKeys.summary.tr(context: context).toText18(weight: FontWeight.w700, color: AppColors.blackColor),
initiallyExpanded: true,
children: [
SizedBox(height: 10.h),
Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 12.r, side: BorderSide(width: 1, color: Color(0xFF0B85F7))),
padding: EdgeInsets.all(16.r),
child: (analysis.summary ?? "").toText14(color: AppColors.textColorLight, height: 1.5, weight: FontWeight.w400),
@ -64,6 +67,9 @@ class _LabAiAnalysisDetailedPageState extends State<LabAiAnalysisDetailedPage> {
if (analysis.aiGeneratedAttributes != null && analysis.aiGeneratedAttributes!.isNotEmpty) {
expandableItems.add(
ExpandableListItem(
backgroundColor: Colors.transparent,
expandedBackgroundColor:Colors.transparent ,
title: LocaleKeys.labResults.tr(context: context).toText18(weight: FontWeight.w700, color: AppColors.blackColor),
children: [
SizedBox(height: 10.h),
@ -84,6 +90,8 @@ class _LabAiAnalysisDetailedPageState extends State<LabAiAnalysisDetailedPage> {
if (analysis.aiPredictions != null && analysis.aiPredictions!.isNotEmpty) {
expandableItems.add(
ExpandableListItem(
backgroundColor: Colors.transparent,
expandedBackgroundColor:Colors.transparent ,
title: LocaleKeys.prediction.tr(context: context).toText18(weight: FontWeight.w700, color: AppColors.blackColor),
children: [
SizedBox(height: 10.h),
@ -105,6 +113,8 @@ class _LabAiAnalysisDetailedPageState extends State<LabAiAnalysisDetailedPage> {
if (analysis.aiRecommendations != null && analysis.aiRecommendations!.isNotEmpty) {
expandableItems.add(
ExpandableListItem(
backgroundColor: Colors.transparent,
expandedBackgroundColor:Colors.transparent ,
title: LocaleKeys.suggestions.tr(context: context).toText18(weight: FontWeight.w700, color: AppColors.blackColor),
children: [
SizedBox(height: 10.h),
@ -152,6 +162,8 @@ class _LabAiAnalysisDetailedPageState extends State<LabAiAnalysisDetailedPage> {
if (analysis.riskFactors != null && analysis.riskFactors!.isNotEmpty) {
expandableItems.add(
ExpandableListItem(
backgroundColor: Colors.transparent,
expandedBackgroundColor:Colors.transparent ,
title: LocaleKeys.riskFactors.tr(context: context).toText18(weight: FontWeight.w700, color: AppColors.blackColor),
children: [
SizedBox(height: 10.h),
@ -221,6 +233,8 @@ class _LabAiAnalysisDetailedPageState extends State<LabAiAnalysisDetailedPage> {
if (analysis.prevention != null && analysis.prevention!.isNotEmpty) {
expandableItems.add(
ExpandableListItem(
backgroundColor: Colors.transparent,
expandedBackgroundColor:Colors.transparent ,
title: LocaleKeys.prevention.tr(context: context).toText18(weight: FontWeight.w700, color: AppColors.blackColor),
children: [
SizedBox(height: 10.h),
@ -308,10 +322,11 @@ class _LabAiAnalysisDetailedPageState extends State<LabAiAnalysisDetailedPage> {
else
CustomExpandableList(
expansionMode: ExpansionMode.exactlyOne,
dividerColor: Color(0xff2b353e1a),
dividerColor: AppColors.dividerColor,
itemPadding: EdgeInsets.symmetric(vertical: 16.h, horizontal: 14.h),
items: expandableItems,
theme: ExpandableListTheme.custom(
defaultTrailingIcon: Utils.buildSvgWithAssets(icon: AppAssets.arrow_down, height: 22.h, width: 22.w, iconColor: AppColors.textColor),
),
).paddingSymmetrical(16.w, 0.0),

@ -49,48 +49,38 @@ class LabOrderResultItem extends StatelessWidget {
SizedBox(height: 12.h),
Directionality(
textDirection: ui.TextDirection.ltr,
child: Row(
mainAxisSize: MainAxisSize.max,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Flexible(
Text(
"${tests?.resultValue} ${tests?.uOM}",
style: TextStyle(
fontSize: 24.f,
fontWeight: FontWeight.w600,
fontFamily: 'Poppins',
color: tests!.checkIfGraphShouldBeDisplayed()
? context.read<LabViewModel>().getColor(
tests?.calculatedResultFlag ?? "",
)
: Colors.grey.shade700,
letterSpacing: -1,
),
),
// SizedBox(
// height: 2.h,
// ),
Visibility(
visible: tests?.referanceRange != null,
child: Text(
"${tests?.resultValue} ${tests?.uOM}",
"(${LocaleKeys.referenceRange.tr(context: context)}: ${tests?.referanceRange})",
style: TextStyle(
fontSize: 24.f,
fontSize: 12.f,
fontWeight: FontWeight.w600,
fontFamily: 'Poppins',
color: tests!.checkIfGraphShouldBeDisplayed()
? context.read<LabViewModel>().getColor(
tests?.calculatedResultFlag ?? "",
)
: Colors.grey.shade700,
letterSpacing: -2,
),
),
),
SizedBox(
width: 4.h,
),
Visibility(
// visible: tests?.checkIfGraphShouldBeDisplayed() == true,
visible: true,
child: Expanded(
flex: 2,
child: Visibility(
visible: tests?.referanceRange != null,
child: Text(
"(${LocaleKeys.referenceRange.tr(context: context)}: ${tests?.referanceRange})",
style: TextStyle(
fontSize: 12.f,
fontWeight: FontWeight.w600,
fontFamily: 'Poppins',
color: AppColors.greyTextColor,
),
// overflow: TextOverflow.ellipsis,
// maxLines: 2,
softWrap: true,
),
color: AppColors.greyTextColor,
),
softWrap: true,
),
)
],

@ -51,7 +51,7 @@ class _MyInvoicesDetailsPageState extends State<MyInvoicesDetailsPage> {
myInvoicesViewModel.downloadInvoicePDF(
setupId: widget.getInvoicesListResponseModel.setupId!,
invoiceNo: widget.getInvoicesListResponseModel.invoiceNo!,
projectID: widget.getInvoicesListResponseModel.projectID!,
projectID: widget.getInvoicesListResponseModel.projectId!,
onError: (err) {
LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight(
@ -150,7 +150,7 @@ class _MyInvoicesDetailsPageState extends State<MyInvoicesDetailsPage> {
Column(
children: [
Image.network(
widget.getInvoiceDetailsResponseModel.doctorImageURL!,
widget.getInvoiceDetailsResponseModel.doctorImageURL ?? 'https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png',
width: 63.h,
height: 63.h,
fit: BoxFit.cover,
@ -162,10 +162,10 @@ class _MyInvoicesDetailsPageState extends State<MyInvoicesDetailsPage> {
height: 40.h,
decoration: BoxDecoration(
color: AppColors.whiteColor,
shape: BoxShape.circle, // Makes the container circular
shape: BoxShape.circle,
border: Border.all(
color: AppColors.scaffoldBgColor, // Color of the border
width: 1.5.w, // Width of the border
color: AppColors.scaffoldBgColor,
width: 1.5.w,
),
),
child: Column(
@ -173,7 +173,7 @@ class _MyInvoicesDetailsPageState extends State<MyInvoicesDetailsPage> {
children: [
Utils.buildSvgWithAssets(icon: AppAssets.rating_icon, width: 15.w, height: 15.h, applyThemeColor: false),
SizedBox(height: 2.h),
"${widget.getInvoicesListResponseModel.decimalDoctorRate}".toText11(isBold: true, color: AppColors.textColor),
"${widget.getInvoicesListResponseModel.decimalDoctorRate ?? '0.0'}".toText11(isBold: true, color: AppColors.textColor),
],
),
).circle(100),
@ -185,7 +185,7 @@ class _MyInvoicesDetailsPageState extends State<MyInvoicesDetailsPage> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
(getIt<AppState>().isArabic() ? widget.getInvoiceDetailsResponseModel.doctorNameN ?? LocaleKeys.doctor.tr(context: context) : widget.getInvoiceDetailsResponseModel.doctorName!).toText16(isBold: true),
(widget.getInvoiceDetailsResponseModel.doctorName ?? LocaleKeys.doctor.tr(context: context)).toText16(isBold: true),
SizedBox(height: 8.h),
Wrap(
direction: Axis.horizontal,
@ -193,29 +193,33 @@ class _MyInvoicesDetailsPageState extends State<MyInvoicesDetailsPage> {
runSpacing: 6.h,
children: [
AppCustomChipWidget(
labelText: "${LocaleKeys.invoiceNo.tr(context: context)}: ${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: ((getIt<AppState>().isArabic() ? widget.getInvoiceDetailsResponseModel.clinicDescriptionN : widget.getInvoiceDetailsResponseModel.clinicDescription ?? "")!.length > 15
? '${widget.getInvoiceDetailsResponseModel.clinicDescription!.substring(0, 12)}...'
: getIt<AppState>().isArabic() ? widget.getInvoiceDetailsResponseModel.clinicDescriptionN : widget.getInvoiceDetailsResponseModel.clinicDescription ?? ""),
labelText: () {
final clinicName = getIt<AppState>().isArabic()
? (widget.getInvoiceDetailsResponseModel.clinicDescriptionN ?? widget.getInvoiceDetailsResponseModel.clinicDescription ?? LocaleKeys.clinic.tr(context: context))
: (widget.getInvoiceDetailsResponseModel.clinicDescription ?? widget.getInvoiceDetailsResponseModel.clinicDescriptionN ?? LocaleKeys.clinic.tr(context: context));
return clinicName.length > 15 ? '${clinicName.substring(0, 12)}...' : clinicName;
}(),
labelPadding: EdgeInsetsDirectional.only(start: 4.w, end: 4.w),
),
AppCustomChipWidget(
labelText: widget.getInvoiceDetailsResponseModel.projectName!,
labelText: widget.getInvoiceDetailsResponseModel.projectName ?? LocaleKeys.hospital.tr(context: context),
labelPadding: EdgeInsetsDirectional.only(start: 6.w, end: 6.w),
),
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,
if (widget.getInvoiceDetailsResponseModel.appointmentDate != null)
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,
),
),
),
],
),
],
@ -241,22 +245,25 @@ class _MyInvoicesDetailsPageState extends State<MyInvoicesDetailsPage> {
children: [
LocaleKeys.insurance.tr(context: context).toText16(isBold: true),
SizedBox(height: 16.h),
(getIt<AppState>().isArabic() ? widget.getInvoiceDetailsResponseModel.groupNameN : widget.getInvoiceDetailsResponseModel.groupName)!.toText14(isBold: true),
(getIt<AppState>().isArabic()
? (widget.getInvoiceDetailsResponseModel.groupNameN ?? widget.getInvoiceDetailsResponseModel.groupName ?? LocaleKeys.insurance.tr(context: context))
: (widget.getInvoiceDetailsResponseModel.groupName ?? widget.getInvoiceDetailsResponseModel.groupNameN ?? LocaleKeys.insurance.tr(context: context))
).toText14(isBold: true),
Row(
children: [
Expanded(child: (widget.getInvoiceDetailsResponseModel.companyName ?? "").toText14(isBold: true)),
],
),
SizedBox(height: 12.h),
Row(
children: [
AppCustomChipWidget(
labelText: "Insurance ID: ${widget.getInvoiceDetailsResponseModel.insuranceID ?? "-"}",
labelPadding: EdgeInsetsDirectional.only(start: 6.w, end: 6.w),
isEnglishOnly: true,
),
],
),
// Row(
// children: [
// AppCustomChipWidget(
// labelText: "Insurance ID: ${widget.getInvoiceDetailsResponseModel.insuranceID ?? "-"}",
// labelPadding: EdgeInsetsDirectional.only(start: 6.w, end: 6.w),
// isEnglishOnly: true,
// ),
// ],
// ),
],
),
),
@ -299,8 +306,8 @@ class _MyInvoicesDetailsPageState extends State<MyInvoicesDetailsPage> {
children: [
Expanded(flex: 3, child: (consultation.procedureName ?? '-').toText12(isBold: true)),
Expanded(flex: 1, child: '${consultation.quantity ?? '-'}'.toText12(isBold: true, isCenter: true, isEnglishOnly: true)),
Expanded(flex: 2, child: (NumberFormat.decimalPattern().format(consultation.price) ?? '-').toText12(isBold: true, isCenter: true, isEnglishOnly: true)),
Expanded(flex: 2, child: (NumberFormat.decimalPattern().format(consultation.total) ?? '-').toText12(isBold: true, isCenter: true, isEnglishOnly: true)),
Expanded(flex: 2, child: (NumberFormat.decimalPattern().format(consultation.totalPatientShare) ?? '-').toText12(isBold: true, isCenter: true, isEnglishOnly: true)),
Expanded(flex: 2, child: (NumberFormat.decimalPattern().format(consultation.totalPatientShare) ?? '-').toText12(isBold: true, isCenter: true, isEnglishOnly: true)),
],
),
),
@ -335,7 +342,7 @@ class _MyInvoicesDetailsPageState extends State<MyInvoicesDetailsPage> {
children: [
LocaleKeys.amountBeforeTax.tr(context: context).toText14(isBold: true),
Utils.getPaymentAmountWithSymbol(
NumberFormat.decimalPattern().format(widget.getInvoiceDetailsResponseModel.listConsultation!.first.totalShare).toString().toText16(isBold: true, isEnglishOnly: true), AppColors.blackColor, 13,
NumberFormat.decimalPattern().format(widget.getInvoiceDetailsResponseModel.listConsultation!.first.patientShare).toString().toText16(isBold: true, isEnglishOnly: true), AppColors.blackColor, 13,
isSaudiCurrency: true),
],
).paddingSymmetrical(24.h, 0.h),
@ -345,7 +352,7 @@ class _MyInvoicesDetailsPageState extends State<MyInvoicesDetailsPage> {
LocaleKeys.vat15.tr(context: context).toText14(isBold: true, color: AppColors.greyTextColor),
Utils.getPaymentAmountWithSymbol(
NumberFormat.decimalPattern()
.format(widget.getInvoiceDetailsResponseModel.listConsultation!.first.totalVATAmount!)
.format(widget.getInvoiceDetailsResponseModel.listConsultation!.first.patientVATAmount!)
.toString()
.toText14(isBold: true, color: AppColors.greyTextColor, isEnglishOnly: true),
AppColors.greyTextColor,
@ -354,25 +361,25 @@ class _MyInvoicesDetailsPageState extends State<MyInvoicesDetailsPage> {
],
).paddingSymmetrical(24.h, 0.h),
SizedBox(height: 16.h),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
LocaleKeys.discount.tr(context: context).toText14(isBold: true),
Utils.getPaymentAmountWithSymbol(
NumberFormat.decimalPattern()
.format(widget.getInvoiceDetailsResponseModel.listConsultation!.first.discountAmount!)
.toString()
.toText14(isBold: true, color: AppColors.primaryRedColor, isEnglishOnly: true),
AppColors.primaryRedColor, 13,
isSaudiCurrency: true),
],
).paddingSymmetrical(24.h, 0.h),
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// LocaleKeys.discount.tr(context: context).toText14(isBold: true),
// Utils.getPaymentAmountWithSymbol(
// NumberFormat.decimalPattern()
// .format(widget.getInvoiceDetailsResponseModel.listConsultation!.first.discountAmount!)
// .toString()
// .toText14(isBold: true, color: AppColors.primaryRedColor, isEnglishOnly: true),
// AppColors.primaryRedColor, 13,
// isSaudiCurrency: true),
// ],
// ).paddingSymmetrical(24.h, 0.h),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
LocaleKeys.paid.tr(context: context).toText14(isBold: true),
Utils.getPaymentAmountWithSymbol(
NumberFormat.decimalPattern().format(widget.getInvoiceDetailsResponseModel.listConsultation!.first.grandTotal!).toString().toText14(isBold: true, color: AppColors.textColor, isEnglishOnly: true),
NumberFormat.decimalPattern().format(widget.getInvoiceDetailsResponseModel.listConsultation!.first.totalPatientShare!).toString().toText14(isBold: true, color: AppColors.textColor, isEnglishOnly: true),
AppColors.textColor,
13,
isSaudiCurrency: true),

@ -143,7 +143,7 @@ class _MyInvoicesListState extends State<MyInvoicesList> {
CustomButton(
text: LocaleKeys.hospitals.tr(context: context),
onPressed: () {
if (myInvoicesVM.allInvoicesList.isEmpty) return;
if (myInvoicesVM.getOriginalInvoicesList().isEmpty) return;
_showHospitalFilterBottomSheet(context);
},
backgroundColor: myInvoicesVM.currentFilter == InvoiceFilterType.hospital ? AppColors.bgRedLightColor : AppColors.whiteColor,
@ -159,7 +159,7 @@ class _MyInvoicesListState extends State<MyInvoicesList> {
CustomButton(
text: LocaleKeys.clinics.tr(context: context),
onPressed: () {
if (myInvoicesVM.allInvoicesList.isEmpty) return;
if (myInvoicesVM.getOriginalInvoicesList().isEmpty) return;
_showClinicFilterBottomSheet(context);
},
backgroundColor: myInvoicesVM.currentFilter == InvoiceFilterType.clinic ? AppColors.bgRedLightColor : AppColors.whiteColor,
@ -175,7 +175,7 @@ class _MyInvoicesListState extends State<MyInvoicesList> {
CustomButton(
text: LocaleKeys.doctors.tr(context: context),
onPressed: () {
if (myInvoicesVM.allInvoicesList.isEmpty) return;
if (myInvoicesVM.getOriginalInvoicesList().isEmpty) return;
_showDoctorFilterBottomSheet(context);
},
backgroundColor: myInvoicesVM.currentFilter == InvoiceFilterType.doctor ? AppColors.bgRedLightColor : AppColors.whiteColor,
@ -220,7 +220,7 @@ class _MyInvoicesListState extends State<MyInvoicesList> {
await myInvoicesVM.getInvoiceDetails(
appointmentNo: myInvoicesVM.allInvoicesList[index].appointmentNo!,
invoiceNo: myInvoicesVM.allInvoicesList[index].invoiceNo!,
projectID: myInvoicesVM.allInvoicesList[index].projectID!,
projectID: myInvoicesVM.allInvoicesList[index].projectId!,
onSuccess: (val) {
LoaderBottomSheet.hideLoader();
Navigator.of(context).push(

@ -61,7 +61,7 @@ class InvoiceListCard extends StatelessWidget {
Column(
children: [
Image.network(
getInvoicesListResponseModel.doctorImageURL!,
getInvoicesListResponseModel.doctorImageUrl ?? 'https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png',
width: 63.h,
height: 63.h,
fit: BoxFit.cover,
@ -73,10 +73,10 @@ class InvoiceListCard extends StatelessWidget {
height: 40.h,
decoration: BoxDecoration(
color: AppColors.whiteColor,
shape: BoxShape.circle, // Makes the container circular
shape: BoxShape.circle,
border: Border.all(
color: AppColors.scaffoldBgColor, // Color of the border
width: 1.5.w, // Width of the border
color: AppColors.scaffoldBgColor,
width: 1.5.w,
),
),
child: Column(
@ -84,7 +84,7 @@ class InvoiceListCard extends StatelessWidget {
children: [
Utils.buildSvgWithAssets(icon: AppAssets.rating_icon, width: 15.w, height: 15.h, applyThemeColor: false),
SizedBox(height: 2.h),
"${getInvoicesListResponseModel.decimalDoctorRate}".toText11(isBold: true, color: AppColors.textColor),
"${getInvoicesListResponseModel.decimalDoctorRate ?? '0.0'}".toText11(isBold: true, color: AppColors.textColor),
],
),
).circle(100),
@ -96,7 +96,10 @@ class InvoiceListCard extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
(getIt<AppState>().isArabic() ? getInvoicesListResponseModel.doctorNameN! : getInvoicesListResponseModel.doctorName ?? "HMG Doctor").toText16(isBold: true),
(getIt<AppState>().isArabic()
? (getInvoicesListResponseModel.doctorNameN ?? getInvoicesListResponseModel.doctorName ?? LocaleKeys.doctor.tr(context: context))
: (getInvoicesListResponseModel.doctorName ?? getInvoicesListResponseModel.doctorNameN ?? LocaleKeys.doctor.tr(context: context))
).toText16(isBold: true),
SizedBox(height: 8.h),
Wrap(
direction: Axis.horizontal,
@ -104,28 +107,30 @@ class InvoiceListCard extends StatelessWidget {
runSpacing: 6.h,
children: [
AppCustomChipWidget(
labelText: "${LocaleKeys.invoiceNo.tr(context: context)}: ${getInvoicesListResponseModel.invoiceNo!}",
labelText: "${LocaleKeys.invoiceNo.tr(context: context)}: ${getInvoicesListResponseModel.invoiceNo ?? '-'}",
labelPadding: EdgeInsetsDirectional.only(start: 6.w, end: 6.w),
isEnglishOnly: true,
),
AppCustomChipWidget(
labelText:
(getInvoicesListResponseModel.clinicName!.length > 15 ? '${getInvoicesListResponseModel.clinicName!.substring(0, 12)}...' : getInvoicesListResponseModel.clinicName!),
labelText: ((getInvoicesListResponseModel.clinicName ?? LocaleKeys.clinic.tr(context: context)).length > 15
? '${(getInvoicesListResponseModel.clinicName ?? LocaleKeys.clinic.tr(context: context)).substring(0, 12)}...'
: (getInvoicesListResponseModel.clinicName ?? LocaleKeys.clinic.tr(context: context))),
labelPadding: EdgeInsetsDirectional.only(start: 4.w, end: 4.w),
),
AppCustomChipWidget(
labelText: getInvoicesListResponseModel.projectName!,
labelText: getInvoicesListResponseModel.projectName ?? LocaleKeys.hospital.tr(context: context),
labelPadding: EdgeInsetsDirectional.only(start: 6.w, end: 6.w),
),
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,
if (getInvoicesListResponseModel.appointmentDate != null)
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,
),
),
),
],
),
],

@ -258,7 +258,7 @@ class _RadiologyResultPageState extends State<RadiologyResultPage> {
).paddingSymmetrical(24.h, 12.h).onPress(() async {
final _dialogService = getIt.get<DialogService>();
await _dialogService.showCommonBottomSheetWithoutH(
message: LocaleKeys.aiDisclaimer.tr(),
message: LocaleKeys.aiDisclaimerRad.tr(),
label: LocaleKeys.consent.tr(),
okLabel: LocaleKeys.acceptLbl.tr(),
cancelLabel: LocaleKeys.rejectView.tr(),

@ -1,5 +1,7 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
@ -90,7 +92,7 @@ class _RateAppointmentDoctorState extends State<RateAppointmentDoctor> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Please rate the doctor".toText16(isBold: true),
LocaleKeys.rateTheDoctor.tr(context: context).toText16(isBold: true),
SizedBox(height: 12),
Row(
mainAxisAlignment: MainAxisAlignment.center,
@ -139,16 +141,23 @@ class _RateAppointmentDoctorState extends State<RateAppointmentDoctor> {
child: Padding(
padding: EdgeInsets.all(16.0),
child: TextField(
maxLines: 4,
// style: TextStyle(
// fontSize: 14.f,
// fontWeight: FontWeight.w400,
// color: Color(0xff2B353E),
// letterSpacing: 0,
// fontFamily: getIt.get<AppState>().getLanguageCode() == "ar" ? 'CairoArabic' : 'Poppins',
// ),
decoration: InputDecoration.collapsed(
hintText: LocaleKeys.notes.tr(context: context),
hintStyle: TextStyle(
fontSize: 16.f,
fontWeight: FontWeight.w600,
color: Color(0xff2B353E),
letterSpacing: -0.64,
height: 23 / 16)),
fontSize: 16.f,
fontWeight: FontWeight.w600,
letterSpacing: -0.4,
fontFamily: getIt.get<AppState>().getLanguageCode() == "ar" ? 'CairoArabic' : 'Poppins',
),
),
onChanged: (value) {
setState(() {
note = value;

@ -57,7 +57,8 @@ class _SelectedOrgansSectionState extends State<SelectedOrgansSection> {
LocaleKeys.selectedOrgans.tr(context: context),
style: TextStyle(
fontSize: 16.f,
isBold: true,
// isBold: true,
fontWeight: FontWeight.w600,
color: AppColors.textColor,
),
),
@ -78,7 +79,7 @@ class _SelectedOrgansSectionState extends State<SelectedOrgansSection> {
style: TextStyle(
color: AppColors.whiteColor,
fontSize: 12.f,
// isBold: true,
fontWeight: FontWeight.w600,
),
),
),

@ -26,8 +26,7 @@ class AppTheme {
canvasColor: Colors.white,
highlightColor: Colors.grey[100]!.withOpacity(0.4),
splashColor: Colors.transparent,
bottomSheetTheme: BottomSheetThemeData(
backgroundColor: Colors.black.withOpacity(0)),
bottomSheetTheme: BottomSheetThemeData(backgroundColor: Colors.black.withOpacity(0)),
floatingActionButtonTheme: const FloatingActionButtonThemeData(highlightElevation: 2, disabledElevation: 0, elevation: 2),
appBarTheme: AppBarTheme(
color: const Color(0xff515A5D),
@ -35,7 +34,7 @@ class AppTheme {
actionsIconTheme: IconThemeData(
color: Colors.grey[800],
),
systemOverlayStyle: SystemUiOverlayStyle.light,
systemOverlayStyle: SystemUiOverlayStyle.dark,
surfaceTintColor: Colors.transparent,
),
);

@ -88,7 +88,7 @@ Widget buildDigit(String digit) {
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.black,
fontSize: 14.f,
fontSize: 10.f,
),
),
),

@ -55,7 +55,7 @@ class DatePickerWidget extends StatelessWidget {
labelText,
style: TextStyle(
fontSize: 12.f,
isBold: true,
// isBold: true,
color: Color(0xff898A8D),
letterSpacing: -0.2,
height: 18 / 12,

@ -12,7 +12,6 @@ import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/dropdown/country_dropdown_widget.dart';
import 'package:hmg_patient_app_new/widgets/time_picker_widget.dart';
import 'dart:ui' as ui;
class TextInputWidget extends StatelessWidget {
final String labelText;
@ -295,59 +294,70 @@ class TextInputWidget extends StatelessWidget {
Widget _buildTextField(BuildContext context) {
double fontS = fontSize ?? 14.f;
final isArabic = getIt.get<AppState>().isArabic();
return Builder(
builder: (context) {
return Localizations.override(
context: context,
locale: const Locale('en', 'US'), // Force English locale for TextField
child: TextField(
hintLocales: const [Locale('en', 'US')],
enabled: isEnable,
scrollPadding: EdgeInsets.zero,
keyboardType: isMultiline ? TextInputType.multiline : (isWalletAmountInput! ? const TextInputType.numberWithOptions(decimal: true) : keyboardType),
controller: controller,
readOnly: isReadOnly,
textAlignVertical: TextAlignVertical.top,
textAlign: TextAlign.left,
textDirection: TextDirection.ltr,
onChanged: onChange,
focusNode: focusNode ?? _focusNode,
autofocus: autoFocus,
textInputAction: TextInputAction.done,
cursorHeight: isWalletAmountInput! ? 40.h : 20.h,
maxLength: isWalletAmountInput! ? 7 : 100,
inputFormatters: isWalletAmountInput!
? [
_ThousandSeparatorInputFormatter(),
]
: null,
onTapOutside: (event) {
FocusManager.instance.primaryFocus?.unfocus();
},
onSubmitted: onSubmitted,
minLines: isMultiline ? minLines : 1,
maxLines: isMultiline ? maxLines : 1,
style: TextStyle(
fontSize: fontS,
height: isMultiline ? 1.2 : (isWalletAmountInput! ? 1 / 4 : 0),
fontWeight: FontWeight.w600,
color: AppColors.textColor,
letterSpacing: -1,
// fontFamily: keyboardType == TextInputType.number ? getIt.get<AppState>().isArabic() ? 'GESSTwo' : 'Poppins' : 'Poppins',
fontFamily: fontFamily,
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.w600, color: hintColor != null ? AppColors.textColor : Color(0xff898A8D), letterSpacing: -0.75),
prefixIconConstraints: BoxConstraints(minWidth: 30.h),
prefixIcon: prefix == null ? null : "+${prefix!}".toText14(letterSpacing: -1, color: AppColors.textColor, isBold: true),
contentPadding: EdgeInsets.zero,
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
return Directionality(
textDirection: isArabic ? TextDirection.rtl : TextDirection.ltr,
child: Localizations.override(
context: context,
locale: const Locale('en', 'US'), // Force English locale for TextField
child: TextField(
hintLocales: const [Locale('en', 'US')],
enabled: isEnable,
scrollPadding: EdgeInsets.zero,
keyboardType: isMultiline ? TextInputType.multiline : (isWalletAmountInput! ? const TextInputType.numberWithOptions(decimal: true) : keyboardType),
controller: controller,
readOnly: isReadOnly,
textAlignVertical: TextAlignVertical.top,
textAlign: isArabic ? TextAlign.right : TextAlign.left,
textDirection: TextDirection.ltr,
onChanged: onChange,
focusNode: focusNode ?? _focusNode,
autofocus: autoFocus,
textInputAction: TextInputAction.done,
cursorHeight: isWalletAmountInput! ? 40.h : 20.h,
maxLength: isWalletAmountInput! ? 7 : 100,
inputFormatters: isWalletAmountInput!
? [
_ThousandSeparatorInputFormatter(),
]
: null,
onTapOutside: (event) {
FocusManager.instance.primaryFocus?.unfocus();
},
onSubmitted: onSubmitted,
minLines: isMultiline ? minLines : 1,
maxLines: isMultiline ? maxLines : 1,
style: TextStyle(
fontSize: fontS,
height: isMultiline ? 1.2 : (isWalletAmountInput! ? 1 / 4 : 0),
fontWeight: FontWeight.w600,
color: AppColors.textColor,
letterSpacing: -1,
fontFamily: fontFamily,
locale: const Locale('en', 'US'), // Force English locale for text style
),
decoration: InputDecoration(
counterText: "",
isDense: true,
hintText: hintText,
hintStyle: TextStyle(
fontFamily: isArabic ? 'CairoArabic' : 'Poppins',
fontSize: 14.f,
height: 21 / 16,
fontWeight: FontWeight.w600,
color: hintColor != null ? AppColors.textColor : Color(0xff898A8D),
letterSpacing: -0.75,
),
prefixIconConstraints: BoxConstraints(minWidth: 30.h),
prefixIcon: prefix == null ? null : "+${prefix!}".toText14(letterSpacing: -1, color: AppColors.textColor, isBold: true),
contentPadding: EdgeInsets.zero,
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
),
),
),
);

@ -210,7 +210,7 @@ class _GMSMapState extends State<GMSMap> {
Icons.location_pin,
size: 36.h,
color: AppColors.primaryRedColor,
).paddingOnly(bottom: Platform.isAndroid ? 30.h : double.parse((widget.bottomPaddingHeight + 25.h).toString())),
).paddingOnly(bottom: Platform.isAndroid ? 30.h : 60.h),
),
// My Location button

@ -204,44 +204,22 @@ abstract class _CustomLayoutStateBase<T extends _SubSwiper> extends State<T>
void _onPanEnd(DragEndDetails details) {
if (_lockScroll) return;
final bool _isReversedGesture = widget.axisDirection == AxisDirection.right;
double velocity = widget.scrollDirection == Axis.horizontal
? details.velocity.pixelsPerSecond.dx
: details.velocity.pixelsPerSecond.dy;
if (_isReversedGesture) {
// Reversed: swipe right (value >= 0.75) = next, swipe left (value < 0.25) = previous
if (_animationController.value >= 0.75 || velocity > 500.0) {
if (_currentIndex >= widget.itemCount - 1 && !widget.loop) {
_move(0.5);
return;
}
_move(1.0, nextIndex: _currentIndex + 1);
} else if (_animationController.value < 0.25 || velocity < -500.0) {
if (_currentIndex <= 0 && !widget.loop) {
_move(0.5);
return;
}
_move(0.0, nextIndex: _currentIndex - 1);
} else {
_move(0.5);
if (_animationController.value >= 0.75 || velocity > 500.0) {
if (_currentIndex <= 0 && !widget.loop) {
return;
}
} else {
// Default: swipe right (value >= 0.75) = previous, swipe left (value < 0.25) = next
if (_animationController.value >= 0.75 || velocity > 500.0) {
if (_currentIndex <= 0 && !widget.loop) {
return;
}
_move(1.0, nextIndex: _currentIndex - 1);
} else if (_animationController.value < 0.25 || velocity < -500.0) {
if (_currentIndex >= widget.itemCount - 1 && !widget.loop) {
return;
}
_move(0.0, nextIndex: _currentIndex + 1);
} else {
_move(0.5);
_move(1.0, nextIndex: _currentIndex - 1);
} else if (_animationController.value < 0.25 || velocity < -500.0) {
if (_currentIndex >= widget.itemCount - 1 && !widget.loop) {
return;
}
_move(0.0, nextIndex: _currentIndex + 1);
} else {
_move(0.5);
}
}
@ -255,7 +233,6 @@ abstract class _CustomLayoutStateBase<T extends _SubSwiper> extends State<T>
void _onPanUpdate(DragUpdateDetails details) {
if (_lockScroll) return;
double value = _currentValue +
((widget.scrollDirection == Axis.horizontal
? details.globalPosition.dx
@ -265,26 +242,13 @@ abstract class _CustomLayoutStateBase<T extends _SubSwiper> extends State<T>
2;
// no loop ?
if (!widget.loop) {
if (widget.axisDirection == AxisDirection.right) {
// Reversed bounds: block dragging left past first, right past last
if (_currentIndex <= 0) {
if (value < 0.5) {
value = 0.5;
}
} else if (_currentIndex >= widget.itemCount - 1) {
if (value > 0.5) {
value = 0.5;
}
if (_currentIndex >= widget.itemCount - 1) {
if (value < 0.5) {
value = 0.5;
}
} else {
if (_currentIndex >= widget.itemCount - 1) {
if (value < 0.5) {
value = 0.5;
}
} else if (_currentIndex <= 0) {
if (value > 0.5) {
value = 0.5;
}
} else if (_currentIndex <= 0) {
if (value > 0.5) {
value = 0.5;
}
}
}

Loading…
Cancel
Save