Merge branch 'refs/heads/master' into dev_aamir

# Conflicts:
#	android/app/src/main/AndroidManifest.xml
pull/236/head
aamir-csol 3 days ago
commit 90bcdf674d

@ -39,7 +39,6 @@
<uses-permission <uses-permission
android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE"
tools:node="remove" /> tools:node="remove" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<!-- Gallery/Photo permissions for Android 13+ (API 33+) --> <!-- Gallery/Photo permissions for Android 13+ (API 33+) -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
@ -52,6 +51,7 @@
<uses-permission <uses-permission
android:name="android.permission.ACCESS_BACKGROUND_LOCATION" android:name="android.permission.ACCESS_BACKGROUND_LOCATION"
tools:node="remove" /> <!-- <uses-permission android:name="android.permission.INTERNET" /> --> tools:node="remove" /> <!-- <uses-permission android:name="android.permission.INTERNET" /> -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" /> <uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 573 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 KiB

@ -69,7 +69,7 @@
"date": "التاريخ", "date": "التاريخ",
"time": "الوقت", "time": "الوقت",
"pendingPayment": "معلق للدفع", "pendingPayment": "معلق للدفع",
"payNow": "ادفع الآن", "payNow": "الدفع",
"viewQR": "عرض رمز الاستجابة السريعة", "viewQR": "عرض رمز الاستجابة السريعة",
"instruction": "تعليمات", "instruction": "تعليمات",
"livecare": "لايف كير", "livecare": "لايف كير",
@ -83,6 +83,8 @@
"bookSuccessConfirmMore2412": "ستكون عملية الدفع عبر الإنترنت متاحة قبل 24 ساعة <20><>ن الموعد.", "bookSuccessConfirmMore2412": "ستكون عملية الدفع عبر الإنترنت متاحة قبل 24 ساعة <20><>ن الموعد.",
"upcomingPaymentPending": "سيتم تفعيل الدفع عبر الإنترنت قبل 24 ساعة من موعد الموعد", "upcomingPaymentPending": "سيتم تفعيل الدفع عبر الإنترنت قبل 24 ساعة من موعد الموعد",
"upcomingPaymentNow": "ادفع عبر الإنترنت الآن لتجنب الانتظار الطويل", "upcomingPaymentNow": "ادفع عبر الإنترنت الآن لتجنب الانتظار الطويل",
"timeUntilAppointment": "الوقت المتبقي حتى الموعد",
"appointmentTimePassed": "انتهى وقت الموعد",
"upcomingQR": "استخدم رمز الاستجابة السريعة لتسجيل الوصول في المستشفى", "upcomingQR": "استخدم رمز الاستجابة السريعة لتسجيل الوصول في المستشفى",
"upcomingVirtual": "هذا موعد افتراضي، يرجى الالتزام بالتعليمات لتجربة سلسة.", "upcomingVirtual": "هذا موعد افتراضي، يرجى الالتزام بالتعليمات لتجربة سلسة.",
"upcomingLivecare": "هذا موعد لايف كير", "upcomingLivecare": "هذا موعد لايف كير",
@ -171,9 +173,9 @@
"emailSentError": "خطأ في إرسال البريد الإلكتروني", "emailSentError": "خطأ في إرسال البريد الإلكتروني",
"close": "إغلاق", "close": "إغلاق",
"closeIt": "أغلق", "closeIt": "أغلق",
"booked": "محجوز", "booked": "تم الحجز",
"confirmed": "مؤكد", "confirmed": "مؤكد",
"arrived": "وصل", "arrived": " تم الوصول",
"payNowBookSuccess": "ادفع الآن عبر تطبيق الحبيب", "payNowBookSuccess": "ادفع الآن عبر تطبيق الحبيب",
"payNowBookSuccesstext1": "ادفع الآن باستخدام خدمة الدفع عبر الإنترنت من بوابات الدفع الآمنة", "payNowBookSuccesstext1": "ادفع الآن باستخدام خدمة الدفع عبر الإنترنت من بوابات الدفع الآمنة",
"payNowBookSuccesstext2": "يمكنك أيضًا الدفع لاحقًا عبر الدفع الإلكتروني أو في المستشفى.", "payNowBookSuccesstext2": "يمكنك أيضًا الدفع لاحقًا عبر الدفع الإلكتروني أو في المستشفى.",
@ -274,7 +276,7 @@
"parkingDescription": "خدمة المواقف هي لك لمسح موقع السيارة حتى تتمكن من العثور عليها بسهولة عند مغادرتك. انقر على زر (مسح الموقف) لحفظ موقع الموقف، ثم سيظهر زر (عرض موقفي) لإظهار الطريق إلى الموقف. إذا كنت ترغب في إعادة مسح موقف السيارة QR فقط انقر على (مسح بياناتي).", "parkingDescription": "خدمة المواقف هي لك لمسح موقع السيارة حتى تتمكن من العثور عليها بسهولة عند مغادرتك. انقر على زر (مسح الموقف) لحفظ موقع الموقف، ثم سيظهر زر (عرض موقفي) لإظهار الطريق إلى الموقف. إذا كنت ترغب في إعادة مسح موقف السيارة QR فقط انقر على (مسح بياناتي).",
"appointments": "المواعيد", "appointments": "المواعيد",
"all2": "الكل", "all2": "الكل",
"checkinOption": "تسجيل الوصول", "checkinOption": "تسجيل الحضور",
"readBarcode": "قراءة الكود", "readBarcode": "قراءة الكود",
"showMyPark": "عرض الموقف", "showMyPark": "عرض الموقف",
"clearMyData": "امسح البيانات", "clearMyData": "امسح البيانات",
@ -296,7 +298,7 @@
"radiology": "الأشعة", "radiology": "الأشعة",
"radiologySubtitle": "النتيجة", "radiologySubtitle": "النتيجة",
"lab": "المختبر", "lab": "المختبر",
"labSubtitle": "النتائج", "labSubtitle": "نتائج",
"medicines": "الأدوية", "medicines": "الأدوية",
"medicinesSubtitle": "الوصفات", "medicinesSubtitle": "الوصفات",
"vitalSigns": "علامات حيوية", "vitalSigns": "علامات حيوية",
@ -307,13 +309,16 @@
"vitalSignObese": "بدين", "vitalSignObese": "بدين",
"vitalSignOverweight": "زيادة الوزن", "vitalSignOverweight": "زيادة الوزن",
"vitalSignUnderweight": "نقص الوزن", "vitalSignUnderweight": "نقص الوزن",
"vitalSignSkinny": "نحيف جداً",
"myMedical": "نشط", "myMedical": "نشط",
"myMedicalSubtitle": "الأدوية", "myMedicalSubtitle": "الأدوية",
"myDoctor": "أطبائي", "myDoctor": "أطبائي",
"myDoctorSubtitle": "القائمة", "myDoctorSubtitle": "القائمة",
"myDoctorSubtitle2": "قائمة",
"eye": "العين", "eye": "العين",
"eyeSubtitle": "القياس", "eyeSubtitle": "القياس",
"insurance": "التأمين", "insurance": "التأمين",
"insurance2": "تأمين",
"insuranceSubtitle": "البطاقة", "insuranceSubtitle": "البطاقة",
"updateInsurance": "تحديث", "updateInsurance": "تحديث",
"updateInsuranceSubtitle": "التأمين", "updateInsuranceSubtitle": "التأمين",
@ -328,6 +333,7 @@
"monthly": "شهري", "monthly": "شهري",
"monthlySubtitle": "التقرير", "monthlySubtitle": "التقرير",
"sick": "مريض", "sick": "مريض",
"sick2": "المريضة",
"sickSubtitle": "الإجازات", "sickSubtitle": "الإجازات",
"myBalance": "رصيدي", "myBalance": "رصيدي",
"myBalanceSubtitle": "الرصيد", "myBalanceSubtitle": "الرصيد",
@ -490,9 +496,11 @@
"refferalTitle": "إحالة إلكترونية", "refferalTitle": "إحالة إلكترونية",
"refferalSubTitle": "الخدمة", "refferalSubTitle": "الخدمة",
"healthCare": "الرعاية الصحية", "healthCare": "الرعاية الصحية",
"emergency": "حالة طوارئ", "emergency": "طوارئ",
"emergency2": "الطوارئ",
"erservices": "خدمات الطوارئ", "erservices": "خدمات الطوارئ",
"services2": "الخدمات", "services2": "الخدمات",
"services3": "خدمات",
"cantSeeProfile": "لرؤية ملفك الطبي، يرجى تسجيل الدخول أو التسجيل الآن", "cantSeeProfile": "لرؤية ملفك الطبي، يرجى تسجيل الدخول أو التسجيل الآن",
"loginRegisterNow": "تسجيل الدخول أو التسجيل الآن", "loginRegisterNow": "تسجيل الدخول أو التسجيل الآن",
"hmgPharmacy": "صيدلية الحبيب", "hmgPharmacy": "صيدلية الحبيب",
@ -765,6 +773,7 @@
"erConsultation": "تتيح لك هذه الخدمة إجراء استشارة افتراضية عبر الإنترنت عبر مكالمة فيديو مباشرة مع الطبيب من أي مكان وفي أي وقت.", "erConsultation": "تتيح لك هذه الخدمة إجراء استشارة افتراضية عبر الإنترنت عبر مكالمة فيديو مباشرة مع الطبيب من أي مكان وفي أي وقت.",
"myInvoice": "القائمة", "myInvoice": "القائمة",
"invoiceList": "فواتيري", "invoiceList": "فواتيري",
"invoiceList2": "فواتيري",
"allInvoices": "كل الفواتير", "allInvoices": "كل الفواتير",
"hospitals": "المستشفيات", "hospitals": "المستشفيات",
"clinics": "العيادات", "clinics": "العيادات",
@ -888,7 +897,7 @@
"to": "إلى", "to": "إلى",
"startDate": "تاريخ البدء", "startDate": "تاريخ البدء",
"endDate": "تاريخ الانتهاء", "endDate": "تاريخ الانتهاء",
"walkin": "زيارة بدون موعد", "walkin": "بدون موعد",
"laserClinic": "عيادة الليزر", "laserClinic": "عيادة الليزر",
"continueString": "يكمل", "continueString": "يكمل",
"covid_info": "تجري مستشفيات د. سليمان الحبيب فحص فيروس كورونا المستجد وتصدر شهادات السفر على مدار الساعة، طوال أيام الأسبوع، وبسرعة ودقة عالية. يمكن للراغبين في الاستفادة من هذه الخدمة زيارة أحد فروع مستشفيات د. سليمان الحبيب وإجراء فحص كورونا خلال بضع دقائق والحصول على النتائج خلال عدة ساعات خدمة فحص فيروس كورونا Covid 19 بتقنية PCR للكشف عن الفيروس وفقاً لأعلى المعايير العالمية وبأحدث أجهزة RT-PCR عالية الدقة (GeneXpert الأمريكي وغيره)، وهي طرق معتمدة من قبل هيئة الغذاء والدواء وكذلك من قبل المركز السعودي للوقاية من الأمراض المُعدية", "covid_info": "تجري مستشفيات د. سليمان الحبيب فحص فيروس كورونا المستجد وتصدر شهادات السفر على مدار الساعة، طوال أيام الأسبوع، وبسرعة ودقة عالية. يمكن للراغبين في الاستفادة من هذه الخدمة زيارة أحد فروع مستشفيات د. سليمان الحبيب وإجراء فحص كورونا خلال بضع دقائق والحصول على النتائج خلال عدة ساعات خدمة فحص فيروس كورونا Covid 19 بتقنية PCR للكشف عن الفيروس وفقاً لأعلى المعايير العالمية وبأحدث أجهزة RT-PCR عالية الدقة (GeneXpert الأمريكي وغيره)، وهي طرق معتمدة من قبل هيئة الغذاء والدواء وكذلك من قبل المركز السعودي للوقاية من الأمراض المُعدية",
@ -931,7 +940,7 @@
"immediateConsultation": "استشارة فورية", "immediateConsultation": "استشارة فورية",
"scheduledConsultation": "استشارة مجدولة", "scheduledConsultation": "استشارة مجدولة",
"pharmaLiveCare": "لايف كير الصيدلية", "pharmaLiveCare": "لايف كير الصيدلية",
"notSureHelpMeChooseClinic": "غير متأكد؟ ساعدني في اختيار عيادة!", "notSureHelpMeChooseClinic": "هل تريد مساعدة في اختيار العياة؟",
"mentionYourSymptomsAndFindDoctors": "اذكر أعراضك واعثر على قائمة الأطباء وفقاً لذلك", "mentionYourSymptomsAndFindDoctors": "اذكر أعراضك واعثر على قائمة الأطباء وفقاً لذلك",
"immediateService": "خدمة فورية", "immediateService": "خدمة فورية",
"noNeedToWaitGetMedicalConsultation": "لا حاجة للانتظار، ستحصل على استشارة طبية فورية عبر مكالمة فيديو", "noNeedToWaitGetMedicalConsultation": "لا حاجة للانتظار، ستحصل على استشارة طبية فورية عبر مكالمة فيديو",
@ -995,7 +1004,7 @@
"processingCheckIn": "جاري معالجة تسجيل الحضور...", "processingCheckIn": "جاري معالجة تسجيل الحضور...",
"bookingWaitingAppointment": "جاري حجز موعد الانتظار، يرجى الانتظار...", "bookingWaitingAppointment": "جاري حجز موعد الانتظار، يرجى الانتظار...",
"enterValidIDorIqama": "يرجى إدخال رقم هوية وطنية أو رقم ملف صالح", "enterValidIDorIqama": "يرجى إدخال رقم هوية وطنية أو رقم ملف صالح",
"selectAppointment": "حدد الموعد", "selectAppointment": "اختر الموعد",
"rebookSameDoctor": "أعد الحجز مع نفس الطبيب", "rebookSameDoctor": "أعد الحجز مع نفس الطبيب",
"queueing": "قائمة الانتظار", "queueing": "قائمة الانتظار",
"inQueue": "في قائمة الانتظار", "inQueue": "في قائمة الانتظار",
@ -1291,7 +1300,7 @@
"rebook": "إعادة الحجز", "rebook": "إعادة الحجز",
"noOphthalmologyAppointments": "لم يتم العثور على أي مواعيد في قسم طب العيون...", "noOphthalmologyAppointments": "لم يتم العثور على أي مواعيد في قسم طب العيون...",
"noVitalSignsRecordedYet": "لا توجد علامات حيوية مسجلة بعد", "noVitalSignsRecordedYet": "لا توجد علامات حيوية مسجلة بعد",
"appointmentsAndVisits": "المواعيد والزيارات", "appointmentsAndVisits": "المواعيد",
"labAndRadiology": "المختبر والأشعة", "labAndRadiology": "المختبر والأشعة",
"activeMedicationsAndPrescriptions": "الوصفات الطبية", "activeMedicationsAndPrescriptions": "الوصفات الطبية",
"allPrescriptions": "جميع الوصفات", "allPrescriptions": "جميع الوصفات",
@ -1456,6 +1465,8 @@
"setTimerOfReminder": "ضبط مؤقت التذكير", "setTimerOfReminder": "ضبط مؤقت التذكير",
"youHaveAppointmentWithDr": "لديك موعد مع د. ", "youHaveAppointmentWithDr": "لديك موعد مع د. ",
"hours": "ساعات", "hours": "ساعات",
"minutes": "دقائق",
"seconds": "ثواني",
"secs": "ثواني", "secs": "ثواني",
"noAllergiesDataFound": "لم يتم العثور على بيانات الحساسية...", "noAllergiesDataFound": "لم يتم العثور على بيانات الحساسية...",
"heartRateDescription": "معدل ضربات قلبك يشير إلى عدد المرات التي ينبض فيها قلبك في الدقيقة", "heartRateDescription": "معدل ضربات قلبك يشير إلى عدد المرات التي ينبض فيها قلبك في الدقيقة",
@ -1465,6 +1476,7 @@
"distanceDescription": "المسافة المقطوعة على مدار اليوم", "distanceDescription": "المسافة المقطوعة على مدار اليوم",
"overview": "نظرة عامة", "overview": "نظرة عامة",
"details": "التفاصيل", "details": "التفاصيل",
"details2": "تفاصيل",
"healthy": "صحي", "healthy": "صحي",
"warning": "تحذير", "warning": "تحذير",
"vitalSignDetails": "تفاصيل العلامات الحيوية", "vitalSignDetails": "تفاصيل العلامات الحيوية",

