Merge branch 'master' into dev_aamir

pull/221/head
aamir-csol 2 days ago
commit 7a0caa05c3

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

File diff suppressed because one or more lines are too long

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

@ -1572,7 +1572,7 @@
"contextDependent": "Context Dependent", "contextDependent": "Context Dependent",
"calculatedValue": "Calculated Value", "calculatedValue": "Calculated Value",
"calculationFormula": "Calculation Formula", "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", "symptoms": "Symptoms",
"insuranceInActive": "Insurance Inactive", "insuranceInActive": "Insurance Inactive",
"insuranceInActiveContactSupport": "You have a valid insurance but it is currently inactive in HMG. Please contact HMG customer support to activate it.", "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", "openGallery": "Open Gallery",
"openFiles": "Open Files", "openFiles": "Open Files",
"generateAiAnalysisRadResult": "Generate AI analysis for this result", "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_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 GET_DENTAL_APPOINTMENT_INVOICE = "Services/Patients.svc/REST/HIS_eInvoiceForDentalByAppointmentNo";
var SEND_DENTAL_APPOINTMENT_INVOICE_EMAIL = "Services/Notifications.svc/REST/SendInvoiceForDental"; 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 ambulance = '$lottieBasePath/ambulance.json';
static const String ambulanceAlert = '$lottieBasePath/ambulance_alert.json'; static const String ambulanceAlert = '$lottieBasePath/ambulance_alert.json';
static const String rrtAmbulance = '$lottieBasePath/rrt_ambulance.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, BorderRadius? customBorder,
bool hasShadow = false, bool hasShadow = false,
bool hasDenseShadow = false, bool hasDenseShadow = false,
List<BoxShadow>? isCustomShadow,
}) { }) {
final bgColor = backgroundColor ?? color; final bgColor = backgroundColor ?? color;
return ShapeDecoration( return ShapeDecoration(
@ -174,7 +175,7 @@ extension SmoothContainerExtension on ShapeBorder {
offset: const Offset(1, 0), offset: const Offset(1, 0),
) )
] ]
: [], : isCustomShadow ?? [],
); );
} }
} }

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

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

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

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