@ -69,7 +69,7 @@
"date": "Date", "date": "Date",
"time": "Time", "time": "Time",
"pendingPayment": "Pending for payment", "pendingPayment": "Pending for payment",
"payNow": "Pay Now", "payNow": "Payment",
"viewQR": "View QR Code", "viewQR": "View QR Code",
"instruction": "Instructions", "instruction": "Instructions",
"livecare": "LiveCare", "livecare": "LiveCare",
@ -306,10 +306,12 @@
"vitalSignObese": "Obese", "vitalSignObese": "Obese",
"vitalSignOverweight": "Overweight", "vitalSignOverweight": "Overweight",
"vitalSignUnderweight": "Underweight", "vitalSignUnderweight": "Underweight",
"vitalSignSkinny": "Underweight",
"myMedical": "Active", "myMedical": "Active",
"myMedicalSubtitle": "Medications", "myMedicalSubtitle": "Medications",
"myDoctor": "My Doctors", "myDoctor": "My Doctors",
"myDoctorSubtitle": "List", "myDoctorSubtitle": "List",
"myDoctorSubtitle2": "List",
"eye": "Eye", "eye": "Eye",
"eyeSubtitle": "Measurement", "eyeSubtitle": "Measurement",
"insurance": "Insurance", "insurance": "Insurance",
@ -327,6 +329,7 @@
"monthly": "Monthly", "monthly": "Monthly",
"monthlySubtitle": "Report", "monthlySubtitle": "Report",
"sick": "Sick", "sick": "Sick",
"sick2": "Sick",
"sickSubtitle": "Leaves", "sickSubtitle": "Leaves",
"myBalance": "My Balance", "myBalance": "My Balance",
"myBalanceSubtitle": "Credit", "myBalanceSubtitle": "Credit",
@ -484,8 +487,10 @@
"refferalSubTitle": "Service", "refferalSubTitle": "Service",
"healthCare": "Health Care", "healthCare": "Health Care",
"emergency": "Emergency", "emergency": "Emergency",
"emergency2": "Emergency",
"erservices": "Emergency", "erservices": "Emergency",
"services2": "Services", "services2": "Services",
"services3": "Services",
"cantSeeProfile": "To view your medical profile, please log in or register now", "cantSeeProfile": "To view your medical profile, please log in or register now",
"loginRegisterNow": "Login or Register Now", "loginRegisterNow": "Login or Register Now",
"hmgPharmacy": "HMG Pharmacy", "hmgPharmacy": "HMG Pharmacy",
@ -757,6 +762,7 @@
"erConsultation": "This service allows you to make an online virtual consultation via video call directly with the doctor from anywhere at any time.", "erConsultation": "This service allows you to make an online virtual consultation via video call directly with the doctor from anywhere at any time.",
"myInvoice": "List", "myInvoice": "List",
"invoiceList": "My Invoice", "invoiceList": "My Invoice",
"invoiceList2": "My Invoice",
"allInvoices": "All Invoices", "allInvoices": "All Invoices",
"hospitals": "Hospitals", "hospitals": "Hospitals",
"clinics": "Clinics", "clinics": "Clinics",
@ -1448,6 +1454,8 @@
"setTimerOfReminder": "Set the timer of reminder", "setTimerOfReminder": "Set the timer of reminder",
"youHaveAppointmentWithDr": "You have appointment with Dr. ", "youHaveAppointmentWithDr": "You have appointment with Dr. ",
"hours": "Hours", "hours": "Hours",
"minutes": "Minutes",
"seconds": "Seconds",
"secs": "Secs", "secs": "Secs",
"noAllergiesDataFound": "No allergies data found...", "noAllergiesDataFound": "No allergies data found...",
"heartRateDescription": "Your heart rate indicates how many times your heart beats per minute", "heartRateDescription": "Your heart rate indicates how many times your heart beats per minute",
@ -1457,6 +1465,7 @@
"distanceDescription": "Distance covered throughout the day", "distanceDescription": "Distance covered throughout the day",
"overview": "Overview", "overview": "Overview",
"details": "Details", "details": "Details",
"details2": "Details",
"healthy": "Healthy", "healthy": "Healthy",
"warning": "Warning", "warning": "Warning",
"vitalSignDetails": "Vital Sign Details", "vitalSignDetails": "Vital Sign Details",

@ -4,7 +4,7 @@ import 'package:hmg_patient_app_new/core/enums.dart';
class ApiConsts { class ApiConsts {
static const maxSmallScreen = 660; static const maxSmallScreen = 660;
static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.prod; static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.preProd;
// static String baseUrl = 'https://uat.hmgwebservices.com/'; // HIS API URL UAT // static String baseUrl = 'https://uat.hmgwebservices.com/'; // HIS API URL UAT
@ -205,6 +205,9 @@ class ApiConsts {
static String updateDiabeticResult = 'Services/Patients.svc/REST/Patient_UpdateDiabtecResult'; static String updateDiabeticResult = 'Services/Patients.svc/REST/Patient_UpdateDiabtecResult';
static String deactivateDiabeticStatus = 'Services/Patients.svc/REST/Patient_DeactivateDiabeticStatus'; static String deactivateDiabeticStatus = 'Services/Patients.svc/REST/Patient_DeactivateDiabeticStatus';
static String sendAverageBloodSugarReport = 'Services/Notifications.svc/REST/SendAverageBloodSugarReport'; static String sendAverageBloodSugarReport = 'Services/Notifications.svc/REST/SendAverageBloodSugarReport';
static String averageBloodSugarReportDownload = 'Services/Notifications.svc/REST/SendAverageBloodSugarReportDownload';
static String averageWeightReportDownload = 'Services/Notifications.svc/REST/SendAverageBodyWeightReportDownload';
static String averageBloodPressureReportDownload = 'Services/Notifications.svc/REST/SendAverageBloodPressureReportDownload';
// Blood Pressure // Blood Pressure
static String getBloodPressureResultAverage = 'Services/Patients.svc/REST/Patient_GetBloodPressureResultAverage'; static String getBloodPressureResultAverage = 'Services/Patients.svc/REST/Patient_GetBloodPressureResultAverage';

@ -400,7 +400,13 @@ class AppAssets {
static const String fullBodyFrontFemale = '$pngBasePath/full_body_front_female.png'; static const String fullBodyFrontFemale = '$pngBasePath/full_body_front_female.png';
static const String fullBodyBackFemale = '$pngBasePath/full_body_back_female.png'; static const String fullBodyBackFemale = '$pngBasePath/full_body_back_female.png';
static const String bmiFullBody = '$pngBasePath/bmi_image_1.png'; static const String bmiFullBody = '$pngBasePath/bmi_image_1.png';
static const String bmiFullBodyFemale = '$pngBasePath/female_bmi.png';
static const String defaultMEP = '$pngBasePath/default_MEP.png'; static const String defaultMEP = '$pngBasePath/default_MEP.png';
static const String ambulance_section = '$pngBasePath/ambulance_section.png';
static const String rrt_section = '$pngBasePath/rrt_section.png';
} }
class AppAnimations { class AppAnimations {

@ -820,6 +820,28 @@ class Utils {
// return Image.asset(icon, width: width, height: height, fit: fit, ); // return Image.asset(icon, width: width, height: height, fit: fit, );
} }
static Widget buildImgWithAssetsWithBorderRadius({
required String icon,
Color? iconColor,
bool isDisabled = false,
double? width,
double? height,
BoxFit fit = BoxFit.cover,
double? border,
double? borderRadius,
}) {
final iconH = height ?? 24.h;
final iconW = width ?? 24.w;
return Container(
width: iconW, height: iconH,
decoration: BoxDecoration(
border: border != null ? Border.all(color: AppColors.whiteColor, width: border) : null,
borderRadius: borderRadius != null ? BorderRadius.circular(borderRadius ?? 12.r) : null,
image: DecorationImage(image: AssetImage(icon,), fit: fit)
),
);
}
/// Widget to build an SVG from network /// Widget to build an SVG from network
static Widget buildImgWithNetwork({ static Widget buildImgWithNetwork({
required String url, required String url,

@ -183,7 +183,7 @@ class EmergencyServicesRepoImp implements EmergencyServicesRepo {
@override @override
Future<Either<Failure, GenericApiModel<List<HospitalsModel>>>> getProjectList() async { Future<Either<Failure, GenericApiModel<List<HospitalsModel>>>> getProjectList() async {
Map<String, dynamic> request = {'IsOnlineCheckIn': true, 'IsAdvancePayment': false, 'IsForER': true}; Map<String, dynamic> request = {"IsEROnlineCheckIn":true,'IsOnlineCheckIn': false, 'IsAdvancePayment': false, 'IsForER': true};
try { try {
GenericApiModel<List<HospitalsModel>>? apiResponse; GenericApiModel<List<HospitalsModel>>? apiResponse;

@ -274,7 +274,6 @@ class EmergencyServicesViewModel extends ChangeNotifier {
void navigateTOAmbulancePage() { void navigateTOAmbulancePage() {
placeValueInController(); placeValueInController();
getProjects();
flushData(); flushData();
selectedFacility = FacilitySelection.ALL; selectedFacility = FacilitySelection.ALL;
@ -282,6 +281,7 @@ class EmergencyServicesViewModel extends ChangeNotifier {
locationUtils!.getLocation( locationUtils!.getLocation(
isShowConfirmDialog: true, isShowConfirmDialog: true,
onSuccess: (position) { onSuccess: (position) {
getProjects();
updateBottomSheetState(BottomSheetType.FIXED); updateBottomSheetState(BottomSheetType.FIXED);
navServices.push( navServices.push(
CustomPageRoute(page: CallAmbulancePage(), direction: AxisDirection.down), CustomPageRoute(page: CallAmbulancePage(), direction: AxisDirection.down),
@ -310,17 +310,21 @@ class EmergencyServicesViewModel extends ChangeNotifier {
} }
void updateBottomSheetState(BottomSheetType sheetType) { void updateBottomSheetState(BottomSheetType sheetType) {
if (sheetType == BottomSheetType.EXPANDED && selectedHospital == null) { // if (sheetType == BottomSheetType.EXPANDED && selectedHospital == null) {
dialogService.showErrorBottomSheet(message: LocaleKeys.selectHospital.tr()); // dialogService.showErrorBottomSheet(message: LocaleKeys.selectHospital.tr());
return; // return;
} // }
bottomSheetType = sheetType; bottomSheetType = sheetType;
if (sheetType == BottomSheetType.EXPANDED) { // if (sheetType == BottomSheetType.FIXED) {
clearAppointmentData(); // clearAppointmentData();
} // }
notifyListeners(); notifyListeners();
} }
void showError(String message) {
dialogService.showErrorBottomSheet(message: message);
}
void setIsGMSAvailable(bool value) { void setIsGMSAvailable(bool value) {
notifyListeners(); notifyListeners();
} }
@ -732,6 +736,10 @@ class EmergencyServicesViewModel extends ChangeNotifier {
} }
FutureOr<void> submitAmbulanceRequest(GeocodeResult? result, PlaceDetails? place, PlacePrediction? placePrediction) async { FutureOr<void> submitAmbulanceRequest(GeocodeResult? result, PlaceDetails? place, PlacePrediction? placePrediction) async {
if (false == haveAnAppointment && null == selectedHospital) {
dialogService.showErrorBottomSheet(message: LocaleKeys.selectHospital.tr());
return;
}
PatientER_RC request = createRequest(result, place, placePrediction); PatientER_RC request = createRequest(result, place, placePrediction);
navServices.push(CustomPageRoute(page: RequestingServicesPage())); navServices.push(CustomPageRoute(page: RequestingServicesPage()));
@ -802,19 +810,19 @@ class EmergencyServicesViewModel extends ChangeNotifier {
request.patientERTransportationMethod = selectedTransportOption; request.patientERTransportationMethod = selectedTransportOption;
transportationDetails.pickupUrgency = 1; transportationDetails.pickupUrgency = 1;
switch (callingPlace) { switch (callingPlace) {
case AmbulanceCallingPlace.FROM_HOSPITAL: case AmbulanceCallingPlace.TO_HOSPITAL:
transportationDetails.dropoffLatitude = selectedHospital!.latitude; transportationDetails.dropoffLatitude = selectedHospital?.latitude;
transportationDetails.dropoffLongitude = selectedHospital!.longitude; transportationDetails.dropoffLongitude = selectedHospital?.longitude;
transportationDetails.dropoffLocationName = selectedHospital!.name; transportationDetails.dropoffLocationName = selectedHospital?.name;
transportationDetails.pickupLatitude = ((result?.geometry.location.lat) ?? place?.lat)?.toStringAsFixed(6); transportationDetails.pickupLatitude = ((result?.geometry.location.lat) ?? place?.lat)?.toStringAsFixed(6);
transportationDetails.pickupLongitude = ((result?.geometry.location.lng) ?? place?.lng)?.toStringAsFixed(6); transportationDetails.pickupLongitude = ((result?.geometry.location.lng) ?? place?.lng)?.toStringAsFixed(6);
transportationDetails.pickupLocationName = result?.formattedAddress ?? placePrediction?.description; transportationDetails.pickupLocationName = result?.formattedAddress ?? placePrediction?.description;
transportationDetails.direction = 1; transportationDetails.direction = 1;
break; break;
case AmbulanceCallingPlace.TO_HOSPITAL: case AmbulanceCallingPlace.FROM_HOSPITAL:
transportationDetails.pickupLatitude = selectedHospital!.latitude; transportationDetails.pickupLatitude = selectedHospital?.latitude;
transportationDetails.pickupLongitude = selectedHospital!.longitude; transportationDetails.pickupLongitude = selectedHospital?.longitude;
transportationDetails.pickupLocationName = selectedHospital!.name; transportationDetails.pickupLocationName = selectedHospital?.name;
transportationDetails.dropoffLatitude = ((result?.geometry.location.lat) ?? place?.lat)?.toStringAsFixed(6); transportationDetails.dropoffLatitude = ((result?.geometry.location.lat) ?? place?.lat)?.toStringAsFixed(6);
transportationDetails.dropoffLongitude = ((result?.geometry.location.lng) ?? place?.lng)?.toStringAsFixed(6); transportationDetails.dropoffLongitude = ((result?.geometry.location.lng) ?? place?.lng)?.toStringAsFixed(6);
transportationDetails.dropoffLocationName = result?.formattedAddress ?? placePrediction?.description; transportationDetails.dropoffLocationName = result?.formattedAddress ?? placePrediction?.description;

@ -15,6 +15,9 @@ abstract class HealthTrackersRepo {
/// Get blood sugar results (week, month, year). /// Get blood sugar results (week, month, year).
Future<Either<Failure, GenericApiModel<dynamic>>> getDiabeticResults(); Future<Either<Failure, GenericApiModel<dynamic>>> getDiabeticResults();
Future<Either<Failure, GenericApiModel<String>>> downloadBloodSugarReport();
Future<Either<Failure, GenericApiModel<String>>> downloadWeightReport();
Future<Either<Failure, GenericApiModel<String>>> downloadBloodPressureReport();
/// Add new blood sugar result. /// Add new blood sugar result.
Future<Either<Failure, GenericApiModel<dynamic>>> addDiabeticResult({ Future<Either<Failure, GenericApiModel<dynamic>>> addDiabeticResult({
@ -211,6 +214,114 @@ class HealthTrackersRepoImp implements HealthTrackersRepo {
} }
} }
@override
Future<Either<Failure, GenericApiModel<String>>> downloadBloodSugarReport() async {
try {
GenericApiModel<String>? apiResponse;
Failure? failure;
await apiClient.post(
ApiConsts.averageBloodSugarReportDownload,
body: {},
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
},
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
dynamic pdf = response['ReportPDFContent'];
apiResponse = GenericApiModel<String>(
messageStatus: messageStatus,
statusCode: statusCode,
errorMessage: errorMessage,
data: pdf,
);
} catch (e) {
failure = DataParsingFailure(e.toString());
}
},
);
if (failure != null) return Left(failure!);
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
return Right(apiResponse!);
} catch (e) {
return Left(UnknownFailure(e.toString()));
}
}
@override
Future<Either<Failure, GenericApiModel<String>>> downloadWeightReport() async {
try {
GenericApiModel<String>? apiResponse;
Failure? failure;
await apiClient.post(
ApiConsts.averageWeightReportDownload,
body: {},
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
},
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
dynamic pdf = response['ReportPDFContent'];
apiResponse = GenericApiModel<String>(
messageStatus: messageStatus,
statusCode: statusCode,
errorMessage: errorMessage,
data: pdf,
);
} catch (e) {
failure = DataParsingFailure(e.toString());
}
},
);
if (failure != null) return Left(failure!);
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
return Right(apiResponse!);
} catch (e) {
return Left(UnknownFailure(e.toString()));
}
}
@override
Future<Either<Failure, GenericApiModel<String>>> downloadBloodPressureReport() async {
try {
GenericApiModel<String>? apiResponse;
Failure? failure;
await apiClient.post(
ApiConsts.averageBloodPressureReportDownload,
body: {},
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
},
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
dynamic pdf = response['ReportPDFContent'];
apiResponse = GenericApiModel<String>(
messageStatus: messageStatus,
statusCode: statusCode,
errorMessage: errorMessage,
data: pdf,
);
} catch (e) {
failure = DataParsingFailure(e.toString());
}
},
);
if (failure != null) return Left(failure!);
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
return Right(apiResponse!);
} catch (e) {
return Left(UnknownFailure(e.toString()));
}
}
@override @override
Future<Either<Failure, GenericApiModel<dynamic>>> addDiabeticResult({ Future<Either<Failure, GenericApiModel<dynamic>>> addDiabeticResult({
required String bloodSugarDateChart, required String bloodSugarDateChart,

@ -1,6 +1,8 @@
import 'dart:developer'; import 'dart:developer';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:hmg_patient_app_new/core/enums.dart';
import 'package:hmg_patient_app_new/features/health_trackers/health_trackers_repo.dart'; import 'package:hmg_patient_app_new/features/health_trackers/health_trackers_repo.dart';
import 'package:hmg_patient_app_new/features/health_trackers/models/blood_pressure/blood_pressure_result.dart'; import 'package:hmg_patient_app_new/features/health_trackers/models/blood_pressure/blood_pressure_result.dart';
import 'package:hmg_patient_app_new/features/health_trackers/models/blood_pressure/month_blood_pressure_result_average.dart'; import 'package:hmg_patient_app_new/features/health_trackers/models/blood_pressure/month_blood_pressure_result_average.dart';
@ -14,7 +16,9 @@ import 'package:hmg_patient_app_new/features/health_trackers/models/weight/month
import 'package:hmg_patient_app_new/features/health_trackers/models/weight/week_weight_measurement_result_average.dart'; import 'package:hmg_patient_app_new/features/health_trackers/models/weight/week_weight_measurement_result_average.dart';
import 'package:hmg_patient_app_new/features/health_trackers/models/weight/weight_measurement_result.dart'; import 'package:hmg_patient_app_new/features/health_trackers/models/weight/weight_measurement_result.dart';
import 'package:hmg_patient_app_new/features/health_trackers/models/weight/year_weight_measurement_result_average.dart'; import 'package:hmg_patient_app_new/features/health_trackers/models/weight/year_weight_measurement_result_average.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/services/error_handler_service.dart'; import 'package:hmg_patient_app_new/services/error_handler_service.dart';
import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
class HealthTrackersViewModel extends ChangeNotifier { class HealthTrackersViewModel extends ChangeNotifier {
HealthTrackersRepo healthTrackersRepo; HealthTrackersRepo healthTrackersRepo;
@ -425,6 +429,91 @@ class HealthTrackersViewModel extends ChangeNotifier {
} }
} }
Future<bool> downloadBloodSugerReport({
Function(String)? onSuccess,
}) async {
LoaderBottomSheet.showLoader(loadingText: LocaleKeys.generatingReport.tr());
try {
final result = await healthTrackersRepo.downloadBloodSugarReport();
LoaderBottomSheet.hideLoader();
bool success = false;
result.fold(
(failure) {
errorHandlerService.handleError(failure: failure);
},
(apiModel) {
success = true;
if (onSuccess != null) onSuccess(apiModel.data??"");
},
);
notifyListeners();
return success;
} catch (e) {
log('Error in sendWeightReportByEmail: $e');
return false;
}
}
Future<bool> downloadBloodPressureReport({
Function(String)? onSuccess,
}) async {
LoaderBottomSheet.showLoader(loadingText: LocaleKeys.generatingReport.tr());
try {
final result = await healthTrackersRepo.downloadBloodPressureReport();
LoaderBottomSheet.hideLoader();
bool success = false;
result.fold(
(failure) {
errorHandlerService.handleError(failure: failure);
},
(apiModel) {
success = true;
if (onSuccess != null) onSuccess(apiModel.data??"");
},
);
notifyListeners();
return success;
} catch (e) {
log('Error in sendWeightReportByEmail: $e');
return false;
}
}
Future<bool> downloadWeightReport({
Function(String)? onSuccess,
}) async {
LoaderBottomSheet.showLoader(loadingText: LocaleKeys.generatingReport.tr());
try {
final result = await healthTrackersRepo.downloadWeightReport();
LoaderBottomSheet.hideLoader();
bool success = false;
result.fold(
(failure) {
errorHandlerService.handleError(failure: failure);
},
(apiModel) {
success = true;
if (onSuccess != null) onSuccess(apiModel.data??"");
},
);
notifyListeners();
return success;
} catch (e) {
log('Error in sendWeightReportByEmail: $e');
return false;
}
}
// ==================== BLOOD PRESSURE TRACKING METHODS ==================== // ==================== BLOOD PRESSURE TRACKING METHODS ====================
/// Fetch blood pressure averages and results /// Fetch blood pressure averages and results
@ -1118,4 +1207,30 @@ class HealthTrackersViewModel extends ChangeNotifier {
diastolicController.dispose(); diastolicController.dispose();
super.dispose(); super.dispose();
} }
Future<void> downloadReport(HealthTrackerTypeEnum trackerType, {required Function(dynamic report) onSuccess}) async {
switch (trackerType) {
case HealthTrackerTypeEnum.bloodSugar:
await downloadBloodSugerReport(
onSuccess : (value){
onSuccess(value);
}
);
break;
case HealthTrackerTypeEnum.bloodPressure:
await downloadBloodPressureReport(
onSuccess : (value){
onSuccess(value);
}
);
break;
case HealthTrackerTypeEnum.weightTracker:
await downloadWeightReport(
onSuccess : (value){
onSuccess(value);
}
);
break;
}
}
} }

@ -11,6 +11,7 @@ enum VitalSignStatus {
obese, obese,
overweight, overweight,
underweight, underweight,
skinny,
} }
/// UI-only helper model for Vital Sign cards. /// UI-only helper model for Vital Sign cards.
@ -34,8 +35,9 @@ class VitalSignUiModel {
/// ///
/// Rules: /// Rules:
/// - Height is always blue. /// - Height is always blue.
/// - High, Obese, Overweight => red scheme. /// - High, Obese => red scheme.
/// - Low, Underweight => yellow scheme. /// - Overweight => orange scheme.
/// - Low, Underweight, Skinny => yellow scheme.
/// - Otherwise => green scheme (Normal). /// - Otherwise => green scheme (Normal).
static VitalSignUiModel scheme({required VitalSignStatus? status, required String label}) { static VitalSignUiModel scheme({required VitalSignStatus? status, required String label}) {
final l = label.toLowerCase(); final l = label.toLowerCase();
@ -50,10 +52,8 @@ class VitalSignUiModel {
); );
} }
// High, Obese, Overweight => red scheme (health concerns) // High, Obese => red scheme (health concerns)
if (status == VitalSignStatus.high || if (status == VitalSignStatus.high || status == VitalSignStatus.obese) {
status == VitalSignStatus.obese ||
status == VitalSignStatus.overweight) {
return VitalSignUiModel( return VitalSignUiModel(
iconBg: AppColors.chipSecondaryLightRedColor, iconBg: AppColors.chipSecondaryLightRedColor,
iconFg: AppColors.primaryRedColor, iconFg: AppColors.primaryRedColor,
@ -62,8 +62,20 @@ class VitalSignUiModel {
); );
} }
// Low, Underweight => yellow scheme (warning) // Overweight => orange scheme (warning)
if (status == VitalSignStatus.low || status == VitalSignStatus.underweight) { if (status == VitalSignStatus.overweight) {
return VitalSignUiModel(
iconBg: AppColors.warningColorYellow.withValues(alpha: 0.12),
iconFg: AppColors.warningColorYellow,
chipBg: AppColors.warningColorYellow.withValues(alpha: 0.12),
chipFg: AppColors.warningColorYellow,
);
}
// Low, Underweight, Skinny => yellow scheme (warning)
if (status == VitalSignStatus.low ||
status == VitalSignStatus.underweight ||
status == VitalSignStatus.skinny) {
final Color yellowBg = AppColors.highAndLow.withValues(alpha: 0.12); final Color yellowBg = AppColors.highAndLow.withValues(alpha: 0.12);
return VitalSignUiModel( return VitalSignUiModel(
iconBg: yellowBg, iconBg: yellowBg,
@ -98,6 +110,8 @@ class VitalSignUiModel {
return LocaleKeys.vitalSignOverweight.tr(); return LocaleKeys.vitalSignOverweight.tr();
case VitalSignStatus.underweight: case VitalSignStatus.underweight:
return LocaleKeys.vitalSignUnderweight.tr(); return LocaleKeys.vitalSignUnderweight.tr();
case VitalSignStatus.skinny:
return LocaleKeys.vitalSignSkinny.tr();
} }
} }
@ -131,22 +145,30 @@ class VitalSignUiModel {
return null; return null;
} }
// BMI >= 25 (Overweight or Obese) => High // BMI >= 30 (Obese) => Red
if (bmiResult >= 25) { if (bmiResult >= 30) {
return VitalSignStatus.high; return VitalSignStatus.obese;
}
// BMI >= 25 (Overweight) => Orange
else if (bmiResult >= 25) {
return VitalSignStatus.overweight;
} }
// BMI >= 18.5 and < 25 => Normal // BMI >= 18.5 (Normal) => Green
else if (bmiResult >= 18.5) { else if (bmiResult >= 18.5) {
return VitalSignStatus.normal; return VitalSignStatus.normal;
} }
// BMI < 18.5 (Underweight) => Low // BMI >= 16 (Underweight) => Yellow
else if (bmiResult >= 16) {
return VitalSignStatus.underweight;
}
// BMI < 16 (Skinny/Severely underweight) => Yellow
else { else {
return VitalSignStatus.low; return VitalSignStatus.skinny;
} }
} }
/// Weight status based on BMI with detailed classification /// Weight status based on BMI with detailed classification
/// Returns: Obese, Overweight, Normal, Underweight /// Returns: Obese, Overweight, Normal, Underweight, Skinny
static VitalSignStatus? weightStatus(dynamic bmi) { static VitalSignStatus? weightStatus(dynamic bmi) {
// Return null if BMI is not available or is 0 // Return null if BMI is not available or is 0
final double bmiResult = double.tryParse(bmi.toString()) ?? 0; final double bmiResult = double.tryParse(bmi.toString()) ?? 0;
@ -155,15 +177,26 @@ class VitalSignUiModel {
return null; return null;
} }
// BMI >= 30 (Obese) => Red
if (bmiResult >= 30) { if (bmiResult >= 30) {
return VitalSignStatus.obese; return VitalSignStatus.obese;
} else if (bmiResult >= 25) { }
// BMI >= 25 (Overweight) => Orange
else if (bmiResult >= 25) {
return VitalSignStatus.overweight; return VitalSignStatus.overweight;
} else if (bmiResult >= 18.5) { }
// BMI >= 18.5 (Normal) => Green
else if (bmiResult >= 18.5) {
return VitalSignStatus.normal; return VitalSignStatus.normal;
} else { }
// BMI >= 16 (Underweight) => Yellow
else if (bmiResult >= 16) {
return VitalSignStatus.underweight; return VitalSignStatus.underweight;
} }
// BMI < 16 (Skinny/Severely underweight) => Yellow
else {
return VitalSignStatus.skinny;
}
} }
} }

@ -39,6 +39,7 @@ class ImmediateLiveCareViewModel extends ChangeNotifier {
MyAppointmentsViewModel myAppointmentsViewModel; MyAppointmentsViewModel myAppointmentsViewModel;
List<GetLiveCareClinicListResponseModel> immediateLiveCareClinicsList = []; List<GetLiveCareClinicListResponseModel> immediateLiveCareClinicsList = [];
List<GetLiveCareClinicListResponseModel> mainLiveCareClinicList = [];
bool isImmediateLiveCareClinicsLoading = false; bool isImmediateLiveCareClinicsLoading = false;
int liveCareSelectedCallType = 0; // 1- Video, 2- Audio, 3- Phone int liveCareSelectedCallType = 0; // 1- Video, 2- Audio, 3- Phone
late GetLiveCareClinicListResponseModel immediateLiveCareSelectedClinic; late GetLiveCareClinicListResponseModel immediateLiveCareSelectedClinic;
@ -61,6 +62,7 @@ class ImmediateLiveCareViewModel extends ChangeNotifier {
initImmediateLiveCare() { initImmediateLiveCare() {
_appState = getIt<AppState>(); _appState = getIt<AppState>();
immediateLiveCareClinicsList = []; immediateLiveCareClinicsList = [];
mainLiveCareClinicList = [];
isImmediateLiveCareClinicsLoading = true; isImmediateLiveCareClinicsLoading = true;
liveCareSelectedCallType = 0; // 1- Video, 2- Audio, 3- Phone liveCareSelectedCallType = 0; // 1- Video, 2- Audio, 3- Phone
immediateLiveCareSelectedClinic = GetLiveCareClinicListResponseModel(); immediateLiveCareSelectedClinic = GetLiveCareClinicListResponseModel();
@ -90,9 +92,11 @@ class ImmediateLiveCareViewModel extends ChangeNotifier {
if (apiResponse.messageStatus == 2) { if (apiResponse.messageStatus == 2) {
// dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {}); // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
} else if (apiResponse.messageStatus == 1) { } else if (apiResponse.messageStatus == 1) {
immediateLiveCareClinicsList = apiResponse.data!; mainLiveCareClinicList = apiResponse.data!;
immediateLiveCareClinicsList.sort((a, b) => b.isOnline!.compareTo(a.isOnline!)); mainLiveCareClinicList.sort((a, b) => b.isOnline!.compareTo(a.isOnline!));
immediateLiveCareClinicsList.clear();
immediateLiveCareClinicsList.addAll(mainLiveCareClinicList);
isImmediateLiveCareClinicsLoading = false; isImmediateLiveCareClinicsLoading = false;
notifyListeners(); notifyListeners();
@ -103,6 +107,18 @@ class ImmediateLiveCareViewModel extends ChangeNotifier {
}, },
); );
} }
void filterClinic(String query){
if(query.isEmpty){
immediateLiveCareClinicsList.clear();
immediateLiveCareClinicsList.addAll(mainLiveCareClinicList);
}else{
// bool isArabic = getIt.get<AppState>().isArabic();
immediateLiveCareClinicsList = mainLiveCareClinicList.where((clinic) => clinic.serviceName!.toLowerCase().contains(query.toLowerCase()) || clinic.serviceNameN!.toLowerCase().contains(query.toLowerCase()
)).toList();
}
notifyListeners();
}
Future<void> getLiveCareImmediateAppointmentFees({Function(dynamic)? onSuccess, Function(String)? onError}) async { Future<void> getLiveCareImmediateAppointmentFees({Function(dynamic)? onSuccess, Function(String)? onError}) async {
final result = final result =

@ -191,6 +191,7 @@ class InsuranceViewModel extends ChangeNotifier {
notifyListeners(); notifyListeners();
}, },
(apiResponse) { (apiResponse) {
patientInsuranceApprovalsList =[];
if (apiResponse.messageStatus == 2) { if (apiResponse.messageStatus == 2) {
// dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {}); // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
} else if (apiResponse.messageStatus == 1) { } else if (apiResponse.messageStatus == 1) {

@ -75,6 +75,7 @@ class PatientAppointmentHistoryResponseModel {
num? patientShareWithTax; num? patientShareWithTax;
num? patientTaxAmount; num? patientTaxAmount;
String? doctorNationalityFlagURL; String? doctorNationalityFlagURL;
bool? isClinicReBookingAllowed;
PatientAppointmentHistoryResponseModel({ PatientAppointmentHistoryResponseModel({
this.setupID, this.setupID,
@ -152,6 +153,7 @@ class PatientAppointmentHistoryResponseModel {
this.patientShareWithTax, this.patientShareWithTax,
this.patientTaxAmount, this.patientTaxAmount,
this.doctorNationalityFlagURL, this.doctorNationalityFlagURL,
this.isClinicReBookingAllowed,
}); });
PatientAppointmentHistoryResponseModel.fromJson(Map<String, dynamic> json) { PatientAppointmentHistoryResponseModel.fromJson(Map<String, dynamic> json) {
@ -241,6 +243,7 @@ class PatientAppointmentHistoryResponseModel {
patientShareWithTax = json['PatientShareWithTax']; patientShareWithTax = json['PatientShareWithTax'];
patientTaxAmount = json['PatientTaxAmount']; patientTaxAmount = json['PatientTaxAmount'];
doctorNationalityFlagURL = json['DoctorNationalityFlagURL']; doctorNationalityFlagURL = json['DoctorNationalityFlagURL'];
isClinicReBookingAllowed = json['IsClinicReBookingAllowed'];
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
@ -313,6 +316,7 @@ class PatientAppointmentHistoryResponseModel {
data['RemaniningHoursTocanPay'] = this.remaniningHoursTocanPay; data['RemaniningHoursTocanPay'] = this.remaniningHoursTocanPay;
data['SMSButtonVisable'] = this.sMSButtonVisable; data['SMSButtonVisable'] = this.sMSButtonVisable;
data['ServiceID'] = this.serviceID; data['ServiceID'] = this.serviceID;
data['IsClinicReBookingAllowed'] = this.isClinicReBookingAllowed;
return data; return data;
} }
} }

@ -52,6 +52,8 @@ class MyInvoicesViewModel extends ChangeNotifier {
notifyListeners(); notifyListeners();
}, },
(apiResponse) { (apiResponse) {
_originalInvoicesList =[];
allInvoicesList =[];
if (apiResponse.messageStatus == 2) { if (apiResponse.messageStatus == 2) {
// dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {}); // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
} else if (apiResponse.messageStatus == 1) { } else if (apiResponse.messageStatus == 1) {

@ -322,6 +322,7 @@ class CodegenLoader extends AssetLoader{
"vitalSignObese": "بدين", "vitalSignObese": "بدين",
"vitalSignOverweight": "زيادة الوزن", "vitalSignOverweight": "زيادة الوزن",
"vitalSignUnderweight": "نقص الوزن", "vitalSignUnderweight": "نقص الوزن",
"vitalSignSkinny": "نحيف جداً",
"myMedical": "نشط", "myMedical": "نشط",
"myMedicalSubtitle": "الأدوية", "myMedicalSubtitle": "الأدوية",
"myDoctor": "أطبائي", "myDoctor": "أطبائي",
@ -1465,6 +1466,8 @@ class CodegenLoader extends AssetLoader{
"setTimerOfReminder": "ضبط مؤقت التذكير", "setTimerOfReminder": "ضبط مؤقت التذكير",
"youHaveAppointmentWithDr": "لديك موعد مع د. ", "youHaveAppointmentWithDr": "لديك موعد مع د. ",
"hours": "ساعات", "hours": "ساعات",
"minutes": "دقائق",
"seconds": "ثواني",
"secs": "ثواني", "secs": "ثواني",
"noAllergiesDataFound": "لم يتم العثور على بيانات الحساسية...", "noAllergiesDataFound": "لم يتم العثور على بيانات الحساسية...",
"heartRateDescription": "معدل ضربات قلبك يشير إلى عدد المرات التي ينبض فيها قلبك في الدقيقة", "heartRateDescription": "معدل ضربات قلبك يشير إلى عدد المرات التي ينبض فيها قلبك في الدقيقة",
@ -2034,6 +2037,7 @@ static const Map<String,dynamic> _en_US = {
"vitalSignObese": "Obese", "vitalSignObese": "Obese",
"vitalSignOverweight": "Overweight", "vitalSignOverweight": "Overweight",
"vitalSignUnderweight": "Underweight", "vitalSignUnderweight": "Underweight",
"vitalSignSkinny": "Underweight",
"myMedical": "Active", "myMedical": "Active",
"myMedicalSubtitle": "Medications", "myMedicalSubtitle": "Medications",
"myDoctor": "My Doctors", "myDoctor": "My Doctors",
@ -3174,6 +3178,8 @@ static const Map<String,dynamic> _en_US = {
"setTimerOfReminder": "Set the timer of reminder", "setTimerOfReminder": "Set the timer of reminder",
"youHaveAppointmentWithDr": "You have appointment with Dr. ", "youHaveAppointmentWithDr": "You have appointment with Dr. ",
"hours": "Hours", "hours": "Hours",
"minutes": "Minutes",
"seconds": "Seconds",
"secs": "Secs", "secs": "Secs",
"noAllergiesDataFound": "No allergies data found...", "noAllergiesDataFound": "No allergies data found...",
"heartRateDescription": "Your heart rate indicates how many times your heart beats per minute", "heartRateDescription": "Your heart rate indicates how many times your heart beats per minute",

@ -87,6 +87,8 @@ abstract class LocaleKeys {
static const bookSuccessConfirmMore2412 = 'bookSuccessConfirmMore2412'; static const bookSuccessConfirmMore2412 = 'bookSuccessConfirmMore2412';
static const upcomingPaymentPending = 'upcomingPaymentPending'; static const upcomingPaymentPending = 'upcomingPaymentPending';
static const upcomingPaymentNow = 'upcomingPaymentNow'; static const upcomingPaymentNow = 'upcomingPaymentNow';
static const timeUntilAppointment = 'timeUntilAppointment';
static const appointmentTimePassed = 'appointmentTimePassed';
static const upcomingQR = 'upcomingQR'; static const upcomingQR = 'upcomingQR';
static const upcomingVirtual = 'upcomingVirtual'; static const upcomingVirtual = 'upcomingVirtual';
static const upcomingLivecare = 'upcomingLivecare'; static const upcomingLivecare = 'upcomingLivecare';
@ -308,13 +310,16 @@ abstract class LocaleKeys {
static const vitalSignObese = 'vitalSignObese'; static const vitalSignObese = 'vitalSignObese';
static const vitalSignOverweight = 'vitalSignOverweight'; static const vitalSignOverweight = 'vitalSignOverweight';
static const vitalSignUnderweight = 'vitalSignUnderweight'; static const vitalSignUnderweight = 'vitalSignUnderweight';
static const vitalSignSkinny = 'vitalSignSkinny';
static const myMedical = 'myMedical'; static const myMedical = 'myMedical';
static const myMedicalSubtitle = 'myMedicalSubtitle'; static const myMedicalSubtitle = 'myMedicalSubtitle';
static const myDoctor = 'myDoctor'; static const myDoctor = 'myDoctor';
static const myDoctorSubtitle = 'myDoctorSubtitle'; static const myDoctorSubtitle = 'myDoctorSubtitle';
static const myDoctorSubtitle2 = 'myDoctorSubtitle2';
static const eye = 'eye'; static const eye = 'eye';
static const eyeSubtitle = 'eyeSubtitle'; static const eyeSubtitle = 'eyeSubtitle';
static const insurance = 'insurance'; static const insurance = 'insurance';
static const insurance2 = 'insurance2';
static const insuranceSubtitle = 'insuranceSubtitle'; static const insuranceSubtitle = 'insuranceSubtitle';
static const updateInsurance = 'updateInsurance'; static const updateInsurance = 'updateInsurance';
static const updateInsuranceSubtitle = 'updateInsuranceSubtitle'; static const updateInsuranceSubtitle = 'updateInsuranceSubtitle';
@ -329,6 +334,7 @@ abstract class LocaleKeys {
static const monthly = 'monthly'; static const monthly = 'monthly';
static const monthlySubtitle = 'monthlySubtitle'; static const monthlySubtitle = 'monthlySubtitle';
static const sick = 'sick'; static const sick = 'sick';
static const sick2 = 'sick2';
static const sickSubtitle = 'sickSubtitle'; static const sickSubtitle = 'sickSubtitle';
static const myBalance = 'myBalance'; static const myBalance = 'myBalance';
static const myBalanceSubtitle = 'myBalanceSubtitle'; static const myBalanceSubtitle = 'myBalanceSubtitle';
@ -492,8 +498,10 @@ abstract class LocaleKeys {
static const refferalSubTitle = 'refferalSubTitle'; static const refferalSubTitle = 'refferalSubTitle';
static const healthCare = 'healthCare'; static const healthCare = 'healthCare';
static const emergency = 'emergency'; static const emergency = 'emergency';
static const emergency2 = 'emergency2';
static const erservices = 'erservices'; static const erservices = 'erservices';
static const services2 = 'services2'; static const services2 = 'services2';
static const services3 = 'services3';
static const cantSeeProfile = 'cantSeeProfile'; static const cantSeeProfile = 'cantSeeProfile';
static const loginRegisterNow = 'loginRegisterNow'; static const loginRegisterNow = 'loginRegisterNow';
static const hmgPharmacy = 'hmgPharmacy'; static const hmgPharmacy = 'hmgPharmacy';
@ -764,6 +772,7 @@ abstract class LocaleKeys {
static const erConsultation = 'erConsultation'; static const erConsultation = 'erConsultation';
static const myInvoice = 'myInvoice'; static const myInvoice = 'myInvoice';
static const invoiceList = 'invoiceList'; static const invoiceList = 'invoiceList';
static const invoiceList2 = 'invoiceList2';
static const allInvoices = 'allInvoices'; static const allInvoices = 'allInvoices';
static const hospitals = 'hospitals'; static const hospitals = 'hospitals';
static const clinics = 'clinics'; static const clinics = 'clinics';
@ -1451,6 +1460,8 @@ abstract class LocaleKeys {
static const setTimerOfReminder = 'setTimerOfReminder'; static const setTimerOfReminder = 'setTimerOfReminder';
static const youHaveAppointmentWithDr = 'youHaveAppointmentWithDr'; static const youHaveAppointmentWithDr = 'youHaveAppointmentWithDr';
static const hours = 'hours'; static const hours = 'hours';
static const minutes = 'minutes';
static const seconds = 'seconds';
static const secs = 'secs'; static const secs = 'secs';
static const noAllergiesDataFound = 'noAllergiesDataFound'; static const noAllergiesDataFound = 'noAllergiesDataFound';
static const heartRateDescription = 'heartRateDescription'; static const heartRateDescription = 'heartRateDescription';
@ -1460,6 +1471,7 @@ abstract class LocaleKeys {
static const distanceDescription = 'distanceDescription'; static const distanceDescription = 'distanceDescription';
static const overview = 'overview'; static const overview = 'overview';
static const details = 'details'; static const details = 'details';
static const details2 = 'details2';
static const healthy = 'healthy'; static const healthy = 'healthy';
static const warning = 'warning'; static const warning = 'warning';
static const vitalSignDetails = 'vitalSignDetails'; static const vitalSignDetails = 'vitalSignDetails';

@ -73,6 +73,12 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
bool isAppointmentWithin4Hours = false; bool isAppointmentWithin4Hours = false;
// Countdown timer variables
Timer? _countdownTimer;
Duration? _timeRemaining;
String _countdownText = "";
Function(void Function())? _modalSetState; // Callback for modal state updates
@override @override
void initState() { void initState() {
scheduleMicrotask(() async { scheduleMicrotask(() async {
@ -91,9 +97,114 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
} }
} }
}); });
// Initialize countdown timer for payment
if (widget.patientAppointmentHistoryResponseModel.nextAction == 15 ||
widget.patientAppointmentHistoryResponseModel.nextAction == 20) {
_startCountdownTimer();
}
super.initState(); super.initState();
} }
void _startCountdownTimer() {
final appointmentDate = DateUtil.convertStringToDate(widget.patientAppointmentHistoryResponseModel.appointmentDate);
_updateTimeRemaining();
_countdownTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
if (mounted) {
_updateTimeRemaining();
} else {
timer.cancel();
}
});
}
void _updateTimeRemaining() {
final appointmentDate = DateUtil.convertStringToDate(widget.patientAppointmentHistoryResponseModel.appointmentDate);
final now = DateTime.now();
final difference = appointmentDate.difference(now);
if (difference.isNegative) {
if (mounted) {
setState(() {
_timeRemaining = Duration.zero;
_countdownText = LocaleKeys.appointmentTimePassed.tr(context: context);
});
}
// Also update modal if callback is available
_modalSetState?.call(() {
_timeRemaining = Duration.zero;
_countdownText = LocaleKeys.appointmentTimePassed.tr(context: context);
});
_countdownTimer?.cancel();
} else {
if (mounted) {
setState(() {
_timeRemaining = difference;
_countdownText = _formatDuration(difference);
});
}
// Also update modal if callback is available
_modalSetState?.call(() {
_timeRemaining = difference;
_countdownText = _formatDuration(difference);
});
}
}
String _formatDuration(Duration duration) {
final days = duration.inDays;
final hours = duration.inHours.remainder(24);
final minutes = duration.inMinutes.remainder(60);
final seconds = duration.inSeconds.remainder(60);
// Format: DD : HH : MM : SS
return '${days.toString().padLeft(2, '0')} : ${hours.toString().padLeft(2, '0')} : ${minutes.toString().padLeft(2, '0')} : ${seconds.toString().padLeft(2, '0')}';
}
@override
void dispose() {
_countdownTimer?.cancel();
super.dispose();
}
// Helper method to build each time unit (number + label)
Widget _buildTimeUnit(String value, String label) {
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
alignment: Alignment.center,
child: value.toText32(
isBold: true,
color: AppColors.blackColor,
isEnglishOnly: true,
),
),
SizedBox(height: 4.h),
Container(
alignment: Alignment.center,
child: label.toText12(
color: AppColors.greyTextColor,
),
),
],
);
}
// Helper method to build time separator (:)
Widget _buildTimeSeparator() {
return Padding(
padding: EdgeInsets.only(bottom: 16.h, left: 6.w, right: 6.w),
child: ':'.toText32(
isBold: true,
color: AppColors.blackColor,
),
);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
myAppointmentsViewModel = Provider.of<MyAppointmentsViewModel>(context, listen: false); myAppointmentsViewModel = Provider.of<MyAppointmentsViewModel>(context, listen: false);
@ -914,6 +1025,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
? (!(widget.patientAppointmentHistoryResponseModel.isActiveDoctor ?? true) || ? (!(widget.patientAppointmentHistoryResponseModel.isActiveDoctor ?? true) ||
widget.patientAppointmentHistoryResponseModel.isLiveCareAppointment! || widget.patientAppointmentHistoryResponseModel.isLiveCareAppointment! ||
widget.patientAppointmentHistoryResponseModel.isExecludeDoctor! || widget.patientAppointmentHistoryResponseModel.isExecludeDoctor! ||
widget.patientAppointmentHistoryResponseModel.isClinicReBookingAllowed == false ||
!Utils.isClinicAllowedForRebook(widget.patientAppointmentHistoryResponseModel.clinicID)) !Utils.isClinicAllowedForRebook(widget.patientAppointmentHistoryResponseModel.clinicID))
? SizedBox.shrink() ? SizedBox.shrink()
: CustomButton( : CustomButton(
@ -1104,14 +1216,86 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
}); });
// LoaderBottomSheet.hideLoader(); // LoaderBottomSheet.hideLoader();
case 15: case 15:
getIt.get<DialogService>().showCommonBottomSheetWithoutH( // Ensure timer is running before showing modal
message: LocaleKeys.upcomingPaymentPending.tr(context: context), if (_countdownTimer == null || !_countdownTimer!.isActive) {
label: LocaleKeys.notice.tr(), _startCountdownTimer();
onOkPressed: () {}, }
okLabel: "confirm",
cancelLabel: LocaleKeys.acknowledged.tr(context: context), showCommonBottomSheetWithoutHeight(
isConfirmButton: true, context,
); title: LocaleKeys.notice.tr(),
child: StatefulBuilder(
builder: (context, setModalState) {
// Store the modal setState callback
_modalSetState = setModalState;
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
// Message text
LocaleKeys.upcomingPaymentPending.tr(context: context).toText14(
color: AppColors.textColor,
isCenter: true,
),
SizedBox(height: 24.h),
// Countdown Timer - DD : HH : MM : SS format with labels
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Days
_buildTimeUnit(
_timeRemaining != null ? _timeRemaining!.inDays.toString().padLeft(2, '0') : '00',
LocaleKeys.days.tr(context: context),
),
_buildTimeSeparator(),
// Hours
_buildTimeUnit(
_timeRemaining != null ? _timeRemaining!.inHours.remainder(24).toString().padLeft(2, '0') : '00',
LocaleKeys.hours.tr(context: context),
),
_buildTimeSeparator(),
// Minutes
_buildTimeUnit(
_timeRemaining != null ? _timeRemaining!.inMinutes.remainder(60).toString().padLeft(2, '0') : '00',
LocaleKeys.minutes.tr(context: context),
),
_buildTimeSeparator(),
// Seconds
_buildTimeUnit(
_timeRemaining != null ? _timeRemaining!.inSeconds.remainder(60).toString().padLeft(2, '0') : '00',
LocaleKeys.seconds.tr(context: context),
),
],
),
SizedBox(height: 24.h),
// Green Acknowledge button with checkmark icon
CustomButton(
text: LocaleKeys.acknowledged.tr(context: context),
onPressed: () {
_modalSetState = null; // Clear callback when closing
Navigator.of(context).pop();
},
backgroundColor: AppColors.successColor,
borderColor: AppColors.successColor,
textColor: Colors.white,
fontSize: 16.f,
fontWeight: FontWeight.w600,
borderRadius: 12.r,
height: 50.h,
icon: AppAssets.checkmark_icon,
iconColor: Colors.white,
),
],
);
},
),
callBackFunc: () {
_modalSetState = null; // Clear callback when closing
},
isFullScreen: false,
isCloseButtonVisible: true,
);
case 20: case 20:
myAppointmentsViewModel.setIsPatientAppointmentShareLoading(true); myAppointmentsViewModel.setIsPatientAppointmentShareLoading(true);
Navigator.of(context).push( Navigator.of(context).push(

@ -392,58 +392,62 @@ class AppointmentCard extends StatelessWidget {
} }
} }
return (patientAppointmentHistoryResponseModel.isActiveDoctor ?? true) return (patientAppointmentHistoryResponseModel.isActiveDoctor ?? true)
? Row( ? (AppointmentType.isArrived(patientAppointmentHistoryResponseModel) &&
children: [ patientAppointmentHistoryResponseModel.isClinicReBookingAllowed == false)
Expanded( ? // Show only View Details button without arrow when rebooking not allowed
flex: 6, _getArrivedButton(context)
child: (AppointmentType.isArrived(patientAppointmentHistoryResponseModel) : Row(
? _getArrivedButton(context) children: [
: CustomButton( Expanded(
text: AppointmentType.getNextActionText(patientAppointmentHistoryResponseModel.nextAction), flex: 6,
onPressed: () => _goToDetails(context), child: (AppointmentType.isArrived(patientAppointmentHistoryResponseModel)
backgroundColor: AppointmentType.getNextActionButtonColor(patientAppointmentHistoryResponseModel.nextAction).withValues(alpha: 0.15), ? _getArrivedButton(context)
borderColor: AppointmentType.getNextActionButtonColor(patientAppointmentHistoryResponseModel.nextAction).withValues(alpha: 0.01), : CustomButton(
textColor: AppointmentType.getNextActionTextColor(patientAppointmentHistoryResponseModel.nextAction), text: AppointmentType.getNextActionText(patientAppointmentHistoryResponseModel.nextAction),
fontSize: (isFoldable || isTablet) ? 12.f : 14.f, onPressed: () => _goToDetails(context),
fontWeight: FontWeight.w600, backgroundColor: AppointmentType.getNextActionButtonColor(patientAppointmentHistoryResponseModel.nextAction).withValues(alpha: 0.15),
borderRadius: 12.r, borderColor: AppointmentType.getNextActionButtonColor(patientAppointmentHistoryResponseModel.nextAction).withValues(alpha: 0.01),
padding: EdgeInsets.symmetric(horizontal: 10.w), textColor: AppointmentType.getNextActionTextColor(patientAppointmentHistoryResponseModel.nextAction),
height: 40.h, fontSize: (isFoldable || isTablet) ? 12.f : 14.f,
icon: AppointmentType.getNextActionIcon(patientAppointmentHistoryResponseModel.nextAction), fontWeight: FontWeight.w600,
iconColor: AppointmentType.getNextActionTextColor(patientAppointmentHistoryResponseModel.nextAction), borderRadius: 12.r,
iconSize: 15.h, padding: EdgeInsets.symmetric(horizontal: 10.w),
)) height: 40.h,
.toShimmer2(isShow: isLoading), icon: AppointmentType.getNextActionIcon(patientAppointmentHistoryResponseModel.nextAction),
), iconColor: AppointmentType.getNextActionTextColor(patientAppointmentHistoryResponseModel.nextAction),
SizedBox(width: 8.h), iconSize: 15.h,
Expanded( ))
flex: 1, .toShimmer2(isShow: isLoading),
child: Container( ),
height: (isFoldable || isTablet) ? 50.h : 40.h, SizedBox(width: 8.h),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration( Expanded(
color: AppColors.transparent, flex: 1,
borderRadius: 10.h, child: Container(
side: BorderSide( height: (isFoldable || isTablet) ? 50.h : 40.h,
color: AppColors.textColor, decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
width: 1.2, color: AppColors.transparent,
), borderRadius: 10.h,
), side: BorderSide(
child: Transform.flip( color: AppColors.textColor,
flipX: appState.isArabic(), width: 1.2,
child: Utils.buildSvgWithAssets( ),
icon: AppAssets.forward_arrow_icon, ),
iconColor: AppColors.textColor, child: Transform.flip(
width: 24.w, flipX: appState.isArabic(),
height: 24.h, child: Utils.buildSvgWithAssets(
fit: BoxFit.contain, icon: AppAssets.forward_arrow_icon,
), iconColor: AppColors.textColor,
), width: 24.w,
).toShimmer2(isShow: isLoading).onPress(() { height: 24.h,
_goToDetails(context); fit: BoxFit.contain,
}), ),
), ),
], ).toShimmer2(isShow: isLoading).onPress(() {
) _goToDetails(context);
}),
),
],
)
: CustomButton( : CustomButton(
text: LocaleKeys.viewDetails.tr(context: context), text: LocaleKeys.viewDetails.tr(context: context),
onPressed: () { onPressed: () {
@ -475,54 +479,22 @@ class AppointmentCard extends StatelessWidget {
} }
Widget _getArrivedButton(BuildContext context) { Widget _getArrivedButton(BuildContext context) {
// final isRecent = DateTime.now().difference(DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate)).inDays <= 15; if (patientAppointmentHistoryResponseModel.isClinicReBookingAllowed == false) {
// return CustomButton(
// if (isRecent) { text: LocaleKeys.viewDetails.tr(context: context),
// return CustomButton( onPressed: () => _goToDetails(context),
// text: LocaleKeys.askDoctor.tr(context: context), backgroundColor: AppColors.secondaryLightRedColor,
// onPressed: () async { borderColor: AppColors.secondaryLightRedColor,
// LoaderBottomSheet.showLoader(loadingText: LocaleKeys.checkingDoctorAvailability.tr(context: context)); textColor: AppColors.primaryRedColor,
// await myAppointmentsViewModel.isDoctorAvailable( fontSize: (isFoldable || isTablet) ? 12.f : 14.f,
// projectID: patientAppointmentHistoryResponseModel.projectID, fontWeight: FontWeight.w600,
// doctorId: patientAppointmentHistoryResponseModel.doctorID, borderRadius: 12.r,
// clinicId: patientAppointmentHistoryResponseModel.clinicID, padding: EdgeInsets.symmetric(horizontal: 10.w),
// onSuccess: (value) async { height: 40.h,
// 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,
// );
// }
// Show Rebook button
return CustomButton( return CustomButton(
borderSide: BorderSide( borderSide: BorderSide(
color: AppColors.textColor, color: AppColors.textColor,

@ -3,6 +3,7 @@ import 'dart:async';
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:flutter_staggered_animations/flutter_staggered_animations.dart'; import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/app_state.dart'; import 'package:hmg_patient_app_new/core/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/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
@ -22,6 +23,7 @@ import 'package:hmg_patient_app_new/presentation/book_appointment/livecare/widge
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/appbar/collapsing_list_view.dart'; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
import 'package:hmg_patient_app_new/widgets/input_widget.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:provider/provider.dart'; import 'package:provider/provider.dart';
@ -68,6 +70,34 @@ class _SelectImmediateLiveCareClinicPageState extends State<SelectImmediateLiveC
child: Consumer<ImmediateLiveCareViewModel>(builder: (context, immediateLiveCareVM, child) { child: Consumer<ImmediateLiveCareViewModel>(builder: (context, immediateLiveCareVM, child) {
return Column( return Column(
children: [ children: [
TextInputWidget(
labelText: LocaleKeys.search.tr(context: context),
hintText: LocaleKeys.clinicName.tr(context: context),
controller: searchEditingController,
isEnable: true,
prefix: null,
autoFocus: false,
isBorderAllowed: false,
keyboardType: TextInputType.text,
focusNode: textFocusNode,
suffix: searchEditingController.text.isNotEmpty
? GestureDetector(
onTap: () {
searchEditingController.clear();
immediateLiveCareVM.filterClinic("");
textFocusNode.unfocus();
},
child: Utils.buildSvgWithAssets(icon: AppAssets.close_bottom_sheet_icon, width: 20.h, height: 20.h, fit: BoxFit.scaleDown),
)
: null,
onChange: (value) {
immediateLiveCareVM.filterClinic(value!);
},
padding: EdgeInsets.symmetric(
vertical: ResponsiveExtension(10).h,
horizontal: ResponsiveExtension(15).h,
),
),
ListView.separated( ListView.separated(
padding: EdgeInsets.only(top: 16.h), padding: EdgeInsets.only(top: 16.h),
shrinkWrap: true, shrinkWrap: true,

@ -53,8 +53,8 @@ class CallAmbulancePage extends StatelessWidget {
ExpandableBottomSheet( ExpandableBottomSheet(
bottomSheetType: context.watch<EmergencyServicesViewModel>().bottomSheetType, bottomSheetType: context.watch<EmergencyServicesViewModel>().bottomSheetType,
children: { children: {
BottomSheetType.EXPANDED: ExpanedBottomSheet(context), BottomSheetType.EXPANDED: ExpandedBottomSheet(context),
BottomSheetType.FIXED: FixedBottomSheet(context), BottomSheetType.FIXED: pickUpDetailAndAppointementSection(context),
}, },
), ),
], ],
@ -92,7 +92,7 @@ class CallAmbulancePage extends StatelessWidget {
); );
} }
Widget FixedBottomSheet(BuildContext context) { Widget ExpandedBottomSheet(BuildContext context) {
return GestureDetector( return GestureDetector(
onVerticalDragUpdate: (details) { onVerticalDragUpdate: (details) {
// if(details.delta.dy<0){ // if(details.delta.dy<0){
@ -172,7 +172,11 @@ class CallAmbulancePage extends StatelessWidget {
CustomButton( CustomButton(
text: LocaleKeys.selectDetails.tr(context: context), text: LocaleKeys.selectDetails.tr(context: context),
onPressed: () { onPressed: () {
context.read<EmergencyServicesViewModel>().updateBottomSheetState(BottomSheetType.EXPANDED); LocationViewModel locationViewModel = context.read<LocationViewModel>();
GeocodeResponse? response = locationViewModel.geocodeResponse;
PlaceDetails? placeDetails = locationViewModel.placeDetails;
PlacePrediction? placePrediction = locationViewModel.selectedPrediction;
context.read<EmergencyServicesViewModel>().submitAmbulanceRequest(response?.results.first, placeDetails, placePrediction);
}) })
], ],
).paddingOnly(top: 24.h, bottom: 32.h, left: 24.h, right: 24.h), ).paddingOnly(top: 24.h, bottom: 32.h, left: 24.h, right: 24.h),
@ -185,7 +189,7 @@ class CallAmbulancePage extends StatelessWidget {
); );
} }
Widget ExpanedBottomSheet(BuildContext context) { Widget pickUpDetailAndAppointementSection(BuildContext context) {
return GestureDetector( return GestureDetector(
onVerticalDragUpdate: (details) { onVerticalDragUpdate: (details) {
if (details.delta.dy > 0) { if (details.delta.dy > 0) {
@ -324,28 +328,34 @@ class CallAmbulancePage extends StatelessWidget {
) )
], ],
), ),
if(AmbulanceCallingPlace.TO_HOSPITAL == context.read<EmergencyServicesViewModel>().callingPlace)
Row(
children: [
hospitalAndPickUpItemContent(
title: LocaleKeys.appointment.tr(context: context),
subTitle: LocaleKeys.haveAnyAppointment.tr(context: context),
leadingIcon: AppAssets.appointment_calendar_icon,
),
CustomSwitch(
value: context.watch<EmergencyServicesViewModel>().haveAnAppointment,
onChanged: (value) async {
// if (value) {
// openAppointmentList(context);
// }
await context.read<EmergencyServicesViewModel>().updateAppointment(value);
if (context.read<EmergencyServicesViewModel>().appointments?.isNotEmpty == true) {
openAppointmentList(context);
}
},
)
],
),
Row(
children: [ // Visibility(
hospitalAndPickUpItemContent( // visible: ,
title: LocaleKeys.appointment.tr(context: context), // child:
subTitle: LocaleKeys.haveAnyAppointment.tr(context: context), // ),
leadingIcon: AppAssets.appointment_calendar_icon,
),
CustomSwitch(
value: context.watch<EmergencyServicesViewModel>().haveAnAppointment,
onChanged: (value) async {
// if (value) {
// openAppointmentList(context);
// }
await context.read<EmergencyServicesViewModel>().updateAppointment(value);
if (context.read<EmergencyServicesViewModel>().appointments?.isNotEmpty == true) {
openAppointmentList(context);
}
},
)
],
),
], ],
).paddingAll(16.h), ).paddingAll(16.h),
); );
@ -460,12 +470,8 @@ class CallAmbulancePage extends StatelessWidget {
CustomButton( CustomButton(
text: LocaleKeys.submitRequest.tr(context: context), text: LocaleKeys.submitRequest.tr(context: context),
onPressed: () { onPressed: () {
LocationViewModel locationViewModel = context.read<LocationViewModel>(); context.read<EmergencyServicesViewModel>().updateBottomSheetState(BottomSheetType.EXPANDED);
GeocodeResponse? response = locationViewModel.geocodeResponse; })
PlaceDetails? placeDetails = locationViewModel.placeDetails;
PlacePrediction? placePrediction = locationViewModel.selectedPrediction;
context.read<EmergencyServicesViewModel>().submitAmbulanceRequest(response?.results.first, placeDetails, placePrediction);
})
], ],
).paddingOnly(top: 24.h, bottom: 12.h, left: 24.h, right: 24.h), ).paddingOnly(top: 24.h, bottom: 12.h, left: 24.h, right: 24.h),
), ),
@ -582,21 +588,24 @@ class CallAmbulancePage extends StatelessWidget {
} }
hospitalField(BuildContext context) { hospitalField(BuildContext context) {
return DecoratedBox( return Visibility(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 12.h), visible: false == context.watch<EmergencyServicesViewModel>().haveAnAppointment,
child: Row( child: DecoratedBox(
children: [ decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 12.h),
hospitalAndPickUpItemContent( child: Row(
title: LocaleKeys.selectHospital.tr(context: context), children: [
subTitle: context.read<EmergencyServicesViewModel>().getSelectedHospitalName() ?? LocaleKeys.selectHospital.tr(context: context), hospitalAndPickUpItemContent(
leadingIcon: AppAssets.hospital, title: LocaleKeys.selectHospital.tr(context: context),
), subTitle: context.read<EmergencyServicesViewModel>().getSelectedHospitalName() ?? LocaleKeys.selectHospital.tr(context: context),
Utils.buildSvgWithAssets(icon: AppAssets.down_cheveron, width: 24.h, height: 24.h).paddingAll(16.h) leadingIcon: AppAssets.hospital,
], ),
).onPress(() { Utils.buildSvgWithAssets(icon: AppAssets.down_cheveron, width: 24.h, height: 24.h).paddingAll(16.h)
showHospitalBottomSheet(context); ],
}).paddingSymmetrical( ).onPress(() {
10.w, 12.h), showHospitalBottomSheet(context);
}).paddingSymmetrical(
10.w, 12.h),
),
); );
} }

@ -73,7 +73,10 @@ class TrackingScreen extends StatelessWidget {
child: SingleChildScrollView( child: SingleChildScrollView(
child: Column( child: Column(
children: [ children: [
animationSection(), Padding(
padding: EdgeInsetsDirectional.only(top:16.h,start: 16.w,end: 16.w ),
child: animationSection(context),
),
Column( Column(
spacing: 16.h, spacing: 16.h,
children: [orderStatus(context), orderTrackingId(context), contactSection()], children: [orderStatus(context), orderTrackingId(context), contactSection()],
@ -83,12 +86,12 @@ class TrackingScreen extends StatelessWidget {
); );
} }
animationSection() { animationSection(BuildContext context) {
switch (state) { switch (state) {
case OrderTrackingState.waitingForCall: case OrderTrackingState.waitingForCall:
case OrderTrackingState.dispactched: case OrderTrackingState.dispactched:
case OrderTrackingState.returning: case OrderTrackingState.returning:
return Lottie.asset(AppAnimations.ambulance, repeat: true, reverse: false, width: 260.h, height: 200.h); return showImage(order != null ? AppAssets.ambulance_section : AppAssets.rrt_section, context);
case OrderTrackingState.ended: case OrderTrackingState.ended:
return Lottie.asset(AppAnimations.checkmark, repeat: true, width: 260.h, height: 200.h); return Lottie.asset(AppAnimations.checkmark, repeat: true, width: 260.h, height: 200.h);
case OrderTrackingState.failed: case OrderTrackingState.failed:
@ -489,6 +492,18 @@ class TrackingScreen extends StatelessWidget {
); );
} }
showImage(String imageUrl, BuildContext context) {
return Utils.buildImgWithAssetsWithBorderRadius(
icon: imageUrl,
iconColor: Colors.transparent,
width: MediaQuery.sizeOf(context).width,
height: 380.h,
borderRadius: 24.r,
border: 1.r/// did this as the function that is being called is wrongly coupled with the border radius and border, and in some cases like the ambulance and rrt section we don't need any
/// border or border radius
);
}
// Widget rrtOrderData() { // Widget rrtOrderData() {
// return Row( // return Row(
// spacing: 8.h, // spacing: 8.h,

@ -27,6 +27,7 @@ import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
import 'package:hmg_patient_app_new/widgets/graph/custom_graph.dart'; import 'package:hmg_patient_app_new/widgets/graph/custom_graph.dart';
import 'package:hmg_patient_app_new/widgets/input_widget.dart'; import 'package:hmg_patient_app_new/widgets/input_widget.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:open_filex/open_filex.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:shimmer/shimmer.dart'; import 'package:shimmer/shimmer.dart';
@ -1250,7 +1251,32 @@ class _HealthTrackerDetailPageState extends State<HealthTrackerDetailPage> {
return Scaffold( return Scaffold(
backgroundColor: AppColors.bgScaffoldColor, backgroundColor: AppColors.bgScaffoldColor,
body: CollapsingListView( body: CollapsingListView(
sendEmail: () async => onSendEmailPressed(context), downloadReport: () async {
await context.read<HealthTrackersViewModel>().downloadReport(widget.trackerType,
onSuccess: (report) async {
if (report.isEmpty) {}
String path = await Utils.createFileFromString(report, "pdf");
try {
OpenFilex.open(path);
} catch (ex) {
showCommonBottomSheetWithoutHeight(
context,
child: Utils.getErrorWidget(loadingText: "Cannot open file"),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
}
});
// .downloadBloodSugerReport();
},
title: _getPageTitle(), title: _getPageTitle(),
bottomChild: Consumer<HealthTrackersViewModel>( bottomChild: Consumer<HealthTrackersViewModel>(
builder: (context, viewModel, child) { builder: (context, viewModel, child) {

@ -71,12 +71,12 @@ class LandingPageData {
), ),
]; ];
static List<ServiceCardData> get getLoggedInServiceCardsList => [ List<ServiceCardData> get getLoggedInServiceCardsList => [
ServiceCardData( ServiceCardData(
serviceName: "emergency", serviceName: "emergency",
icon: AppAssets.emergency_services_icon, icon: AppAssets.emergency_services_icon,
title: LocaleKeys.emergency, title: getIt.get<AppState>().isArabic()?LocaleKeys.services3 :LocaleKeys.emergency2,
subtitle: LocaleKeys.services2, subtitle: getIt.get<AppState>().isArabic()?LocaleKeys.emergency2:LocaleKeys.services3,
backgroundColor: AppColors.primaryRedColor, backgroundColor: AppColors.primaryRedColor,
iconColor: Colors.white, iconColor: Colors.white,
textColor: Colors.white, textColor: Colors.white,
@ -85,8 +85,8 @@ class LandingPageData {
ServiceCardData( ServiceCardData(
serviceName: "lab_results", serviceName: "lab_results",
icon: AppAssets.home_lab_result_icon, icon: AppAssets.home_lab_result_icon,
title: LocaleKeys.lab, title: getIt.get<AppState>().isArabic()?LocaleKeys.labSubtitle:LocaleKeys.lab,
subtitle: LocaleKeys.labSubtitle, subtitle: getIt.get<AppState>().isArabic()?LocaleKeys.lab:LocaleKeys.labSubtitle ,
backgroundColor: AppColors.whiteColor, backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor, iconColor: AppColors.blackColor,
textColor: AppColors.blackColor, textColor: AppColors.blackColor,
@ -95,8 +95,8 @@ class LandingPageData {
ServiceCardData( ServiceCardData(
serviceName: "radiology_results", serviceName: "radiology_results",
icon: AppAssets.my_radiology_icon, icon: AppAssets.my_radiology_icon,
title: LocaleKeys.radiology, title: getIt.get<AppState>().isArabic()?LocaleKeys.labSubtitle:LocaleKeys.radiology,
subtitle: LocaleKeys.radiologySubtitle, subtitle: getIt.get<AppState>().isArabic()?LocaleKeys.radiology:LocaleKeys.labSubtitle ,
backgroundColor: AppColors.whiteColor, backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor, iconColor: AppColors.blackColor,
textColor: AppColors.blackColor, textColor: AppColors.blackColor,
@ -105,8 +105,8 @@ class LandingPageData {
ServiceCardData( ServiceCardData(
serviceName: "prescriptions", serviceName: "prescriptions",
icon: AppAssets.my_prescription_icon, icon: AppAssets.my_prescription_icon,
title: LocaleKeys.medicinesSubtitle, title: getIt.get<AppState>().isArabic()?LocaleKeys.details2:LocaleKeys.medicinesSubtitle,
subtitle: LocaleKeys.details, subtitle: getIt.get<AppState>().isArabic()?LocaleKeys.medicinesSubtitle:LocaleKeys.details2,
backgroundColor: AppColors.whiteColor, backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor, iconColor: AppColors.blackColor,
textColor: AppColors.blackColor, textColor: AppColors.blackColor,
@ -115,8 +115,8 @@ class LandingPageData {
ServiceCardData( ServiceCardData(
serviceName: "insurance_update", serviceName: "insurance_update",
icon: AppAssets.insurance_update_icon, icon: AppAssets.insurance_update_icon,
title: LocaleKeys.insurance, title: getIt.get<AppState>().isArabic()?LocaleKeys.details2: LocaleKeys.insurance2,
subtitle: LocaleKeys.details, subtitle: getIt.get<AppState>().isArabic()?LocaleKeys.insurance2: LocaleKeys.details2,
backgroundColor: AppColors.whiteColor, backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor, iconColor: AppColors.blackColor,
textColor: AppColors.blackColor, textColor: AppColors.blackColor,
@ -135,8 +135,8 @@ class LandingPageData {
ServiceCardData( ServiceCardData(
serviceName: "sick_leaves", serviceName: "sick_leaves",
icon: AppAssets.my_sick_leave_icon, icon: AppAssets.my_sick_leave_icon,
title: LocaleKeys.sick, title: getIt.get<AppState>().isArabic()?LocaleKeys.sickSubtitle:LocaleKeys.sick2,
subtitle: LocaleKeys.sickSubtitle, subtitle: getIt.get<AppState>().isArabic()?LocaleKeys.sick2:LocaleKeys.sickSubtitle,
backgroundColor: AppColors.whiteColor, backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor, iconColor: AppColors.blackColor,
textColor: AppColors.blackColor, textColor: AppColors.blackColor,
@ -145,8 +145,8 @@ class LandingPageData {
ServiceCardData( ServiceCardData(
serviceName: "my_invoice", serviceName: "my_invoice",
icon: AppAssets.invoiceListIcon, icon: AppAssets.invoiceListIcon,
title: LocaleKeys.invoiceList, title: getIt.get<AppState>().isArabic()?LocaleKeys.myDoctorSubtitle2:LocaleKeys.invoiceList2,
subtitle: LocaleKeys.myDoctorSubtitle, subtitle: getIt.get<AppState>().isArabic()?LocaleKeys.invoiceList2:LocaleKeys.myDoctorSubtitle2,
backgroundColor: AppColors.whiteColor, backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor, iconColor: AppColors.blackColor,
textColor: AppColors.blackColor, textColor: AppColors.blackColor,

@ -696,7 +696,7 @@ class _LandingPageState extends State<LandingPage> {
.width / 2.5 - 10), .width / 2.5 - 10),
child: ListView.separated( child: ListView.separated(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
itemCount: LandingPageData.getLoggedInServiceCardsList.length, itemCount: LandingPageData().getLoggedInServiceCardsList.length,
shrinkWrap: true, shrinkWrap: true,
controller: _horizontalScrollController, controller: _horizontalScrollController,
padding: EdgeInsets.only(left: 0.h, right: 0.h, top: 16.h, bottom: 12.h), padding: EdgeInsets.only(left: 0.h, right: 0.h, top: 16.h, bottom: 12.h),
@ -708,14 +708,14 @@ class _LandingPageState extends State<LandingPage> {
horizontalOffset: 100.0, horizontalOffset: 100.0,
child: FadeInAnimation( child: FadeInAnimation(
child: SmallServiceCard( child: SmallServiceCard(
icon: LandingPageData.getLoggedInServiceCardsList[index].icon, icon: LandingPageData().getLoggedInServiceCardsList[index].icon,
title: LandingPageData.getLoggedInServiceCardsList[index].title, title: LandingPageData().getLoggedInServiceCardsList[index].title,
subtitle: LandingPageData.getLoggedInServiceCardsList[index].subtitle, subtitle: LandingPageData().getLoggedInServiceCardsList[index].subtitle,
iconColor: LandingPageData.getLoggedInServiceCardsList[index].iconColor!, iconColor: LandingPageData().getLoggedInServiceCardsList[index].iconColor!,
textColor: LandingPageData.getLoggedInServiceCardsList[index].textColor, textColor: LandingPageData().getLoggedInServiceCardsList[index].textColor,
backgroundColor: LandingPageData.getLoggedInServiceCardsList[index].backgroundColor, backgroundColor: LandingPageData().getLoggedInServiceCardsList[index].backgroundColor,
isBold: LandingPageData.getLoggedInServiceCardsList[index].isBold, isBold: LandingPageData().getLoggedInServiceCardsList[index].isBold,
serviceName: LandingPageData.getLoggedInServiceCardsList[index].serviceName, serviceName: LandingPageData().getLoggedInServiceCardsList[index].serviceName,
), ),
), ),
), ),

@ -91,35 +91,41 @@ class LabOrderResultItem extends StatelessWidget {
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Visibility( Flexible(
visible: tests?.checkIfGraphShouldBeDisplayed() == true, flex: 2,
child: Column( child: Visibility(
spacing: 6.h, visible: tests?.checkIfGraphShouldBeDisplayed() == true,
crossAxisAlignment: CrossAxisAlignment.start, child: Column(
children: [ spacing: 6.h,
severityText.tr().toText10(isBold: true, color: AppColors.greyTextColor), crossAxisAlignment: CrossAxisAlignment.start,
Utils.buildSvgWithAssets(icon: AppAssets.lab_result_indicator, width: 21, height: 23, iconColor: iconColor), children: [
], severityText.tr().toText10(isBold: true, color: AppColors.greyTextColor),
Utils.buildSvgWithAssets(icon: AppAssets.lab_result_indicator, width: 21, height: 23, iconColor: iconColor),
],
),
), ),
), ),
Visibility( Flexible(
visible: tests?.checkIfGraphShouldBeDisplayed() == true, flex:2,
child: CustomButton( child: Visibility(
icon: AppAssets.view_report_icon, visible: tests?.checkIfGraphShouldBeDisplayed() == true,
iconColor: AppColors.infoColor, child: CustomButton(
iconSize: 16.h, icon: AppAssets.view_report_icon,
text: LocaleKeys.viewReport.tr(context: context), iconColor: AppColors.infoColor,
onPressed: () { iconSize: 16.h,
onTap(); text: LocaleKeys.viewReport.tr(context: context),
}, onPressed: () {
backgroundColor: AppColors.infoColor.withAlpha(20), onTap();
borderColor: AppColors.infoColor.withAlpha(0), },
textColor: AppColors.infoColor, backgroundColor: AppColors.infoColor.withAlpha(20),
fontSize: 14, borderColor: AppColors.infoColor.withAlpha(0),
fontWeight: FontWeight.w600, textColor: AppColors.infoColor,
borderRadius: 12, fontSize: 14,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0), fontWeight: FontWeight.w600,
height: 40.h, borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 40.h,
),
), ),
), ),
], ],

@ -80,7 +80,7 @@ class _TriagePageState extends State<TriagePage> {
} }
// Case 2: Should stop flag is true OR Case 3: Probability >= 70% OR Case 4: 7 or more questions answered // Case 2: Should stop flag is true OR Case 3: Probability >= 70% OR Case 4: 7 or more questions answered
if (viewModel.shouldStopTriage || highestProbability >= 70.0 || viewModel.triageQuestionCount >= 7) { if (viewModel.shouldStopTriage || highestProbability >= 70.0 || viewModel.triageQuestionCount >= 15) {
// Navigate to results/possible conditions screen // Navigate to results/possible conditions screen
context.navigateWithName(AppRoutes.possibleConditionsPage); context.navigateWithName(AppRoutes.possibleConditionsPage);
return; return;

@ -236,7 +236,9 @@ class _VitalSignPageState extends State<VitalSignPage> {
fit: StackFit.expand, fit: StackFit.expand,
children: [ children: [
Image.asset( Image.asset(
AppAssets.bmiFullBody, getIt.get<AppState>().getAuthenticatedUser()?.gender == 1
? AppAssets.bmiFullBody
: AppAssets.bmiFullBodyFemale,
fit: BoxFit.cover, fit: BoxFit.cover,
alignment: Alignment.topCenter, alignment: Alignment.topCenter,
), ),

@ -27,7 +27,7 @@ class BottomNavigation extends StatelessWidget {
BottomNavItem( BottomNavItem(
icon: AppAssets.bookAppoBottom, icon: AppAssets.bookAppoBottom,
fillIcon: AppAssets.bookAppoBottom, fillIcon: AppAssets.bookAppoBottom,
label: LocaleKeys.appointment.tr(context: context), label: LocaleKeys.appointments.tr(context: context),
iconSize: 32, isSpecial: true), iconSize: 32, isSpecial: true),
appState.isAuthenticated appState.isAuthenticated
// ? BottomNavItem(icon: AppAssets.toDoBottom, label: LocaleKeys.todoList.tr(context: context)) // ? BottomNavItem(icon: AppAssets.toDoBottom, label: LocaleKeys.todoList.tr(context: context))
@ -80,7 +80,7 @@ class BottomNavigation extends StatelessWidget {
), ),
// const SizedBox(height: 10), // const SizedBox(height: 10),
SizedBox(height: item.isSpecial ? 0 : 8.h), SizedBox(height: item.isSpecial ? 0 : 8.h),
item.label.toText11(isBold: true), item.label.toText10(isBold: true),
// SizedBox(height: item.isSpecial ? 5 : 0) // SizedBox(height: item.isSpecial ? 5 : 0)
], ],
), ),

@ -86,7 +86,8 @@ class CustomButton extends StatelessWidget {
), ),
if (text.isNotEmpty && icon != null) if (text.isNotEmpty && icon != null)
Flexible( Flexible(
child: Text( child:
Text(
text, text,
overflow: textOverflow ?? TextOverflow.ellipsis, overflow: textOverflow ?? TextOverflow.ellipsis,
maxLines: 1, maxLines: 1,

@ -26,12 +26,7 @@ class OrderTrackingWidget extends StatelessWidget {
Widget? getBarAndDot(OrderTrackingState? state, BuildContext context, Widget? getBarAndDot(OrderTrackingState? state, BuildContext context,
double width) { double width) {
print("the parent padding value is $parentPaddingValue");
print("the parent padding value is ${(parentPaddingValue+24)}");
print("the width - (parentPaddingValue+24) ${(width - (parentPaddingValue+24))}");
double widthOfOneState = (width/4) - (parentPaddingValue+8.h); double widthOfOneState = (width/4) - (parentPaddingValue+8.h);
print("te width of one state is $widthOfOneState");
print("the value of${width/4}");
if(state == null) { if(state == null) {
return Row( return Row(
children: List.generate(4, (index) { children: List.generate(4, (index) {

Loading…
Cancel
Save