@ -38,7 +38,7 @@ class MyInvoicesRepoImp implements MyInvoicesRepo {
}, },
onSuccess: (response, statusCode, {messageStatus, errorMessage}) { onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try { 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>(); 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 openFiles = 'openFiles';
static const generateAiAnalysisRadResult = 'generateAiAnalysisRadResult'; static const generateAiAnalysisRadResult = 'generateAiAnalysisRadResult';
static const grantLocationPermission = 'grantLocationPermission'; 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/app_state.dart';
import 'package:hmg_patient_app_new/core/dependencies.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/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/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/authentication/authentication_view_model.dart';
import 'package:hmg_patient_app_new/features/blood_donation/blood_donation_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/logger_service.dart';
import 'package:hmg_patient_app_new/services/navigation_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/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:hmg_patient_app_new/widgets/date_range_selector/viewmodel/date_range_view_model.dart' show DateRangeSelectorRangeViewModel;
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:provider/single_child_widget.dart'; import 'package:provider/single_child_widget.dart';

@ -393,8 +393,8 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
), ),
const Spacer(), const Spacer(),
Switch( Switch(
// activeThumbColor: AppColors.successColor, activeThumbColor: AppColors.successColor,
activeTrackColor: AppColors.successColor.withValues(alpha: .15), // activeTrackColor: AppColors.successColor.withValues(alpha: .15),
value: widget.patientAppointmentHistoryResponseModel.hasReminder!, value: widget.patientAppointmentHistoryResponseModel.hasReminder!,
onChanged: (newValue) async { onChanged: (newValue) async {
CalenderUtilsNew calender = CalenderUtilsNew.instance; CalenderUtilsNew calender = CalenderUtilsNew.instance;
@ -612,7 +612,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
isLocked: false, isLocked: false,
).toShimmer2() ).toShimmer2()
: MedicalFileCard( : MedicalFileCard(
label: !((myAppointmentsVM.appointmentRatedResponseModel!).isAppointmentRated ?? true) label: !((myAppointmentsVM.appointmentRatedResponseModel!).isAllowedToRate ?? false)
? LocaleKeys.ratingSubmitted.tr(context: context) ? LocaleKeys.ratingSubmitted.tr(context: context)
: LocaleKeys.doctorRatingAppointment.tr(context: context), : LocaleKeys.doctorRatingAppointment.tr(context: context),
textColor: AppColors.blackColor, textColor: AppColors.blackColor,
@ -620,9 +620,9 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
svgIcon: AppAssets.appointmentRatingIcon, svgIcon: AppAssets.appointmentRatingIcon,
isLargeText: true, isLargeText: true,
iconSize: 36.w, iconSize: 36.w,
isLocked: !(myAppointmentsVM.appointmentRatedResponseModel!.isAppointmentRated ?? true), isLocked: !(myAppointmentsVM.appointmentRatedResponseModel!.isAllowedToRate ?? false),
).onPress(() { ).onPress(() {
if(!(myAppointmentsVM.appointmentRatedResponseModel!.isAppointmentRated ?? true)) { if ((myAppointmentsVM.appointmentRatedResponseModel!.isAllowedToRate ?? true)) {
showCommonBottomSheetWithoutHeight( showCommonBottomSheetWithoutHeight(
context, context,
title: LocaleKeys.doctorRating.tr(context: 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/buttons/custom_button.dart';
import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.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:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:lottie/lottie.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class AppointmentQueuePage extends StatelessWidget { class AppointmentQueuePage extends StatelessWidget {
@ -32,13 +33,14 @@ class AppointmentQueuePage extends StatelessWidget {
children: [ children: [
Expanded( Expanded(
child: CollapsingListView( child: CollapsingListView(
title: LocaleKeys.queueing.tr(context: context), title: LocaleKeys.queueing.tr(context: context),
child: RefreshIndicator( child: RefreshIndicator(
color: AppColors.primaryRedColor, color: AppColors.primaryRedColor,
onRefresh: () async { onRefresh: () async {
await myAppointmentsVM.getPatientAppointmentQueueDetails(); await myAppointmentsVM.getPatientAppointmentQueueDetails();
}, },
child: SingleChildScrollView( child: SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
child: Padding( child: Padding(
padding: EdgeInsets.all(24.0), padding: EdgeInsets.all(24.0),
child: Column( child: Column(
@ -59,13 +61,21 @@ class AppointmentQueuePage extends StatelessWidget {
children: [ children: [
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
AppCustomChipWidget( AppCustomChipWidget(
labelText: myAppointmentsVM.currentQueueStatus == 0 ? LocaleKeys.inQueue.tr(context: context) : LocaleKeys.yourTurn.tr(context: context), labelText: myAppointmentsVM.currentQueueStatus == 0 ? LocaleKeys.inQueue.tr(context: context) : LocaleKeys.yourTurn.tr(context: context),
backgroundColor: Utils.getCardBorderColor(myAppointmentsVM.currentQueueStatus).withValues(alpha: 0.20), backgroundColor: Utils.getCardBorderColor(myAppointmentsVM.currentQueueStatus).withValues(alpha: 0.20),
textColor: Utils.getCardBorderColor(myAppointmentsVM.currentQueueStatus), 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), ).toShimmer2(isShow: myAppointmentsVM.isAppointmentQueueDetailsLoading),
SizedBox(height: 10.h), SizedBox(height: 10.h),
@ -189,9 +199,9 @@ class AppointmentQueuePage extends StatelessWidget {
], ],
), ),
), ),
),
), ),
), ),
),
), ),
Container( Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration( decoration: RoundedRectangleBorder().toSmoothCornerDecoration(

@ -205,7 +205,7 @@ class AppointmentCard extends StatelessWidget {
richText: isLoading richText: isLoading
? 'Cardiology'.toText10().toShimmer2(isShow: isLoading) ? 'Cardiology'.toText10().toShimmer2(isShow: isLoading)
: "${DateUtil.formatDateToDate(DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate), false)} ${DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate), false)}" : "${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), ).toShimmer2(isShow: isLoading),
), ),
@ -243,42 +243,123 @@ class AppointmentCard extends StatelessWidget {
(patientAppointmentHistoryResponseModel.isExecludeDoctor ?? false) || (patientAppointmentHistoryResponseModel.isExecludeDoctor ?? false) ||
!Utils.isClinicAllowedForRebook(patientAppointmentHistoryResponseModel.clinicID ?? 0))) && !Utils.isClinicAllowedForRebook(patientAppointmentHistoryResponseModel.clinicID ?? 0))) &&
AppointmentType.isArrived(patientAppointmentHistoryResponseModel)) { AppointmentType.isArrived(patientAppointmentHistoryResponseModel)) {
return CustomButton( if (((patientAppointmentHistoryResponseModel.isLiveCareAppointment ?? false) &&
text: isFromMedicalReport ? LocaleKeys.selectAppointment.tr(context: context) : LocaleKeys.viewDetails.tr(context: context), DateTime.now().difference(DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate)).inDays <= 15)) {
onPressed: () { return Row(
if (isFromMedicalReport) { children: [
if (isForFeedback) { Expanded(
contactUsViewModel!.setPatientFeedbackSelectedAppointment(patientAppointmentHistoryResponseModel); 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 { } 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 { backgroundColor: AppColors.secondaryLightRedColor,
Navigator.of(context) borderColor: AppColors.secondaryLightRedColor,
.push( textColor: AppColors.primaryRedColor,
CustomPageRoute( fontSize: (isFoldable || isTablet) ? 12.f : 14.f,
page: AppointmentDetailsPage(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel), fontWeight: FontWeight.w600,
), borderRadius: 12.r,
) padding: EdgeInsets.symmetric(horizontal: 10.w),
.then((_) { // height: isTablet || isFoldable ? 46.h : 40.h,
myAppointmentsViewModel.initAppointmentsViewModel(); height: 40.h,
myAppointmentsViewModel.getPatientAppointments(true, false); 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 { } else {
if (isFromMedicalReport) { if (isFromMedicalReport) {
if (isForEyeMeasurements) { if (isForEyeMeasurements) {
@ -309,7 +390,6 @@ class AppointmentCard extends StatelessWidget {
); );
} }
} }
return Row( return Row(
children: [ children: [
Expanded( Expanded(
@ -415,6 +495,10 @@ class AppointmentCard extends StatelessWidget {
} }
return CustomButton( return CustomButton(
borderSide: BorderSide(
color: AppColors.textColor,
width: 1.2,
),
text: LocaleKeys.rebookSameDoctor.tr(context: context), text: LocaleKeys.rebookSameDoctor.tr(context: context),
onPressed: () => openDoctorScheduleCalendar(context), onPressed: () => openDoctorScheduleCalendar(context),
backgroundColor: AppColors.transparent, backgroundColor: AppColors.transparent,

@ -168,7 +168,7 @@ class AppointmentCheckinBottomSheet extends StatelessWidget {
// page: AppointmentQueuePage(), // page: AppointmentQueuePage(),
// ), // ),
// ); // );
}, isFullScreen: false); }, isFullScreen: false, isAutoDismiss: true, isCloseButtonVisible: false);
}, },
onError: (error) { onError: (error) {
LoaderBottomSheet.hideLoader(); 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/size_utils.dart';
import 'package:hmg_patient_app_new/core/utils/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/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/features/authentication/authentication_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/authentication/login.dart'; import 'package:hmg_patient_app_new/presentation/authentication/login.dart';
@ -89,15 +90,11 @@ class _SavedLogin extends State<SavedLogin> {
: SizedBox(), : SizedBox(),
SizedBox(height: 24.h), SizedBox(height: 24.h),
Container( Container(
padding: EdgeInsets.all(16.h), padding: EdgeInsets.all(16.h),
decoration: BoxDecoration( decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 20.h, hasShadow: false, isCustomShadow: [
color: AppColors.whiteColor,
border: Border.all(color: AppColors.whiteColor),
borderRadius: BorderRadius.circular(24.h),
boxShadow: [
BoxShadow(color: Color(0x0D000000), blurRadius: 16.h, offset: Offset(0, 0), spreadRadius: 5.h), BoxShadow(color: Color(0x0D000000), blurRadius: 16.h, offset: Offset(0, 0), spreadRadius: 5.h),
], ]),
),
child: Column( child: Column(
children: [ children: [
// Last login info - show WhatsApp only if isOther AND loginType is SMS // Last login info - show WhatsApp only if isOther AND loginType is SMS

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

@ -264,7 +264,7 @@ class _ImmediateLiveCarePaymentPageState extends State<ImmediateLiveCarePaymentP
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
LocaleKeys.amountBeforeTax.tr().toText14(isBold: true), 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), isSaudiCurrency: true),
], ],
).paddingSymmetrical(24.h, 0.h), ).paddingSymmetrical(24.h, 0.h),
@ -273,7 +273,7 @@ class _ImmediateLiveCarePaymentPageState extends State<ImmediateLiveCarePaymentP
children: [ children: [
LocaleKeys.vat15.tr().toText14(isBold: true, color: AppColors.greyTextColor), LocaleKeys.vat15.tr().toText14(isBold: true, color: AppColors.greyTextColor),
Utils.getPaymentAmountWithSymbol( 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), isSaudiCurrency: true),
], ],
).paddingSymmetrical(24.h, 0.h), ).paddingSymmetrical(24.h, 0.h),
@ -282,7 +282,7 @@ class _ImmediateLiveCarePaymentPageState extends State<ImmediateLiveCarePaymentP
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
"".toText14(isBold: true), "".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), isSaudiCurrency: true),
], ],
).paddingSymmetrical(24.h, 0.h), ).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 //TODO: Need to pass dynamic params to the payment request instead of static values
browser?.openPaymentBrowser( browser?.openPaymentBrowser(
num.parse(immediateLiveCareViewModel.liveCareImmediateAppointmentFeesList.total!), num.parse(immediateLiveCareViewModel.liveCareImmediateAppointmentFeesList.total ?? "0.0"),
"LiveCare Payment", "LiveCare Payment",
transID, transID,
"12", "12",
@ -547,7 +547,7 @@ class _ImmediateLiveCarePaymentPageState extends State<ImmediateLiveCarePaymentP
// customerEmail: projectViewModel.authenticatedUserObject.user.emailAddress, // customerEmail: projectViewModel.authenticatedUserObject.user.emailAddress,
customerEmail: "CustID_${appState.getAuthenticatedUser()!.patientId.toString()}@HMG.com", customerEmail: "CustID_${appState.getAuthenticatedUser()!.patientId.toString()}@HMG.com",
orderDescription: "LiveCare Payment", orderDescription: "LiveCare Payment",
orderAmount: double.parse(immediateLiveCareViewModel.liveCareImmediateAppointmentFeesList.total!), orderAmount: double.parse((immediateLiveCareViewModel.liveCareImmediateAppointmentFeesList.total ?? "0.0")),
merchantReference: transID, merchantReference: transID,
merchantIdentifier: payfortViewModel.payfortProjectDetailsRespModel!.merchantIdentifier, merchantIdentifier: payfortViewModel.payfortProjectDetailsRespModel!.merchantIdentifier,
applePayAccessCode: payfortViewModel.payfortProjectDetailsRespModel!.accessCode, 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/buttons/custom_button.dart';
import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.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:hmg_patient_app_new/widgets/countdown_timer.dart';
import 'package:lottie/lottie.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
@ -97,17 +98,28 @@ class _ImmediateLiveCarePendingRequestPageState extends State<ImmediateLiveCareP
SizedBox(width: 8.w), SizedBox(width: 8.w),
AppCustomChipWidget( AppCustomChipWidget(
icon: AppAssets.appointment_calendar_icon, 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), // 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),
SizedBox(height: 8.h), SizedBox(height: 8.h),
LocaleKeys.yourTurnIsAfterPatients LocaleKeys.yourTurnIsAfterPatients.tr(namedArgs: {
.tr(namedArgs: {'count': (immediateLiveCareViewModel.patientLiveCareHistoryList[0].patCount ?? 0).toString()}, context: context).toText14(isBold: true), '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), // "Your turn is after ${immediateLiveCareViewModel.patientLiveCareHistoryList[0].patCount} patients.".toText16(isBold: true),
SizedBox(height: 8.h), SizedBox(height: 8.h),
], ],
@ -127,7 +139,7 @@ class _ImmediateLiveCarePendingRequestPageState extends State<ImmediateLiveCareP
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
"Expected waiting time: ".toText16(isBold: true), LocaleKeys.waitingTime.tr(context: context).toText16(isBold: true),
SizedBox(height: 8.h), SizedBox(height: 8.h),
ValueListenableBuilder<Duration>( ValueListenableBuilder<Duration>(
valueListenable: immediateLiveCareVM.durationNotifier, valueListenable: immediateLiveCareVM.durationNotifier,

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

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

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

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

@ -74,7 +74,8 @@ class _HabibWalletState extends State<HabibWalletPage> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
"${_appState.getAuthenticatedUser()!.firstName!} ${_appState.getAuthenticatedUser()!.lastName!}".toText19(isBold: true, color: Colors.white), "${_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, ).expanded,
Utils.buildSvgWithAssets(icon: AppAssets.habiblogo, width: 24.h, height: 24.h, applyThemeColor: false), 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), LocaleKeys.balanceAmount.tr(context: context).toText14(isBold: true, color: Colors.white),
SizedBox(height: 4.h), SizedBox(height: 4.h),
Consumer<HabibWalletViewModel>(builder: (context, habibWalletVM, child) { Consumer<HabibWalletViewModel>(builder: (context, habibWalletVM, child) {
return Utils.getPaymentAmountWithSymbol2(num.parse(NumberFormat.decimalPattern().format(habibWalletVM.habibWalletAmount)), return Utils.getPaymentAmountWithSymbol2(
textColor: Colors.white, iconColor: Colors.white, iconSize: 16, isExpanded: false) 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); .toShimmer2(isShow: habibWalletVM.isWalletAmountLoading, radius: 12.h, width: 80.h, height: 24.h);
}), }),
], ],
@ -140,7 +148,7 @@ class _HabibWalletState extends State<HabibWalletPage> {
children: [ children: [
Expanded(child: habibWalletVM.habibWalletBalanceList[index].projectDescription!.toText16(isBold: true, color: AppColors.textColor)), Expanded(child: habibWalletVM.habibWalletBalanceList[index].projectDescription!.toText16(isBold: true, color: AppColors.textColor)),
Utils.getPaymentAmountWithSymbol2(num.parse(NumberFormat.decimalPattern().format(habibWalletVM.habibWalletBalanceList[index].patientAdvanceBalanceAmount!)), 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); ).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/loader/bottomsheet_loader.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.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:hmg_patient_app_new/widgets/routes/spring_page_route_builder.dart';
import 'package:lottie/lottie.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:smooth_corner/smooth_corner.dart'; import 'package:smooth_corner/smooth_corner.dart';
@ -264,15 +265,15 @@ class _LandingPageState extends State<LandingPage> {
borderColor: AppColors.secondaryLightRedColor, borderColor: AppColors.secondaryLightRedColor,
textColor: AppColors.primaryRedColor, textColor: AppColors.primaryRedColor,
fontSize: 14.f, fontSize: 14.f,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w700,
borderRadius: 12.r, borderRadius: 12.r,
padding: EdgeInsets.fromLTRB(12.h, 0, 12.h, 0), padding: EdgeInsets.fromLTRB(12.h, 0, 12.h, 0),
height: 40.h, height: 40.h,
), ),
Consumer<TodoSectionViewModel>(builder: (context, todoSectionVM, child) { Consumer<TodoSectionViewModel>(builder: (context, todoSectionVM, child) {
return Row( return Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
spacing: 18.h, // spacing: 18.h,
children: [ children: [
Stack(clipBehavior: Clip.none, children: [ Stack(clipBehavior: Clip.none, children: [
if (appState.isAuthenticated) if (appState.isAuthenticated)
@ -292,7 +293,7 @@ class _LandingPageState extends State<LandingPage> {
}), }),
(appState.isAuthenticated && (int.parse(todoSectionVM.notificationsCount ?? "0") > 0)) (appState.isAuthenticated && (int.parse(todoSectionVM.notificationsCount ?? "0") > 0))
? Positioned( ? Positioned(
right: appState.isArabic() ? 8.w : -8.w, // right: appState.isArabic() ? 8.w : -8.w,
top: -8.h, top: -8.h,
// left: 4.h, // left: 4.h,
// bottom: 4.h, // bottom: 4.h,
@ -318,6 +319,7 @@ class _LandingPageState extends State<LandingPage> {
) )
: SizedBox.shrink(), : SizedBox.shrink(),
]), ]),
SizedBox(width: 24.w,),
Utils.buildSvgWithAssets(icon: AppAssets.location, height: 24.h, width: 24.w).onPress(() { Utils.buildSvgWithAssets(icon: AppAssets.location, height: 24.h, width: 24.w).onPress(() {
// openIndoorNavigationBottomSheet(context); // openIndoorNavigationBottomSheet(context);
showCommonBottomSheetWithoutHeight( showCommonBottomSheetWithoutHeight(
@ -328,6 +330,7 @@ class _LandingPageState extends State<LandingPage> {
isFullScreen: false, isFullScreen: false,
); );
}), }),
// Utils.buildSvgWithAssets(icon: AppAssets.contact_icon, height: 24.h, width: 24.h).onPress(() { // Utils.buildSvgWithAssets(icon: AppAssets.contact_icon, height: 24.h, width: 24.h).onPress(() {
// showCommonBottomSheetWithoutHeight( // showCommonBottomSheetWithoutHeight(
// context, // context,
@ -338,10 +341,10 @@ class _LandingPageState extends State<LandingPage> {
// ); // );
// }), // }),
!appState.isAuthenticated !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')); context.setLocale(appState.isArabic() ? Locale('en', 'US') : Locale('ar', 'SA'));
}) })])
: SizedBox.shrink() : SizedBox()
], ],
); );
}), }),
@ -483,29 +486,37 @@ class _LandingPageState extends State<LandingPage> {
) )
: SizedBox( : SizedBox(
height: 255.h + 20 + 30, // itemHeight + shadow padding (10 top + 10 bottom) + pagination dots space height: 255.h + 20 + 30, // itemHeight + shadow padding (10 top + 10 bottom) + pagination dots space
child: Swiper( child: Builder(
itemCount: myAppointmentsVM.isMyAppointmentsLoading builder: (context) {
? 3 final int swiperItemCount = myAppointmentsVM.isMyAppointmentsLoading
: myAppointmentsVM.patientAppointmentsHistoryList.length < 3 ? 3
? myAppointmentsVM.patientAppointmentsHistoryList.length : myAppointmentsVM.patientAppointmentsHistoryList.length < 3
: 3, ? myAppointmentsVM.patientAppointmentsHistoryList.length
layout: SwiperLayout.STACK, : 3;
loop: false, final bool isArabic = appState.isArabic();
itemWidth: MediaQuery.of(context).size.width - 48.h, return Swiper(
indicatorLayout: PageIndicatorLayout.COLOR, itemCount: swiperItemCount,
axisDirection: appState.isArabic() ? AxisDirection.right : AxisDirection.left, layout: SwiperLayout.STACK,
controller: _controller, loop: false,
itemHeight: 255.h + 20, itemWidth: MediaQuery.of(context).size.width - 48.h,
// extra space for shadow indicatorLayout: PageIndicatorLayout.COLOR,
pagination: SwiperPagination( axisDirection: isArabic ? AxisDirection.right : AxisDirection.left,
alignment: Alignment.bottomCenter, controller: _controller,
margin: EdgeInsets.only(top: 220.h + 20 + 8 + 24), index: isArabic ? swiperItemCount - 1 : 0,
builder: DotSwiperPaginationBuilder(color: Color(0xffD9D9D9), activeColor: AppColors.blackBgColor), itemHeight: 255.h + 20,
), // extra space for shadow
itemBuilder: (BuildContext context, int index) { pagination: SwiperPagination(
return Padding( alignment: Alignment.bottomCenter,
padding: const EdgeInsets.symmetric(vertical: 10), margin: EdgeInsets.only(top: 220.h + 20 + 8 + 24),
child: getIndexSwiperCard(index), 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), LocaleKeys.quickLinks.tr(context: context).toText16(isBold: true),
Row( Row(
children: [ 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), SizedBox(width: 2.h),
Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 14.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) { Widget _buildQueueHeader(int currentStatus) {
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
AppCustomChipWidget( AppCustomChipWidget(
labelText: currentStatus == 0 ? LocaleKeys.inQueue.tr() : LocaleKeys.yourTurn.tr(), labelText: currentStatus == 0 ? LocaleKeys.inQueue.tr() : LocaleKeys.yourTurn.tr(),
backgroundColor: Utils.getCardBorderColor(currentStatus).withValues(alpha: 0.20), backgroundColor: Utils.getCardBorderColor(currentStatus).withValues(alpha: 0.20),
textColor: Utils.getCardBorderColor(currentStatus), textColor: Utils.getCardBorderColor(currentStatus),
), ),
Utils.buildSvgWithAssets( Container(
icon: AppAssets.waiting_icon, decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
width: 24.h, color: AppColors.greyColor,
height: 24.h, 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, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Row( Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
AppCustomChipWidget( AppCustomChipWidget(
labelText: liveCareData.stringCallStatus, labelText: liveCareData.stringCallStatus,
@ -1162,13 +1178,42 @@ class _LandingPageState extends State<LandingPage> {
false, 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( Container(
icon: AppAssets.waiting_icon, decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
width: 24.h, color: AppColors.greyColor,
height: 24.h, 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:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_assets.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/size_utils.dart';
import 'package:hmg_patient_app_new/core/utils/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/string_extensions.dart';
@ -76,13 +78,14 @@ class HabibWalletCard extends StatelessWidget {
// ], // ],
// ), // ),
SizedBox(height: 4.h), SizedBox(height: 4.h),
Row( Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Column( Consumer<HabibWalletViewModel>(builder: (context, habibWalletVM, child) {
crossAxisAlignment: CrossAxisAlignment.start, return Row(
children: [ mainAxisSize: MainAxisSize.max,
Consumer<HabibWalletViewModel>(builder: (context, habibWalletVM, child) { children: [
return Row( Row(
children: [ children: [
Utils.buildSvgWithAssets( Utils.buildSvgWithAssets(
icon: AppAssets.saudi_riyal_icon, icon: AppAssets.saudi_riyal_icon,
@ -98,58 +101,70 @@ class HabibWalletCard extends StatelessWidget {
.toText32(isBold: true, isEnglishOnly: true) .toText32(isBold: true, isEnglishOnly: true)
.toShimmer2(isShow: habibWalletVM.isWalletAmountLoading, radius: 12.h, width: 80.h, height: 40.h), .toShimmer2(isShow: habibWalletVM.isWalletAmountLoading, radius: 12.h, width: 80.h, height: 40.h),
], ],
); ),
}), Spacer(),
Padding( Utils.getPaymentMethods(),
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(),
),
], ],
), ),
SizedBox(height: 16.h), SizedBox(height: 16.h),
CustomButton( Row(
height: 40.h, children: [
icon: AppAssets.recharge_icon, Expanded(
iconColor: AppColors.infoColor, flex: 6,
iconSize: 24.h, child: CustomButton(
backgroundColor: AppColors.infoColor.withAlpha(15), height: 40.h,
textColor: AppColors.infoColor, icon: AppAssets.recharge_icon,
text: LocaleKeys.recharge.tr(context: context), iconColor: AppColors.infoColor,
borderWidth: 0.w, iconSize: 24.h,
fontWeight: FontWeight.w600, backgroundColor: AppColors.infoColor.withAlpha(15),
borderColor: AppColors.infoColor.withAlpha(15), textColor: AppColors.infoColor,
padding: EdgeInsets.fromLTRB(4, 0, 12, 0), text: LocaleKeys.recharge.tr(context: context),
fontSize: 14.f, borderWidth: 0.w,
onPressed: () { fontWeight: FontWeight.w600,
Navigator.of(context).push(CustomPageRoute(page: RechargeWalletPage())); 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) { if (analysis.summary != null && analysis.summary!.isNotEmpty) {
expandableItems.add( expandableItems.add(
ExpandableListItem( ExpandableListItem(
backgroundColor: Colors.transparent,
expandedBackgroundColor:Colors.transparent ,
title: LocaleKeys.summary.tr(context: context).toText18(weight: FontWeight.w700, color: AppColors.blackColor), title: LocaleKeys.summary.tr(context: context).toText18(weight: FontWeight.w700, color: AppColors.blackColor),
initiallyExpanded: true, initiallyExpanded: true,
children: [ children: [
SizedBox(height: 10.h), SizedBox(height: 10.h),
Container( Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 12.r, side: BorderSide(width: 1, color: Color(0xFF0B85F7))), decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 12.r, side: BorderSide(width: 1, color: Color(0xFF0B85F7))),
padding: EdgeInsets.all(16.r), padding: EdgeInsets.all(16.r),
child: (analysis.summary ?? "").toText14(color: AppColors.textColorLight, height: 1.5, weight: FontWeight.w400), 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) { if (analysis.aiGeneratedAttributes != null && analysis.aiGeneratedAttributes!.isNotEmpty) {
expandableItems.add( expandableItems.add(
ExpandableListItem( ExpandableListItem(
backgroundColor: Colors.transparent,
expandedBackgroundColor:Colors.transparent ,
title: LocaleKeys.labResults.tr(context: context).toText18(weight: FontWeight.w700, color: AppColors.blackColor), title: LocaleKeys.labResults.tr(context: context).toText18(weight: FontWeight.w700, color: AppColors.blackColor),
children: [ children: [
SizedBox(height: 10.h), SizedBox(height: 10.h),
@ -84,6 +90,8 @@ class _LabAiAnalysisDetailedPageState extends State<LabAiAnalysisDetailedPage> {
if (analysis.aiPredictions != null && analysis.aiPredictions!.isNotEmpty) { if (analysis.aiPredictions != null && analysis.aiPredictions!.isNotEmpty) {
expandableItems.add( expandableItems.add(
ExpandableListItem( ExpandableListItem(
backgroundColor: Colors.transparent,
expandedBackgroundColor:Colors.transparent ,
title: LocaleKeys.prediction.tr(context: context).toText18(weight: FontWeight.w700, color: AppColors.blackColor), title: LocaleKeys.prediction.tr(context: context).toText18(weight: FontWeight.w700, color: AppColors.blackColor),
children: [ children: [
SizedBox(height: 10.h), SizedBox(height: 10.h),
@ -105,6 +113,8 @@ class _LabAiAnalysisDetailedPageState extends State<LabAiAnalysisDetailedPage> {
if (analysis.aiRecommendations != null && analysis.aiRecommendations!.isNotEmpty) { if (analysis.aiRecommendations != null && analysis.aiRecommendations!.isNotEmpty) {
expandableItems.add( expandableItems.add(
ExpandableListItem( ExpandableListItem(
backgroundColor: Colors.transparent,
expandedBackgroundColor:Colors.transparent ,
title: LocaleKeys.suggestions.tr(context: context).toText18(weight: FontWeight.w700, color: AppColors.blackColor), title: LocaleKeys.suggestions.tr(context: context).toText18(weight: FontWeight.w700, color: AppColors.blackColor),
children: [ children: [
SizedBox(height: 10.h), SizedBox(height: 10.h),
@ -152,6 +162,8 @@ class _LabAiAnalysisDetailedPageState extends State<LabAiAnalysisDetailedPage> {
if (analysis.riskFactors != null && analysis.riskFactors!.isNotEmpty) { if (analysis.riskFactors != null && analysis.riskFactors!.isNotEmpty) {
expandableItems.add( expandableItems.add(
ExpandableListItem( ExpandableListItem(
backgroundColor: Colors.transparent,
expandedBackgroundColor:Colors.transparent ,
title: LocaleKeys.riskFactors.tr(context: context).toText18(weight: FontWeight.w700, color: AppColors.blackColor), title: LocaleKeys.riskFactors.tr(context: context).toText18(weight: FontWeight.w700, color: AppColors.blackColor),
children: [ children: [
SizedBox(height: 10.h), SizedBox(height: 10.h),
@ -221,6 +233,8 @@ class _LabAiAnalysisDetailedPageState extends State<LabAiAnalysisDetailedPage> {
if (analysis.prevention != null && analysis.prevention!.isNotEmpty) { if (analysis.prevention != null && analysis.prevention!.isNotEmpty) {
expandableItems.add( expandableItems.add(
ExpandableListItem( ExpandableListItem(
backgroundColor: Colors.transparent,
expandedBackgroundColor:Colors.transparent ,
title: LocaleKeys.prevention.tr(context: context).toText18(weight: FontWeight.w700, color: AppColors.blackColor), title: LocaleKeys.prevention.tr(context: context).toText18(weight: FontWeight.w700, color: AppColors.blackColor),
children: [ children: [
SizedBox(height: 10.h), SizedBox(height: 10.h),
@ -308,10 +322,11 @@ class _LabAiAnalysisDetailedPageState extends State<LabAiAnalysisDetailedPage> {
else else
CustomExpandableList( CustomExpandableList(
expansionMode: ExpansionMode.exactlyOne, expansionMode: ExpansionMode.exactlyOne,
dividerColor: Color(0xff2b353e1a), dividerColor: AppColors.dividerColor,
itemPadding: EdgeInsets.symmetric(vertical: 16.h, horizontal: 14.h), itemPadding: EdgeInsets.symmetric(vertical: 16.h, horizontal: 14.h),
items: expandableItems, items: expandableItems,
theme: ExpandableListTheme.custom( theme: ExpandableListTheme.custom(
defaultTrailingIcon: Utils.buildSvgWithAssets(icon: AppAssets.arrow_down, height: 22.h, width: 22.w, iconColor: AppColors.textColor), defaultTrailingIcon: Utils.buildSvgWithAssets(icon: AppAssets.arrow_down, height: 22.h, width: 22.w, iconColor: AppColors.textColor),
), ),
).paddingSymmetrical(16.w, 0.0), ).paddingSymmetrical(16.w, 0.0),

@ -49,48 +49,38 @@ class LabOrderResultItem extends StatelessWidget {
SizedBox(height: 12.h), SizedBox(height: 12.h),
Directionality( Directionality(
textDirection: ui.TextDirection.ltr, textDirection: ui.TextDirection.ltr,
child: Row( child: Column(
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [ 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( child: Text(
"${tests?.resultValue} ${tests?.uOM}", "(${LocaleKeys.referenceRange.tr(context: context)}: ${tests?.referanceRange})",
style: TextStyle( style: TextStyle(
fontSize: 24.f, fontSize: 12.f,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
fontFamily: 'Poppins', fontFamily: 'Poppins',
color: tests!.checkIfGraphShouldBeDisplayed() color: AppColors.greyTextColor,
? 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,
),
), ),
softWrap: true,
), ),
) )
], ],

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

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

@ -61,7 +61,7 @@ class InvoiceListCard extends StatelessWidget {
Column( Column(
children: [ children: [
Image.network( Image.network(
getInvoicesListResponseModel.doctorImageURL!, getInvoicesListResponseModel.doctorImageUrl ?? 'https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png',
width: 63.h, width: 63.h,
height: 63.h, height: 63.h,
fit: BoxFit.cover, fit: BoxFit.cover,
@ -73,10 +73,10 @@ class InvoiceListCard extends StatelessWidget {
height: 40.h, height: 40.h,
decoration: BoxDecoration( decoration: BoxDecoration(
color: AppColors.whiteColor, color: AppColors.whiteColor,
shape: BoxShape.circle, // Makes the container circular shape: BoxShape.circle,
border: Border.all( border: Border.all(
color: AppColors.scaffoldBgColor, // Color of the border color: AppColors.scaffoldBgColor,
width: 1.5.w, // Width of the border width: 1.5.w,
), ),
), ),
child: Column( child: Column(
@ -84,7 +84,7 @@ class InvoiceListCard extends StatelessWidget {
children: [ children: [
Utils.buildSvgWithAssets(icon: AppAssets.rating_icon, width: 15.w, height: 15.h, applyThemeColor: false), Utils.buildSvgWithAssets(icon: AppAssets.rating_icon, width: 15.w, height: 15.h, applyThemeColor: false),
SizedBox(height: 2.h), SizedBox(height: 2.h),
"${getInvoicesListResponseModel.decimalDoctorRate}".toText11(isBold: true, color: AppColors.textColor), "${getInvoicesListResponseModel.decimalDoctorRate ?? '0.0'}".toText11(isBold: true, color: AppColors.textColor),
], ],
), ),
).circle(100), ).circle(100),
@ -96,7 +96,10 @@ class InvoiceListCard extends StatelessWidget {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ 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), SizedBox(height: 8.h),
Wrap( Wrap(
direction: Axis.horizontal, direction: Axis.horizontal,
@ -104,28 +107,30 @@ class InvoiceListCard extends StatelessWidget {
runSpacing: 6.h, runSpacing: 6.h,
children: [ children: [
AppCustomChipWidget( 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), labelPadding: EdgeInsetsDirectional.only(start: 6.w, end: 6.w),
isEnglishOnly: true, isEnglishOnly: true,
), ),
AppCustomChipWidget( AppCustomChipWidget(
labelText: labelText: ((getInvoicesListResponseModel.clinicName ?? LocaleKeys.clinic.tr(context: context)).length > 15
(getInvoicesListResponseModel.clinicName!.length > 15 ? '${getInvoicesListResponseModel.clinicName!.substring(0, 12)}...' : getInvoicesListResponseModel.clinicName!), ? '${(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), labelPadding: EdgeInsetsDirectional.only(start: 4.w, end: 4.w),
), ),
AppCustomChipWidget( AppCustomChipWidget(
labelText: getInvoicesListResponseModel.projectName!, labelText: getInvoicesListResponseModel.projectName ?? LocaleKeys.hospital.tr(context: context),
labelPadding: EdgeInsetsDirectional.only(start: 6.w, end: 6.w), labelPadding: EdgeInsetsDirectional.only(start: 6.w, end: 6.w),
), ),
Directionality( if (getInvoicesListResponseModel.appointmentDate != null)
textDirection: ui.TextDirection.ltr, Directionality(
child: AppCustomChipWidget( textDirection: ui.TextDirection.ltr,
labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: 6.w), child: AppCustomChipWidget(
icon: AppAssets.doctor_calendar_icon, labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: 6.w),
labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(getInvoicesListResponseModel.appointmentDate), false), icon: AppAssets.doctor_calendar_icon,
isEnglishOnly: true, 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 { ).paddingSymmetrical(24.h, 12.h).onPress(() async {
final _dialogService = getIt.get<DialogService>(); final _dialogService = getIt.get<DialogService>();
await _dialogService.showCommonBottomSheetWithoutH( await _dialogService.showCommonBottomSheetWithoutH(
message: LocaleKeys.aiDisclaimer.tr(), message: LocaleKeys.aiDisclaimerRad.tr(),
label: LocaleKeys.consent.tr(), label: LocaleKeys.consent.tr(),
okLabel: LocaleKeys.acceptLbl.tr(), okLabel: LocaleKeys.acceptLbl.tr(),
cancelLabel: LocaleKeys.rejectView.tr(), cancelLabel: LocaleKeys.rejectView.tr(),

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

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

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

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

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

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

Loading…
Cancel
Save