Merge branch 'master' into dev_aamir

# Conflicts:
#	assets/langs/ar-SA.json
#	assets/langs/en-US.json
#	lib/extensions/string_extensions.dart
#	lib/generated/locale_keys.g.dart
pull/8/head
aamir-csol 2 months ago
commit da035650c0

@ -0,0 +1,3 @@
<svg width="14" height="13" viewBox="0 0 14 13" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.99984 12.7702C3.53655 12.7702 0.729004 9.96263 0.729004 6.49935C0.729004 3.03606 3.53655 0.228516 6.99984 0.228516C10.4631 0.228516 13.2707 3.03606 13.2707 6.49935C13.2707 9.96263 10.4631 12.7702 6.99984 12.7702ZM9.1623 5.16184C9.39012 4.93404 9.39013 4.5647 9.16233 4.33688C8.93453 4.10907 8.56519 4.10906 8.33737 4.33686L6.99972 5.67442L5.6623 4.33709C5.43449 4.10929 5.06514 4.1093 4.83734 4.33711C4.60955 4.56493 4.60956 4.93427 4.83737 5.16207L6.17474 6.49935L4.83737 7.83663C4.60956 8.06442 4.60955 8.43377 4.83734 8.66158C5.06514 8.8894 5.43449 8.88941 5.6623 8.66161L6.99972 7.32428L8.33737 8.66184C8.56519 8.88964 8.93453 8.88963 9.16233 8.66181C9.39013 8.434 9.39012 8.06465 9.1623 7.83686L7.82471 6.49935L9.1623 5.16184Z" fill="#ED1C2B"/>
</svg>

After

Width:  |  Height:  |  Size: 909 B

@ -0,0 +1,4 @@
<svg width="22" height="23" viewBox="0 0 22 23" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M19.4932 13.7808C20.7528 9.09639 17.955 4.27023 13.2297 3.00853C9.70851 2.06832 6.11906 3.37593 3.99728 6.04158C3.84468 6.2333 3.86798 6.50772 4.04125 6.68099L5.04846 7.6882C5.18151 7.82125 5.1938 8.04137 5.18151 8.24316C5.14872 8.78189 4.6854 9.19203 4.14668 9.15923L1.69362 9.00989C1.38358 8.99102 1.10097 8.82587 0.932324 8.56502C0.76368 8.30416 0.72909 7.97867 0.839142 7.6882C2.77489 2.57901 8.3266 -0.323654 13.7339 1.12017C19.4935 2.65805 22.9235 8.55039 21.3807 14.2883C19.8381 20.025 13.9137 23.4174 8.1554 21.8799C3.87709 20.7375 0.886935 17.1944 0.261338 13.0982C0.179854 12.5647 0.546317 12.0661 1.07986 11.9846C1.61339 11.9031 2.11197 12.2696 2.19345 12.8031C2.70523 16.1541 5.15307 19.0552 8.65962 19.9915C13.3861 21.2536 18.2332 18.4666 19.4932 13.7808Z" fill="#ED1C2B"/>
<path d="M12 7.5C12 6.94772 11.5523 6.5 11 6.5C10.4477 6.5 10 6.94772 10 7.5V11.5C10 11.7652 10.1054 12.0196 10.2929 12.2071L12.2929 14.2071C12.6834 14.5976 13.3166 14.5976 13.7071 14.2071C14.0976 13.8166 14.0976 13.1834 13.7071 12.7929L12 11.0858V7.5Z" fill="#ED1C2B"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

@ -0,0 +1,5 @@
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="40" height="40" rx="10" fill="#EFEFF0"/>
<path d="M20 9.25C15.5442 9.25 11.9279 12.8415 11.9279 17.277C11.9278 18.3087 11.8584 19.0873 11.3827 19.7872C11.3166 19.8831 11.2288 20.0032 11.1329 20.1345C10.9663 20.3625 10.7753 20.624 10.6303 20.8505C10.3745 21.2503 10.1246 21.7324 10.0387 22.2942C9.75836 24.127 11.0506 25.3136 12.3375 25.8454C16.8702 27.7182 23.1298 27.7182 27.6625 25.8454C28.9494 25.3136 30.2416 24.127 29.9613 22.2942C29.8754 21.7324 29.6255 21.2503 29.3697 20.8505C29.2247 20.624 29.0337 20.3625 28.8671 20.1345C28.7712 20.0033 28.6835 19.8832 28.6173 19.7873C28.1416 19.0874 28.0722 18.3088 28.0721 17.277C28.0721 12.8415 24.4558 9.25 20 9.25Z" fill="#8F9AA3"/>
<path d="M19.9985 30.7477C21.0187 30.7477 21.9742 30.4563 22.7776 29.9511C23.4906 29.5027 23.8472 29.2785 23.7224 28.9057C23.5976 28.533 23.1057 28.5747 22.1217 28.6582C20.7146 28.7776 19.2824 28.7776 17.8752 28.6582C16.8913 28.5747 16.3993 28.533 16.2745 28.9057C16.1498 29.2784 16.5063 29.5027 17.2193 29.9511C18.0227 30.4563 18.9782 30.7477 19.9985 30.7477Z" fill="#8F9AA3"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

@ -0,0 +1,4 @@
<svg width="15" height="16" viewBox="0 0 15 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6.16613 2.14867C6.59446 2.05148 7.04084 2 7.50016 2C10.8139 2 13.5002 4.68629 13.5002 8C13.5002 9.53082 12.9272 10.928 11.9827 11.9886L11.9827 11C11.9827 10.5858 11.6469 10.25 11.2327 10.25C10.8185 10.25 10.4827 10.5858 10.4827 11L10.4827 13.625C10.4827 14.0392 10.8185 14.375 11.2327 14.375H13.8752C14.2894 14.375 14.6252 14.0392 14.6252 13.625C14.6252 13.2108 14.2894 12.875 13.8752 12.875H13.1997C14.3217 11.5644 15.0002 9.86153 15.0002 8C15.0002 3.85786 11.6423 0.5 7.50016 0.5C6.9284 0.5 6.3707 0.564117 5.8342 0.685856C5.43025 0.777516 5.1771 1.17928 5.26876 1.58323C5.36042 1.98717 5.76218 2.24033 6.16613 2.14867Z" fill="#18C273"/>
<path d="M1.125 1.63672C0.710786 1.63672 0.375 1.97251 0.375 2.38672C0.375 2.80093 0.710786 3.13672 1.125 3.13672H1.79048C0.674497 4.44574 0 6.14405 0 8.00006C0 12.1422 3.35786 15.5001 7.5 15.5001C8.07176 15.5001 8.62946 15.4359 9.16597 15.3142C9.56991 15.2225 9.82307 14.8208 9.73141 14.4168C9.63975 14.0129 9.23798 13.7597 8.83404 13.8514C8.4057 13.9486 7.95932 14.0001 7.5 14.0001C4.18629 14.0001 1.5 11.3138 1.5 8.00006C1.5 6.4787 2.06588 5.08936 3 4.03118V5.00006C3 5.41427 3.33579 5.75006 3.75 5.75006C4.16421 5.75006 4.5 5.41427 4.5 5.00006V2.38672C4.5 1.97251 4.16421 1.63672 3.75 1.63672L1.125 1.63672Z" fill="#18C273"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

@ -782,6 +782,9 @@
"resultsPending": "النتائج معلقة",
"resultsAvailable": "النتائج متاحة",
"viewReport": "عرض التقرير",
"checkAvailability": "التحقق من التوفر",
"readInstructions": "قراءة التعليمات",
"searchLabReport" : "ابحث عن تقرير المختبر",
"prescriptionDeliveryError": "هذه العيادة لا تدعم إعادة التعبئة والتسليم.",
"receiveOtpToast": "أين تود تلقي رمز التحقق OTP؟",
"enterPhoneNumber": "أدخل رقم الهاتف",

@ -783,6 +783,9 @@
"resultsPending": "Results Pending",
"resultsAvailable": "Results Available",
"viewReport": "View Report",
"checkAvailability": "Check Availability",
"readInstructions": "Read Instructions",
"searchLabReport" : "Search Lab Report",
"prescriptionDeliveryError": "This clinic doesn't support refill",
"prepareToElevate": "Prepared to elevate your health and well-being?",
"iAcceptTermsConditions": "I Accept the Terms and Conditions",

@ -749,7 +749,6 @@ class ApiConsts {
static final String sendActivationCode = 'Services/Authentication.svc/REST/SendActivationCodebyOTPNotificationType';
static setBackendURLs() {
if (isDevelopment) {
baseUrl = "https://uat.hmgwebservices.com/";

@ -67,6 +67,10 @@ class AppAssets {
static const String rating_icon = '$svgBasePath/rating_icon.svg';
static const String doctor_calendar_icon = '$svgBasePath/doctor_calendar_icon.svg';
static const String prescription_remarks_icon = '$svgBasePath/prescription_remarks_icon.svg';
static const String prescription_reminder_icon = '$svgBasePath/prescription_reminder_icon.svg';
static const String insurance_history_icon = '$svgBasePath/insurance_history_icon.svg';
static const String cancel_circle_icon = '$svgBasePath/cancel_circle.svg';
static const String update_insurance_card_icon = '$svgBasePath/update_insurance_card.svg';
//bottom navigation//
@ -75,6 +79,7 @@ class AppAssets {
static const String myFilesBottom = '$svgBasePath/my_files_bottom.svg';
static const String toDoBottom = '$svgBasePath/todo_bottom.svg';
static const String servicesBottom = '$svgBasePath/services_bottom.svg';
static const String closeBottomNav = '$svgBasePath/close_bottom_nav.svg';
// PNGS //
static const String hmg_logo = '$pngBasePath/hmg_logo.png';

@ -6,6 +6,8 @@ import 'package:hmg_patient_app_new/features/authentication/authentication_repo.
import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_repo.dart';
import 'package:hmg_patient_app_new/features/common/common_repo.dart';
import 'package:hmg_patient_app_new/features/insurance/insurance_repo.dart';
import 'package:hmg_patient_app_new/features/insurance/insurance_view_model.dart';
import 'package:hmg_patient_app_new/features/lab/lab_repo.dart';
import 'package:hmg_patient_app_new/features/lab/lab_view_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_repo.dart';
@ -65,6 +67,7 @@ class AppDependencies {
getIt.registerLazySingleton<LabRepo>(() => LabRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
getIt.registerLazySingleton<RadiologyRepo>(() => RadiologyRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
getIt.registerLazySingleton<PrescriptionsRepo>(() => PrescriptionsRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
getIt.registerLazySingleton<InsuranceRepo>(() => InsuranceRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
// ViewModels
// Global/shared VMs LazySingleton
@ -90,6 +93,13 @@ class AppDependencies {
),
);
getIt.registerLazySingleton<InsuranceViewModel>(
() => InsuranceViewModel(
insuranceRepo: getIt(),
errorHandlerService: getIt(),
),
);
getIt.registerLazySingleton<AuthenticationViewModel>(
() => AuthenticationViewModel(
authenticationRepo: getIt(),

@ -4,8 +4,6 @@ import 'dart:io';
import 'dart:ui';
import 'package:device_calendar/device_calendar.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:manage_calendar_events/manage_calendar_events.dart' as ios;
import 'package:timezone/data/latest.dart' as tzl;
@ -137,14 +135,12 @@ class CalendarUtils {
print("catchError " + e.toString());
}).whenComplete(() {
print("whenComplete Calender ID " + eventId!);
// Utils.showToast(LocaleKeys.appoReminderSuccess.tr());
});
} else {
await _myPlugin.createEvent(calendarId: writableCalendars.id!, event: iosCalEvent).catchError((e) {
print("catchError " + e.toString());
}).whenComplete(() {
print("whenComplete Calender ID iOS " + eventId!);
// Utils.showToast(LocaleKeys.appoReminderSuccess.tr());
});
}
}

@ -11,6 +11,10 @@ extension ResponsiveExtension on num {
double get h => ((this * _width) / FIGMA_DESIGN_WIDTH);
double get fSize => ((this * _width) / FIGMA_DESIGN_WIDTH);
static double get screenHeight => SizeUtils.height;
/// Full screen width
static double get screenWidth => SizeUtils.width;
}
extension FormatExtension on double {

@ -13,13 +13,16 @@ extension CapExtension on String {
String get allInCaps => this.toUpperCase();
String get capitalizeFirstofEach => this.trim().length > 0 ? this.trim().toLowerCase().split(" ").map((str) => str.inCaps).join(" ") : "";
String get capitalizeFirstofEach =>
this.trim().length > 0 ? this.trim().toLowerCase().split(" ").map((str) => str.inCaps).join(" ") : "";
}
extension EmailValidator on String {
Widget get toWidget => Text(this);
Widget toText8({Color? color, bool isBold = false, int? maxlines, FontStyle? fontStyle, TextOverflow? textOverflow}) => Text(
Widget toText8(
{Color? color, bool isBold = false, int? maxlines, FontStyle? fontStyle, TextOverflow? textOverflow}) =>
Text(
this,
maxLines: maxlines,
overflow: textOverflow,
@ -32,7 +35,14 @@ extension EmailValidator on String {
),
);
Widget toText10({Color? color, bool isBold = false, bool isUnderLine = false, int? maxlines, FontStyle? fontStyle, TextOverflow? textOverflow}) => Text(
Widget toText10(
{Color? color,
bool isBold = false,
bool isUnderLine = false,
int? maxlines,
FontStyle? fontStyle,
TextOverflow? textOverflow}) =>
Text(
this,
maxLines: maxlines,
overflow: textOverflow,
@ -46,7 +56,15 @@ extension EmailValidator on String {
decorationColor: color ?? AppColors.blackColor),
);
Widget toText11({Color? color, FontWeight? weight, bool isUnderLine = false, bool isCenter = false, bool isBold = false, int maxLine = 0, double letterSpacing = 0.64}) => Text(
Widget toText11(
{Color? color,
FontWeight? weight,
bool isUnderLine = false,
bool isCenter = false,
bool isBold = false,
int maxLine = 0,
double letterSpacing = 0.64}) =>
Text(
this,
textAlign: isCenter ? TextAlign.center : null,
maxLines: (maxLine > 0) ? maxLine : null,
@ -60,21 +78,33 @@ extension EmailValidator on String {
),
);
Widget toText12({Color? color, bool isUnderLine = false, bool isBold = false, bool isCenter = false, int maxLine = 0}) => Text(
Widget toText12(
{Color? color,
bool isUnderLine = false,
bool isBold = false,
FontWeight? fontWeight,
bool isCenter = false,
double? height,
int maxLine = 0}) =>
Text(
this,
textAlign: isCenter ? TextAlign.center : null,
maxLines: (maxLine > 0) ? maxLine : null,
style: TextStyle(
fontSize: 12.fSize,
fontWeight: isBold ? FontWeight.bold : FontWeight.normal,
fontWeight: fontWeight ?? (isBold ? FontWeight.bold : FontWeight.normal),
color: color ?? AppColors.blackColor,
letterSpacing: -0.4,
height: height,
decorationColor: isUnderLine ? AppColors.blackColor : null,
decoration: isUnderLine ? TextDecoration.underline : null,
),
);
Widget toText12Auto({Color? color, bool isUnderLine = false, bool isBold = false, bool isCenter = false, int maxLine = 0}) => AutoSizeText(
Widget toText12Auto(
{Color? color, bool isUnderLine = false, bool isBold = false, bool isCenter = false, int maxLine = 0}) =>
AutoSizeText(
this,
textAlign: isCenter ? TextAlign.center : null,
maxLines: (maxLine > 0) ? maxLine : null,
@ -135,7 +165,14 @@ extension EmailValidator on String {
decoration: isUnderLine ? TextDecoration.underline : null),
);
Widget toText14({Color? color, bool isUnderLine = false, bool isBold = false, bool isCenter = false, FontWeight? weight, int? maxlines}) => Text(
Widget toText14(
{Color? color,
bool isUnderLine = false,
bool isBold = false,
bool isCenter = false,
FontWeight? weight,
int? maxlines}) =>
Text(
this,
textAlign: isCenter ? TextAlign.center : null,
maxLines: maxlines,
@ -147,7 +184,14 @@ extension EmailValidator on String {
decoration: isUnderLine ? TextDecoration.underline : null),
);
Widget toText15({Color? color, bool isUnderLine = false, bool isBold = false, bool isCenter = false, FontWeight? weight, int? maxlines}) => Text(
Widget toText15(
{Color? color,
bool isUnderLine = false,
bool isBold = false,
bool isCenter = false,
FontWeight? weight,
int? maxlines}) =>
Text(
this,
textAlign: isCenter ? TextAlign.center : null,
maxLines: maxlines,
@ -183,72 +227,84 @@ extension EmailValidator on String {
Widget toText17({Color? color, bool isBold = false, bool isCenter = false}) => Text(
this,
textAlign: isCenter ? TextAlign.center : null,
style: TextStyle(color: color ?? AppColors.blackColor, fontSize: 17.fSize, letterSpacing: -0.4, fontWeight: isBold ? FontWeight.bold : FontWeight.normal),
style: TextStyle(
color: color ?? AppColors.blackColor,
fontSize: 17.fSize,
letterSpacing: -0.4,
fontWeight: isBold ? FontWeight.bold : FontWeight.normal),
);
Widget toText18({Color? color, bool isBold = false, bool isCenter = false, int? maxlines}) => Text(
maxLines: maxlines,
textAlign: isCenter ? TextAlign.center : null,
this,
style: TextStyle(fontSize: 18.fSize, fontWeight: isBold ? FontWeight.bold : FontWeight.normal, color: color ?? AppColors.blackColor, letterSpacing: -0.4),
style: TextStyle(
fontSize: 18.fSize,
fontWeight: isBold ? FontWeight.bold : FontWeight.normal,
color: color ?? AppColors.blackColor,
letterSpacing: -0.4),
);
Widget toText19({Color? color, bool isBold = false}) => Text(
this,
style: TextStyle(fontSize: 19.fSize, fontWeight: isBold ? FontWeight.bold : FontWeight.normal, color: color ?? AppColors.blackColor, letterSpacing: -0.4),
style: TextStyle(
fontSize: 19.fSize,
fontWeight: isBold ? FontWeight.bold : FontWeight.normal,
color: color ?? AppColors.blackColor,
letterSpacing: -0.4),
);
Widget toText20({Color? color, bool isBold = false}) => Text(
this,
style: TextStyle(fontSize: 20.fSize, fontWeight: isBold ? FontWeight.bold : FontWeight.normal, color: color ?? AppColors.blackColor, letterSpacing: -0.4),
style: TextStyle(
fontSize: 20.fSize,
fontWeight: isBold ? FontWeight.bold : FontWeight.normal,
color: color ?? AppColors.blackColor,
letterSpacing: -0.4),
);
Widget toText21({Color? color, bool isBold = false, FontWeight? weight, int? maxlines}) => Text(
this,
maxLines: maxlines,
style: TextStyle(color: color ?? AppColors.blackColor, fontSize: 21.fSize, letterSpacing: -0.4, fontWeight: weight ?? (isBold ? FontWeight.w600 : FontWeight.normal)),
style: TextStyle(color: color ?? AppColors.blackColor, fontSize: 21.fSize, letterSpacing: -0.4, fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.normal)),
);
Widget toText22({Color? color, bool isBold = false, bool isCenter = false}) => Text(
this,
textAlign: isCenter ? TextAlign.center : null,
style: TextStyle(height: 1, color: color ?? AppColors.blackColor, fontSize: 22.fSize, letterSpacing: -0.4, fontWeight: isBold ? FontWeight.w600 : FontWeight.normal),
style: TextStyle(
height: 1,
color: color ?? AppColors.blackColor,
fontSize: 22.fSize,
letterSpacing: -0.4,
fontWeight: isBold ? FontWeight.bold : FontWeight.normal),
);
Widget toText24({Color? color, bool isBold = false, bool isCenter = false}) => Text(
this,
textAlign: isCenter ? TextAlign.center : null,
style: TextStyle(height: 23 / 24, color: color ?? AppColors.blackColor, fontSize: 24.fSize, letterSpacing: -0.4, fontWeight: isBold ? FontWeight.w600 : FontWeight.normal),
);
Widget toText26({Color? color, bool isBold = false, bool isCenter = false, double height = 23/26}) => Text(
this,
textAlign: isCenter ? TextAlign.center : null,
style: TextStyle(height: height, color: color ?? AppColors.blackColor, fontSize: 26.fSize, letterSpacing: -1, fontWeight: isBold ? FontWeight.w600 : FontWeight.normal),
);
Widget toText28({Color? color, bool isBold = false, bool isCenter = false, TextScaler? textScaler}) => Text(
this,
textAlign: isCenter ? TextAlign.center : null,
textScaler: textScaler,
style: TextStyle(height: 40 / 28, color: color ?? AppColors.blackColor, fontSize: 28.fSize, letterSpacing: -1, fontWeight: isBold ? FontWeight.w600 : FontWeight.normal),
style: TextStyle(
height: 23 / 24,
color: color ?? AppColors.blackColor,
fontSize: 24.fSize,
letterSpacing: -0.4,
fontWeight: isBold ? FontWeight.bold : FontWeight.normal),
);
Widget toText32({Color? color, bool isBold = false, bool isCenter = false}) => Text(
this,
textAlign: isCenter ? TextAlign.center : null,
style: TextStyle(height: 32 / 32, color: color ?? AppColors.blackColor, fontSize: 32.fSize, letterSpacing: -0.4, fontWeight: isBold ? FontWeight.w600 : FontWeight.normal),
);
Widget toText36({Color? color, bool isBold = false, bool isCenter = false}) => Text(
this,
textAlign: isCenter ? TextAlign.center : null,
style: TextStyle(height: 47 / 36, color: color ?? AppColors.blackColor, fontSize: 36.fSize, letterSpacing: -1, fontWeight: isBold ? FontWeight.w600 : FontWeight.normal),
style: TextStyle(
height: 32 / 32,
color: color ?? AppColors.blackColor,
fontSize: 32.fSize,
letterSpacing: -0.4,
fontWeight: isBold ? FontWeight.bold : FontWeight.normal),
);
Widget toText44({Color? color, bool isBold = false}) => Text(
this,
style: TextStyle(height: 32 / 32, color: color ?? AppColors.blackColor, fontSize: 44.fSize, letterSpacing: -0.4, fontWeight: isBold ? FontWeight.w600 : FontWeight.normal),
style: TextStyle(height: 32 / 32, color: color ?? AppColors.blackColor, fontSize: 44.fSize, letterSpacing: -0.4, fontWeight: isBold ? FontWeight.bold : FontWeight.normal),
);
Widget toSectionHeading({String upperHeading = "", String lowerHeading = ""}) {
@ -284,7 +340,9 @@ extension EmailValidator on String {
}
bool isValidEmail() {
return RegExp(r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$').hasMatch(this);
return RegExp(
r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$')
.hasMatch(this);
}
String toFormattedDate() {

@ -0,0 +1,77 @@
import 'package:dartz/dartz.dart';
import 'package:hmg_patient_app_new/core/api/api_client.dart';
import 'package:hmg_patient_app_new/core/api_consts.dart';
import 'package:hmg_patient_app_new/core/common_models/generic_api_model.dart';
import 'package:hmg_patient_app_new/core/exceptions/api_failure.dart';
import 'package:hmg_patient_app_new/features/insurance/models/resp_models/patient_insurance_details_response_model.dart';
import 'package:hmg_patient_app_new/services/logger_service.dart';
abstract class InsuranceRepo {
Future<Either<Failure, GenericApiModel<List<PatientInsuranceDetailsResponseModel>>>> getPatientInsuranceDetails({required String patientId});
}
class InsuranceRepoImp implements InsuranceRepo {
final ApiClient apiClient;
final LoggerService loggerService;
InsuranceRepoImp({required this.loggerService, required this.apiClient});
@override
Future<Either<Failure, GenericApiModel<List<PatientInsuranceDetailsResponseModel>>>> getPatientInsuranceDetails({required String patientId}) async {
final mapDevice = {
"isDentalAllowedBackend": false,
"VersionID": 50.0,
"Channel": 3,
"LanguageID": 2,
"IPAdress": "10.20.10.20",
"generalid": "Cs2020@2016\$2958",
"Latitude": 0.0,
"Longitude": 0.0,
"DeviceTypeID": 1,
"PatientType": 1,
"PatientTypeID": 1,
"TokenID": "@dm!n",
"PatientID": "3628599",
"PatientOutSA": "0",
"SessionID": "03478TYC02N80874CTYN04883475!?"
};
try {
GenericApiModel<List<PatientInsuranceDetailsResponseModel>>? apiResponse;
Failure? failure;
await apiClient.post(
GET_PAtIENTS_INSURANCE,
body: mapDevice,
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
},
onSuccess: (response, statusCode, {messageStatus}) {
try {
final list = response['List_PatientInsuranceCard'];
if (list == null || list.isEmpty) {
throw Exception("insurance list is empty");
}
final labOrders = list.map((item) => PatientInsuranceDetailsResponseModel.fromJson(item as Map<String, dynamic>)).toList().cast<PatientInsuranceDetailsResponseModel>();
apiResponse = GenericApiModel<List<PatientInsuranceDetailsResponseModel>>(
messageStatus: messageStatus,
statusCode: statusCode,
errorMessage: null,
data: labOrders,
);
} 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()));
}
throw UnimplementedError();
}
}

@ -0,0 +1,43 @@
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/features/insurance/insurance_repo.dart';
import 'package:hmg_patient_app_new/features/insurance/models/resp_models/patient_insurance_details_response_model.dart';
import 'package:hmg_patient_app_new/features/lab/lab_repo.dart';
import 'package:hmg_patient_app_new/services/error_handler_service.dart';
class InsuranceViewModel extends ChangeNotifier {
bool isInsuranceLoading = false;
InsuranceRepo insuranceRepo;
ErrorHandlerService errorHandlerService;
List<PatientInsuranceDetailsResponseModel> patientInsuranceList = [];
InsuranceViewModel({required this.insuranceRepo, required this.errorHandlerService});
initInsuranceProvider() {
patientInsuranceList.clear();
isInsuranceLoading = true;
getPatientInsuranceDetails();
notifyListeners();
}
Future<void> getPatientInsuranceDetails({Function(dynamic)? onSuccess, Function(String)? onError}) async {
final result = await insuranceRepo.getPatientInsuranceDetails(patientId: "1231755");
result.fold(
(failure) async => await errorHandlerService.handleError(failure: failure),
(apiResponse) {
if (apiResponse.messageStatus == 2) {
// dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
} else if (apiResponse.messageStatus == 1) {
patientInsuranceList = apiResponse.data!;
isInsuranceLoading = false;
notifyListeners();
if (onSuccess != null) {
onSuccess(apiResponse);
}
}
},
);
}
}

@ -0,0 +1,96 @@
class PatientInsuranceDetailsResponseModel {
String? setupID;
int? projectID;
bool? isActive;
int? patientID;
int? companyID;
int? subCategoryID;
dynamic companyType;
String? patientCardID;
String? cardValidTo;
int? patientCreditLimit;
String? subPolicyNo;
String? companyName;
String? companyNameN;
String? subCategoryDesc;
dynamic subCategoryDescN;
bool? isElectronicClaim;
String? subCategoryValidTo;
dynamic groupID;
String? groupName;
dynamic groupNameN;
String? insurancePolicyNo;
PatientInsuranceDetailsResponseModel(
{this.setupID,
this.projectID,
this.isActive,
this.patientID,
this.companyID,
this.subCategoryID,
this.companyType,
this.patientCardID,
this.cardValidTo,
this.patientCreditLimit,
this.subPolicyNo,
this.companyName,
this.companyNameN,
this.subCategoryDesc,
this.subCategoryDescN,
this.isElectronicClaim,
this.subCategoryValidTo,
this.groupID,
this.groupName,
this.groupNameN,
this.insurancePolicyNo});
PatientInsuranceDetailsResponseModel.fromJson(Map<String, dynamic> json) {
setupID = json['SetupID'];
projectID = json['ProjectID'];
isActive = json['IsActive'];
patientID = json['PatientID'];
companyID = json['CompanyID'];
subCategoryID = json['SubCategoryID'];
companyType = json['CompanyType'];
patientCardID = json['PatientCardID'];
cardValidTo = json['CardValidTo'];
patientCreditLimit = json['PatientCreditLimit'];
subPolicyNo = json['SubPolicyNo'];
companyName = json['CompanyName'];
companyNameN = json['CompanyNameN'];
subCategoryDesc = json['SubCategoryDesc'];
subCategoryDescN = json['SubCategoryDescN'];
isElectronicClaim = json['IsElectronicClaim'];
subCategoryValidTo = json['SubCategoryValidTo'];
groupID = json['GroupID'];
groupName = json['GroupName'];
groupNameN = json['GroupNameN'];
insurancePolicyNo = json['InsurancePolicyNo'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['SetupID'] = this.setupID;
data['ProjectID'] = this.projectID;
data['IsActive'] = this.isActive;
data['PatientID'] = this.patientID;
data['CompanyID'] = this.companyID;
data['SubCategoryID'] = this.subCategoryID;
data['CompanyType'] = this.companyType;
data['PatientCardID'] = this.patientCardID;
data['CardValidTo'] = this.cardValidTo;
data['PatientCreditLimit'] = this.patientCreditLimit;
data['SubPolicyNo'] = this.subPolicyNo;
data['CompanyName'] = this.companyName;
data['CompanyNameN'] = this.companyNameN;
data['SubCategoryDesc'] = this.subCategoryDesc;
data['SubCategoryDescN'] = this.subCategoryDescN;
data['IsElectronicClaim'] = this.isElectronicClaim;
data['SubCategoryValidTo'] = this.subCategoryValidTo;
data['GroupID'] = this.groupID;
data['GroupName'] = this.groupName;
data['GroupNameN'] = this.groupNameN;
data['InsurancePolicyNo'] = this.insurancePolicyNo;
return data;
}
}

@ -12,6 +12,10 @@ class LabViewModel extends ChangeNotifier {
List<PatientLabOrdersResponseModel> patientLabOrders = [];
List<String> labSuggestionsList =[];
get labSuggestions => labSuggestionsList;
LabViewModel({required this.labRepo, required this.errorHandlerService});
initLabProvider() {
@ -42,4 +46,8 @@ class LabViewModel extends ChangeNotifier {
},
);
}
filterSuggestions(){
}
}

@ -32,6 +32,7 @@ class PrescriptionDetailResponseModel {
String? sKU;
num? scaleOffset;
String? startDate;
bool? hasReminder;
PrescriptionDetailResponseModel(
{this.address,
@ -66,7 +67,8 @@ class PrescriptionDetailResponseModel {
this.route,
this.sKU,
this.scaleOffset,
this.startDate});
this.startDate,
this.hasReminder = false});
PrescriptionDetailResponseModel.fromJson(Map<String, dynamic> json) {
address = json['Address'];
@ -102,6 +104,7 @@ class PrescriptionDetailResponseModel {
sKU = json['SKU'];
scaleOffset = json['ScaleOffset'];
startDate = json['StartDate'];
hasReminder = false;
}
Map<String, dynamic> toJson() {

@ -43,6 +43,14 @@ class PrescriptionsViewModel extends ChangeNotifier {
notifyListeners();
}
setPrescriptionItemReminder(bool value, PrescriptionDetailResponseModel item) {
int index = prescriptionDetailsList.indexOf(item);
if (index != -1) {
prescriptionDetailsList[index].hasReminder = value;
notifyListeners();
}
}
setIsSortByClinic(bool value) {
isSortByClinic = value;
if (isSortByClinic) {

@ -802,5 +802,8 @@ abstract class LocaleKeys {
static const loginByOTP = 'loginByOTP';
static const guest = 'guest';
static const switchAccount = 'switchAccount';
static const checkAvailability = 'checkAvailability';
static const readInstructions = 'readInstructions';
static const searchLabReport = 'searchLabReport';
}

@ -7,6 +7,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart';
import 'package:hmg_patient_app_new/features/insurance/insurance_view_model.dart';
import 'package:hmg_patient_app_new/features/lab/lab_view_model.dart';
import 'package:hmg_patient_app_new/features/prescriptions/prescriptions_view_model.dart';
import 'package:hmg_patient_app_new/features/radiology/radiology_view_model.dart';
@ -71,6 +72,12 @@ void main() async {
errorHandlerService: getIt(),
),
),
ChangeNotifierProvider<InsuranceViewModel>(
create: (_) => InsuranceViewModel(
insuranceRepo: getIt(),
errorHandlerService: getIt(),
),
),
ChangeNotifierProvider<AuthenticationViewModel>(
create: (_) => AuthenticationViewModel(
authenticationRepo: getIt(),

@ -18,7 +18,6 @@ import 'package:hmg_patient_app_new/presentation/home/widgets/large_service_card
import 'package:hmg_patient_app_new/presentation/home/widgets/small_service_card.dart';
import 'package:hmg_patient_app_new/presentation/medical_file/medical_file_page.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/bottom_navigation/bottom_navigation.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
import 'package:provider/provider.dart';
@ -31,6 +30,7 @@ class LandingPage extends StatefulWidget {
}
class _LandingPageState extends State<LandingPage> {
@override
Widget build(BuildContext context) {
AppState appState = getIt.get<AppState>();
@ -272,7 +272,6 @@ class _LandingPageState extends State<LandingPage> {
),
),
),
bottomNavigationBar: BottomNavigation(),
);
}
}

@ -0,0 +1,40 @@
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/presentation/home/landing_page.dart';
import 'package:hmg_patient_app_new/presentation/medical_file/medical_file_page.dart';
import 'package:hmg_patient_app_new/widgets/bottom_navigation/bottom_navigation.dart';
class LandingNavigation extends StatefulWidget {
const LandingNavigation({super.key});
@override
State<LandingNavigation> createState() => _LandingNavigationState();
}
class _LandingNavigationState extends State<LandingNavigation> {
int _currentIndex = 0;
final PageController _pageController = PageController();
@override
Widget build(BuildContext context) {
return Scaffold(
body: PageView(
controller: _pageController,
physics: const NeverScrollableScrollPhysics(),
children: [
const LandingPage(),
MedicalFilePage(),
const LandingPage(),
const LandingPage(),
const LandingPage(),
],
),
bottomNavigationBar: BottomNavigation(
currentIndex: _currentIndex,
onTap: (index) {
setState(() => _currentIndex = index);
_pageController.animateToPage(index, duration: const Duration(milliseconds: 300), curve: Curves.easeInOut);
},
),
);
}
}

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/presentation/insurance/insurance_home_page.dart';
import 'package:hmg_patient_app_new/presentation/lab/lab_orders_page.dart';
import 'package:hmg_patient_app_new/presentation/prescriptions/prescriptions_list_page.dart';
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
@ -78,6 +79,11 @@ class SmallServiceCard extends StatelessWidget {
);
break;
case "insurance_update":
Navigator.of(context).push(
FadePage(
page: InsuranceHomePage(),
),
);
break;
default:
// Handle unknown service

@ -0,0 +1,93 @@
import 'dart:async';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/utils/date_util.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/features/insurance/insurance_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/insurance/widgets/patient_insurance_card.dart';
import 'package:hmg_patient_app_new/presentation/lab/search_lab_report.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
import 'package:hmg_patient_app_new/widgets/shimmer/movies_shimmer_widget.dart';
import 'package:provider/provider.dart';
class InsuranceHomePage extends StatefulWidget {
const InsuranceHomePage({super.key});
@override
State<InsuranceHomePage> createState() => _InsuranceHomePageState();
}
class _InsuranceHomePageState extends State<InsuranceHomePage> {
late InsuranceViewModel insuranceViewModel;
@override
void initState() {
scheduleMicrotask(() {
insuranceViewModel.initInsuranceProvider();
});
super.initState();
}
@override
Widget build(BuildContext context) {
insuranceViewModel = Provider.of<InsuranceViewModel>(context);
return Scaffold(
backgroundColor: AppColors.bgScaffoldColor,
appBar: AppBar(
title: LocaleKeys.insurance.tr(context: context).toText18(),
backgroundColor: AppColors.bgScaffoldColor,
),
body: SingleChildScrollView(
child: Consumer<InsuranceViewModel>(builder: (context, insuranceVM, child) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"${LocaleKeys.insurance.tr(context: context)} ${LocaleKeys.updateInsurance.tr(context: context)}".toText24(isBold: true),
CustomButton(
icon: AppAssets.insurance_history_icon,
iconColor: AppColors.primaryRedColor,
iconSize: 21.h,
text: LocaleKeys.history.tr(context: context),
onPressed: () {
showCommonBottomSheet(
context,
child: Container(),
callBackFunc: () {},
title: "",
height: ResponsiveExtension.screenHeight * 0.5,
isCloseButtonVisible: false,
);
},
backgroundColor: AppColors.primaryRedColor.withOpacity(0.1),
borderColor: AppColors.primaryRedColor.withOpacity(0.0),
textColor: AppColors.primaryRedColor,
fontSize: 14,
fontWeight: FontWeight.w600,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 40.h,
),
],
).paddingSymmetrical(24.h, 24.h),
insuranceVM.isInsuranceLoading
? const MoviesShimmerWidget().paddingSymmetrical(24.h, 0)
: PatientInsuranceCard(
insuranceCardDetailsModel: insuranceVM.patientInsuranceList.first,
isInsuranceExpired: DateTime.now().isAfter(DateUtil.convertStringToDate(insuranceVM.patientInsuranceList.first.cardValidTo))),
],
);
}),
),
);
}
}

@ -0,0 +1,133 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/utils/date_util.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/insurance/insurance_view_model.dart';
import 'package:hmg_patient_app_new/features/insurance/models/resp_models/patient_insurance_details_response_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
import 'package:provider/provider.dart';
class PatientInsuranceCard extends StatelessWidget {
PatientInsuranceCard({super.key, required this.insuranceCardDetailsModel, required this.isInsuranceExpired});
PatientInsuranceDetailsResponseModel insuranceCardDetailsModel;
bool isInsuranceExpired = false;
late InsuranceViewModel insuranceViewModel;
@override
Widget build(BuildContext context) {
insuranceViewModel = Provider.of<InsuranceViewModel>(context);
return Container(
width: double.infinity,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 24,
),
child: Padding(
padding: EdgeInsets.all(16.h),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Haroon Amjad".toText18(isBold: true),
"Policy: ${insuranceCardDetailsModel.insurancePolicyNo}".toText12(isBold: true, color: AppColors.lightGrayColor),
],
),
CustomButton(
icon: isInsuranceExpired ? AppAssets.cancel_circle_icon : AppAssets.insurance_active_icon,
iconColor: isInsuranceExpired ? AppColors.primaryRedColor : AppColors.successColor,
iconSize: 13.h,
text: isInsuranceExpired ? "Insurance Expired" : "Insurance Active",
onPressed: () {},
backgroundColor: isInsuranceExpired ? AppColors.primaryRedColor.withOpacity(0.15) : AppColors.successColor.withOpacity(0.15),
borderColor: isInsuranceExpired ? AppColors.primaryRedColor.withOpacity(0.01) : AppColors.successColor.withOpacity(0.01),
textColor: isInsuranceExpired ? AppColors.primaryRedColor : AppColors.successColor,
fontSize: 10,
fontWeight: FontWeight.w500,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 30.h,
),
],
),
SizedBox(height: 12.h),
insuranceCardDetailsModel.groupName!.toText12(isBold: true),
insuranceCardDetailsModel.companyName!.toText12(isBold: true),
SizedBox(height: 8.h),
Wrap(
direction: Axis.horizontal,
spacing: 6.h,
runSpacing: 6.h,
children: [
Row(
children: [
CustomButton(
icon: AppAssets.doctor_calendar_icon,
iconColor: AppColors.blackColor,
iconSize: 13.h,
text: "${LocaleKeys.expiryDate.tr(context: context)} ${DateUtil.formatDateToDate(DateUtil.convertStringToDate(insuranceCardDetailsModel.cardValidTo), false)}",
onPressed: () {},
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 10,
fontWeight: FontWeight.w500,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 30.h,
),
],
),
Row(
children: [
CustomButton(
text: "Patient Card ID: ${insuranceCardDetailsModel.patientCardID}",
onPressed: () {},
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 10,
fontWeight: FontWeight.w500,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 30.h,
),
],
),
],
),
SizedBox(height: 10.h),
isInsuranceExpired
? CustomButton(
icon: AppAssets.update_insurance_card_icon,
iconColor: AppColors.successColor,
iconSize: 15.h,
text: "${LocaleKeys.updateInsurance.tr(context: context)} ${LocaleKeys.updateInsuranceSubtitle.tr(context: context)}",
onPressed: () {},
backgroundColor: AppColors.bgGreenColor.withOpacity(0.20),
borderColor: AppColors.bgGreenColor.withOpacity(0.0),
textColor: AppColors.bgGreenColor,
fontSize: 14,
fontWeight: FontWeight.w500,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 40.h,
)
: Container(),
],
),
),
).paddingSymmetrical(24.h, 0.h);
}
}

@ -5,14 +5,19 @@ import 'package:flutter/material.dart';
import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/utils/date_util.dart';
import 'package:hmg_patient_app_new/core/utils/size_config.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/lab/models/resp_models/patient_lab_orders_response_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/features/lab/lab_view_model.dart';
import 'package:hmg_patient_app_new/presentation/lab/search_lab_report.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/bottom_sheet.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
import 'package:hmg_patient_app_new/widgets/shimmer/movies_shimmer_widget.dart';
import 'package:provider/provider.dart';
@ -25,7 +30,7 @@ class LabOrdersPage extends StatefulWidget {
class _LabOrdersPageState extends State<LabOrdersPage> {
late LabViewModel labProvider;
List<List<TestDetails>?> labSuggestions = [];
int? expandedIndex;
@override
@ -57,7 +62,17 @@ class _LabOrdersPageState extends State<LabOrdersPage> {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
LocaleKeys.labResults.tr(context: context).toText24(isBold: true),
Utils.buildSvgWithAssets(icon: AppAssets.search_icon),
Utils.buildSvgWithAssets(icon: AppAssets.search_icon).onPress(() {
if(model.isLabOrdersLoading){
return;
} else {
labSuggestions = getLabSuggestions(model);
showCommonBottomSheet(context, child: SearchLabResultsContent(),
callBackFunc: () {},
title: LocaleKeys.searchLabReport.tr(),
height: ResponsiveExtension.screenHeight,
isCloseButtonVisible: true);
} }),
],
),
SizedBox(height: 16.h),
@ -262,4 +277,13 @@ class _LabOrdersPageState extends State<LabOrdersPage> {
return "";
}
}
getLabSuggestions(LabViewModel model) {
if(model.patientLabOrders.isEmpty){
return [];
}
return model.patientLabOrders.map((m) => m.testDetails).toList();
}
}

@ -0,0 +1,116 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/app_export.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
import 'package:hmg_patient_app_new/widgets/input_widget.dart';
import 'package:sizer/sizer.dart';
class SearchLabResultsContent extends StatelessWidget {
const SearchLabResultsContent({super.key});
final List<String> _chipLabels = const [
"Blood Test",
"X-Ray",
"MRI Scan",
"CT Scan",
"Ultrasound",
"Urine Test",
"Allergy Test",
"Cholesterol Test",
"Diabetes Test",
"Thyroid Test",
];
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextInputWidget(
labelText:"Search lab results",
hintText: "Type test name",
controller: TextEditingController(),
isEnable: true,
prefix: null,
autoFocus: true,
isBorderAllowed: false,
padding: EdgeInsets.symmetric(vertical:ResponsiveExtension(10).h, horizontal: ResponsiveExtension(15).h),
),
SizedBox(height: ResponsiveExtension(20).h),
"Suggestions".toText16(isBold: true),
const SizedBox(height: 12),
],
),
),
Expanded(
child: SingleChildScrollView(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Wrap(
alignment: WrapAlignment.start,
spacing: 10,
runSpacing: 10,
children: _chipLabels
.map((label) => SuggestionChip(
label: label,
onTap: () {},
))
.toList(),
),
),
),
Container(
color: Colors.white,
padding: EdgeInsets.all(ResponsiveExtension(20).h),
child: CustomButton(
text: LocaleKeys.search.tr(),
icon: AppAssets.search_icon,
iconColor: Colors.white,
onPressed: () => Navigator.pop(context),
),
),
],
);
}
}
class SuggestionChip extends StatelessWidget {
final String label;
final bool isSelected;
final VoidCallback? onTap;
const SuggestionChip({
super.key,
required this.label,
this.isSelected = false,
this.onTap,
});
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onTap, // optional tap callback
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8),
decoration: BoxDecoration(
color: isSelected ? AppColors.primaryRedColor : AppColors.whiteColor,
borderRadius: BorderRadius.circular(8),
),
child: label.toText12(
color: isSelected ? Colors.white : Colors.black87,
fontWeight: FontWeight.w500,
),
),
);
}
}

@ -1,20 +1,28 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/utils/date_util.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/insurance/insurance_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/insurance/widgets/patient_insurance_card.dart';
import 'package:hmg_patient_app_new/presentation/medical_file/widgets/medical_file_card.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
import 'package:hmg_patient_app_new/widgets/input_widget.dart';
import 'package:hmg_patient_app_new/widgets/shimmer/movies_shimmer_widget.dart';
import 'package:provider/provider.dart';
class MedicalFilePage extends StatelessWidget {
const MedicalFilePage({super.key});
MedicalFilePage({super.key});
late InsuranceViewModel insuranceViewModel;
@override
Widget build(BuildContext context) {
insuranceViewModel = Provider.of<InsuranceViewModel>(context);
return Scaffold(
backgroundColor: AppColors.bgScaffoldColor,
appBar: AppBar(
@ -161,101 +169,13 @@ class MedicalFilePage extends StatelessWidget {
),
SizedBox(height: 16.h),
//Insurance Tab Data
Container(
// height: 150.h,
width: double.infinity,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 24,
),
child: Padding(
padding: EdgeInsets.all(16.h),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Haroon Amjad".toText18(isBold: true),
"Policy: 223123345".toText12(isBold: true, color: AppColors.lightGrayColor),
],
),
CustomButton(
icon: AppAssets.cross_circle,
iconColor: AppColors.primaryRedColor,
iconSize: 13.h,
text: "Insurance Expired",
onPressed: () {},
backgroundColor: AppColors.primaryRedColor.withOpacity(0.1),
borderColor: AppColors.primaryRedColor.withOpacity(0.0),
textColor: AppColors.primaryRedColor,
fontSize: 10,
fontWeight: FontWeight.w500,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 30.h,
),
],
),
SizedBox(height: 12.h),
"NCCI".toText12(isBold: true),
"NC_Dr Sulaiman Al Habib Medical Group".toText12(isBold: true),
SizedBox(height: 8.h),
Row(
children: [
CustomButton(
icon: AppAssets.cross_circle,
iconColor: AppColors.primaryRedColor,
iconSize: 13.h,
text: "Expiry: 18 Mar, 2025",
onPressed: () {},
backgroundColor: AppColors.primaryRedColor.withOpacity(0.1),
borderColor: AppColors.primaryRedColor.withOpacity(0.0),
textColor: AppColors.primaryRedColor,
fontSize: 10,
fontWeight: FontWeight.w500,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 30.h,
),
SizedBox(width: 5.h),
CustomButton(
text: "Patient Card ID: 3628599",
onPressed: () {},
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 10,
fontWeight: FontWeight.normal,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 30.h,
),
],
),
SizedBox(height: 10.h),
CustomButton(
icon: AppAssets.cross_circle,
iconColor: AppColors.primaryRedColor,
iconSize: 13.h,
text: "${LocaleKeys.updateInsurance.tr(context: context)} ${LocaleKeys.updateInsuranceSubtitle.tr(context: context)}",
onPressed: () {},
backgroundColor: AppColors.bgGreenColor.withOpacity(0.20),
borderColor: AppColors.bgGreenColor.withOpacity(0.0),
textColor: AppColors.bgGreenColor,
fontSize: 14,
fontWeight: FontWeight.w500,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 40.h,
),
],
),
),
),
Consumer<InsuranceViewModel>(builder: (context, insuranceVM, child) {
return insuranceVM.isInsuranceLoading
? const MoviesShimmerWidget()
: PatientInsuranceCard(
insuranceCardDetailsModel: insuranceVM.patientInsuranceList.first,
isInsuranceExpired: DateTime.now().isBefore(DateUtil.convertStringToDate(insuranceVM.patientInsuranceList.first.cardValidTo)));
}),
SizedBox(height: 10.h),
GridView(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, crossAxisSpacing: 13, mainAxisSpacing: 13),

@ -29,6 +29,8 @@ class PrescriptionDetailPage extends StatefulWidget {
class _PrescriptionDetailPageState extends State<PrescriptionDetailPage> {
late PrescriptionsViewModel prescriptionsViewModel;
bool _isSwitched = false; // Initial state of the switch
@override
void initState() {
scheduleMicrotask(() {
@ -46,267 +48,353 @@ class _PrescriptionDetailPageState extends State<PrescriptionDetailPage> {
title: LocaleKeys.prescriptions.tr(context: context).toText18(),
backgroundColor: AppColors.bgScaffoldColor,
),
body: SingleChildScrollView(
child: Consumer<PrescriptionsViewModel>(builder: (context, prescriptionVM, child) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.prescriptions.tr(context: context).toText24(isBold: true).paddingSymmetrical(24.h, 0.h),
SizedBox(height: 24.h),
Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 20.h,
hasShadow: true,
),
child: Padding(
padding: EdgeInsets.all(16.h),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisSize: MainAxisSize.min,
children: [
Image.network(
widget.prescriptionsResponseModel.doctorImageURL!,
width: 24.h,
height: 24.h,
fit: BoxFit.fill,
).circle(100),
SizedBox(width: 8.h),
Expanded(child: widget.prescriptionsResponseModel.doctorName!.toText16(isBold: true)),
],
),
SizedBox(height: 16.h),
Wrap(
direction: Axis.horizontal,
spacing: 6.h,
runSpacing: 6.h,
children: [
Row(
mainAxisSize: MainAxisSize.min,
children: [
CustomButton(
icon: AppAssets.doctor_calendar_icon,
iconColor: AppColors.textColor,
iconSize: 13.h,
text: DateUtil.formatDateToDate(DateUtil.convertStringToDate(widget.prescriptionsResponseModel.appointmentDate), false),
onPressed: () {},
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 12,
fontWeight: FontWeight.w500,
borderRadius: 8,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 30.h,
),
],
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
CustomButton(
text: widget.prescriptionsResponseModel.clinicDescription!,
onPressed: () {},
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 12,
fontWeight: FontWeight.w500,
borderRadius: 8,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 30.h,
),
],
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
CustomButton(
icon: AppAssets.rating_icon,
iconColor: AppColors.ratingColorYellow,
iconSize: 13.h,
text: "Rating: ${widget.prescriptionsResponseModel.decimalDoctorRate}",
onPressed: () {},
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 12,
fontWeight: FontWeight.w500,
borderRadius: 8,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 30.h,
),
],
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
CustomButton(
text: widget.prescriptionsResponseModel.name!,
onPressed: () {},
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 12,
fontWeight: FontWeight.w500,
borderRadius: 8,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 30.h,
),
],
),
],
body: Column(
children: [
Expanded(
child: SingleChildScrollView(
child: Consumer<PrescriptionsViewModel>(builder: (context, prescriptionVM, child) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.prescriptions.tr(context: context).toText24(isBold: true).paddingSymmetrical(24.h, 0.h),
SizedBox(height: 24.h),
Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 20.h,
hasShadow: true,
),
],
),
),
).paddingSymmetrical(24.h, 0.h),
SizedBox(height: 16.h),
ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: prescriptionVM.isPrescriptionsDetailsLoading ? 5 : prescriptionVM.prescriptionDetailsList.length,
itemBuilder: (context, index) {
return prescriptionVM.isPrescriptionsDetailsLoading
? const MoviesShimmerWidget()
: AnimationConfiguration.staggeredList(
position: index,
duration: const Duration(milliseconds: 500),
child: SlideAnimation(
verticalOffset: 100.0,
child: FadeInAnimation(
child: AnimatedContainer(
duration: Duration(milliseconds: 300),
curve: Curves.easeInOut,
margin: EdgeInsets.symmetric(vertical: 8.h),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 20.h, hasShadow: true),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
child: Padding(
padding: EdgeInsets.all(16.h),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisSize: MainAxisSize.min,
children: [
Image.network(
widget.prescriptionsResponseModel.doctorImageURL!,
width: 24.h,
height: 24.h,
fit: BoxFit.fill,
).circle(100),
SizedBox(width: 8.h),
Expanded(child: widget.prescriptionsResponseModel.doctorName!.toText16(isBold: true)),
],
),
SizedBox(height: 16.h),
Wrap(
direction: Axis.horizontal,
spacing: 6.h,
runSpacing: 6.h,
children: [
Row(
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: EdgeInsets.all(16.h),
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Image.network(
prescriptionVM.prescriptionDetailsList[index].imageSRCUrl!,
width: 60.h,
height: 60.h,
fit: BoxFit.fill,
).circle(100),
SizedBox(width: 8.h),
Expanded(
child: prescriptionVM.prescriptionDetailsList[index].itemDescription!.toText16(isBold: true, maxlines: 2),
),
],
),
SizedBox(height: 16.h),
Wrap(
direction: Axis.horizontal,
spacing: 6.h,
runSpacing: 6.h,
children: [
Row(
mainAxisSize: MainAxisSize.min,
children: [
CustomButton(
text: "${LocaleKeys.route.tr(context: context)}: ${prescriptionVM.prescriptionDetailsList[index].route}",
onPressed: () {},
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 12,
fontWeight: FontWeight.w500,
borderRadius: 8,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 30.h,
),
],
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
CustomButton(
text: "${LocaleKeys.frequency.tr(context: context)}: ${prescriptionVM.prescriptionDetailsList[index].frequency}",
onPressed: () {},
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 12,
fontWeight: FontWeight.w500,
borderRadius: 8,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 30.h,
),
],
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
CustomButton(
text: "${LocaleKeys.dailyDoses.tr(context: context)}: ${prescriptionVM.prescriptionDetailsList[index].doseDailyQuantity}",
CustomButton(
icon: AppAssets.doctor_calendar_icon,
iconColor: AppColors.textColor,
iconSize: 13.h,
text: DateUtil.formatDateToDate(DateUtil.convertStringToDate(widget.prescriptionsResponseModel.appointmentDate), false),
onPressed: () {},
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 10,
fontWeight: FontWeight.w500,
borderRadius: 8,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 30.h,
),
],
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
CustomButton(
text: widget.prescriptionsResponseModel.clinicDescription!,
onPressed: () {},
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 10,
fontWeight: FontWeight.w500,
borderRadius: 8,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 30.h,
),
],
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
CustomButton(
icon: AppAssets.rating_icon,
iconColor: AppColors.ratingColorYellow,
iconSize: 13.h,
text: "Rating: ${widget.prescriptionsResponseModel.decimalDoctorRate}",
onPressed: () {},
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 10,
fontWeight: FontWeight.w500,
borderRadius: 8,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 30.h,
),
],
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
CustomButton(
text: widget.prescriptionsResponseModel.name!,
onPressed: () {},
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 10,
fontWeight: FontWeight.w500,
borderRadius: 8,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 30.h,
),
],
),
],
),
],
),
),
).paddingSymmetrical(24.h, 0.h),
SizedBox(height: 16.h),
ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: prescriptionVM.isPrescriptionsDetailsLoading ? 5 : prescriptionVM.prescriptionDetailsList.length,
itemBuilder: (context, index) {
return prescriptionVM.isPrescriptionsDetailsLoading
? const MoviesShimmerWidget()
: AnimationConfiguration.staggeredList(
position: index,
duration: const Duration(milliseconds: 500),
child: SlideAnimation(
verticalOffset: 100.0,
child: FadeInAnimation(
child: AnimatedContainer(
duration: Duration(milliseconds: 300),
curve: Curves.easeInOut,
margin: EdgeInsets.symmetric(vertical: 8.h),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 20.h, hasShadow: true),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 16.h),
Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Image.network(
prescriptionVM.prescriptionDetailsList[index].imageThumbUrl!,
width: 60.h,
height: 60.h,
fit: BoxFit.fill,
).circle(100),
SizedBox(width: 8.h),
Expanded(
child: prescriptionVM.prescriptionDetailsList[index].itemDescription!.toText16(isBold: true, maxlines: 2),
),
],
).paddingSymmetrical(16.h, 0.h),
SizedBox(height: 16.h),
Wrap(
direction: Axis.horizontal,
spacing: 6.h,
runSpacing: 6.h,
children: [
Row(
mainAxisSize: MainAxisSize.min,
children: [
CustomButton(
text: "${LocaleKeys.route.tr(context: context)}: ${prescriptionVM.prescriptionDetailsList[index].route}",
onPressed: () {},
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 10,
fontWeight: FontWeight.w500,
borderRadius: 8,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 30.h,
),
],
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
CustomButton(
text: "${LocaleKeys.frequency.tr(context: context)}: ${prescriptionVM.prescriptionDetailsList[index].frequency}",
onPressed: () {},
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 10,
fontWeight: FontWeight.w500,
borderRadius: 8,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 30.h,
),
],
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
CustomButton(
text: "${LocaleKeys.dailyDoses.tr(context: context)}: ${prescriptionVM.prescriptionDetailsList[index].doseDailyQuantity}",
onPressed: () {},
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 10,
fontWeight: FontWeight.w500,
borderRadius: 8,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 30.h,
),
],
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
CustomButton(
text: "${LocaleKeys.days.tr(context: context)}: ${prescriptionVM.prescriptionDetailsList[index].days}",
onPressed: () {},
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 10,
fontWeight: FontWeight.w500,
borderRadius: 8,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 30.h,
),
],
),
],
).paddingSymmetrical(16.h, 0.h),
SizedBox(height: 8.h),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Utils.buildSvgWithAssets(icon: AppAssets.prescription_remarks_icon, width: 18.h, height: 18.h),
SizedBox(width: 9.h),
Expanded(child: "${LocaleKeys.remarks.tr(context: context)}: ${prescriptionVM.prescriptionDetailsList[index].remarks!}".toText10(isBold: true)),
],
).paddingSymmetrical(16.h, 0.h),
SizedBox(height: 14.h),
Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h),
SizedBox(height: 14.h),
Row(
mainAxisSize: MainAxisSize.max,
children: [
Utils.buildSvgWithAssets(icon: AppAssets.prescription_reminder_icon, width: 35.h, height: 35.h),
SizedBox(width: 8.h),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.setReminder.tr(context: context).toText13(isBold: true),
"Notify me before the consumption time".toText10(color: AppColors.textColorLight),
],
),
SizedBox(width: 12.h),
Switch(
activeColor: AppColors.successColor,
value: prescriptionVM.prescriptionDetailsList[index].hasReminder!,
onChanged: (newValue) {
setState(() {
prescriptionVM.setPrescriptionItemReminder(newValue, prescriptionVM.prescriptionDetailsList[index]);
});
},
),
],
).paddingSymmetrical(16.h, 0.h),
SizedBox(height: 14.h),
Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h),
Row(
children: [
Expanded(
child: CustomButton(
text: LocaleKeys.checkAvailability.tr(context: context),
onPressed: () {},
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 12,
backgroundColor: AppColors.primaryRedColor.withOpacity(0.1),
borderColor: AppColors.primaryRedColor.withOpacity(0.0),
textColor: AppColors.primaryRedColor,
fontSize: 13,
fontWeight: FontWeight.w500,
borderRadius: 8,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 30.h,
height: 40.h,
),
],
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
CustomButton(
text: "${LocaleKeys.days.tr(context: context)}: ${prescriptionVM.prescriptionDetailsList[index].days}",
),
SizedBox(width: 16.h),
Expanded(
child: CustomButton(
text: LocaleKeys.readInstructions.tr(context: context),
onPressed: () {},
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 12,
backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedColor,
textColor: AppColors.whiteColor,
fontSize: 13,
fontWeight: FontWeight.w500,
borderRadius: 8,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 30.h,
height: 40.h,
),
],
),
],
),
SizedBox(height: 8.h),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Utils.buildSvgWithAssets(icon: AppAssets.prescription_remarks_icon, width: 18.h, height: 18.h),
SizedBox(width: 9.h),
Expanded(child: "${LocaleKeys.remarks.tr(context: context)}: ${prescriptionVM.prescriptionDetailsList[index].remarks!}".toText10(isBold: true)),
],
)
],
),
),
],
).paddingSymmetrical(16.h, 16.h),
],
)
],
),
)
],
),
),
),
),
),
),
);
},
).paddingSymmetrical(24.h, 0.h),
],
);
}),
);
},
).paddingSymmetrical(24.h, 0.h),
],
);
}),
),
),
Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 24.h,
hasShadow: true,
),
child: CustomButton(
text: widget.prescriptionsResponseModel.isHomeMedicineDeliverySupported! ? LocaleKeys.resendOrder.tr(context: context) : LocaleKeys.prescriptionDeliveryError.tr(context: context),
onPressed: () {},
backgroundColor: widget.prescriptionsResponseModel.isHomeMedicineDeliverySupported! ? AppColors.successColor : AppColors.greyF7Color,
borderColor: AppColors.successColor.withOpacity(0.01),
textColor: widget.prescriptionsResponseModel.isHomeMedicineDeliverySupported! ? AppColors.whiteColor : AppColors.textColor.withOpacity(0.35),
fontSize: 16,
fontWeight: FontWeight.w500,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 50.h,
icon: AppAssets.prescription_refill_icon,
iconColor: widget.prescriptionsResponseModel.isHomeMedicineDeliverySupported! ? AppColors.whiteColor : AppColors.textColor.withOpacity(0.35),
iconSize: 20.h,
).paddingSymmetrical(24.h, 24.h),
),
],
),
);
}

@ -196,7 +196,7 @@ class _PrescriptionsListPageState extends State<PrescriptionsListPage> {
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 12,
fontSize: 10,
fontWeight: FontWeight.w500,
borderRadius: 8,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
@ -209,7 +209,7 @@ class _PrescriptionsListPageState extends State<PrescriptionsListPage> {
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 12,
fontSize: 10,
fontWeight: FontWeight.w500,
borderRadius: 8,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),

@ -11,6 +11,7 @@ import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
// import 'package:hmg_patient_app_new/presentation/authantication/login.dart';
import 'package:hmg_patient_app_new/presentation/home/landing_page.dart';
import 'package:hmg_patient_app_new/presentation/home/navigation_screen.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
import 'package:provider/provider.dart';
@ -37,7 +38,7 @@ class _SplashScreenState extends State<SplashPage> {
LocalNotification.init(onNotificationClick: (payload) {});
Navigator.of(context).pushReplacement(
FadePage(
page: LandingPage(),
page: LandingNavigation(),
// page: LoginScreen(),
),
);

@ -28,6 +28,7 @@ class AppColors {
static const Color bgRedLightColor = Color(0xFFFEE9EA);
static const Color bgGreenColor = Color(0xFF18C273);
static const Color textColor = Color(0xFF2E3039);
static const Color textColorLight = Color(0xFF5E5E5E);
static const Color borderOnlyColor = Color(0xFF2E3039);
static const Color dividerColor = Color(0xFFD2D2D2);
static const Color warningColorYellow = Color(0xFFF4A308);

@ -1,59 +1,103 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
class BottomNavigation extends StatelessWidget {
const BottomNavigation({super.key});
final int currentIndex;
final ValueChanged<int> onTap;
const BottomNavigation({
super.key,
required this.currentIndex,
required this.onTap,
});
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.symmetric(vertical: 12),
decoration: const BoxDecoration(
color: Colors.white,
border: Border(
top: BorderSide(color: AppColors.bottomNAVBorder, width: 0.5),
),
final items = [
BottomNavItem(icon: AppAssets.homeBottom, label: LocaleKeys.home.tr()),
BottomNavItem(icon: AppAssets.myFilesBottom, label: LocaleKeys.myFiles.tr()),
BottomNavItem(
icon: AppAssets.bookAppoBottom,
label: LocaleKeys.appointment.tr(),
iconSize: 27,
isSpecial: true,
),
BottomNavItem(icon: AppAssets.toDoBottom, label: LocaleKeys.todoList.tr()),
BottomNavItem(icon: AppAssets.servicesBottom, label: LocaleKeys.services2.tr()),
];
return Container(
decoration: _containerDecoration,
padding: _containerPadding,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
_buildNavItem(AppAssets.homeBottom, LocaleKeys.home.tr()),
_buildNavItem(AppAssets.myFilesBottom, LocaleKeys.myFiles.tr()),
_buildNavItem(AppAssets.bookAppoBottom, LocaleKeys.appointment.tr(), iconSize: 32),
_buildNavItem(AppAssets.toDoBottom, LocaleKeys.todoList.tr()),
_buildNavItem(AppAssets.servicesBottom, LocaleKeys.services2.tr()),
],
children: List.generate(
items.length,
(index) => _buildNavItem(items[index], index),
),
),
);
}
Widget _buildNavItem(String iconName, String label,{ double iconSize = 24}) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
padding: const EdgeInsets.all(10),
child: Utils.buildSvgWithAssets(
icon: iconName,
height: iconSize,
width: iconSize
),
),
// const SizedBox(height: 4),
Text(
label,
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.w500,
color: Colors.black87,
Widget _buildNavItem(BottomNavItem item, int index) {
final bool isSelected = currentIndex == index;
return GestureDetector(
onTap: () => onTap(index),
behavior: HitTestBehavior.opaque,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Center(
child: Utils.buildSvgWithAssets(
icon: item.icon,
height: item.iconSize.h,
width: item.iconSize.h,
// iconColor: isSelected ? Colors.black87 : Colors.black87,
),
),
const SizedBox(height: 10),
item.label.toText12(
fontWeight:FontWeight.w500,
// color: Colors.black87,
// textAlign: TextAlign.center,
),
),
],
SizedBox(height: item.isSpecial ? 5:0 )
],
),
);
}
}
class BottomNavItem {
final String icon;
final String label;
final double iconSize;
final bool isSpecial;
const BottomNavItem({
required this.icon,
required this.label,
this.iconSize = 21,
this.isSpecial = false,
});
}
// Constants
const EdgeInsets _containerPadding = EdgeInsets.all(15);
const BoxDecoration _containerDecoration = BoxDecoration(
color: Colors.white,
border: Border(
top: BorderSide(
color: AppColors.bottomNAVBorder,
width: 0.5,
),
),
);

@ -0,0 +1,83 @@
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/app_export.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/presentation/lab/search_lab_report.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
void showCommonBottomSheet(BuildContext context, {required Widget child, required VoidCallback callBackFunc, String? title, required double height, bool isCloseButtonVisible = true}) {
showModalBottomSheet<String>(
context: context,
isScrollControlled: false,
showDragHandle: false,
backgroundColor: AppColors.scaffoldBgColor,
builder: (BuildContext context) {
return Container(
height: height,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.scaffoldBgColor, borderRadius: 24.h),
child: ButtonSheetContent(
title: title!,
isCloseButtonVisible: isCloseButtonVisible,
child: child,
),
);
}).then((value) {
callBackFunc();
});
}
class ButtonSheetContent extends StatelessWidget {
final Widget child;
final String title;
final bool isCloseButtonVisible;
const ButtonSheetContent({super.key, required this.child, required this.isCloseButtonVisible, required this.title});
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// SizedBox(
// height: 20.h,
// ),
Center(
child: Container(
margin: const EdgeInsets.only(top: 18, bottom: 12),
height: 4,
width: 40.h,
decoration: BoxDecoration(
color: Colors.grey[400],
borderRadius: BorderRadius.circular(2),
),
),
),
// Close button
isCloseButtonVisible
? Padding(
padding: EdgeInsets.symmetric(horizontal: 16),
child: Utils.buildSvgWithAssets(icon: AppAssets.closeBottomNav, width: 32, height: 32).onPress(() {
Navigator.of(context).pop();
}),
)
: SizedBox(),
SizedBox(
height: 20,
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 16),
child: Text(
title,
style: TextStyle(fontSize: 27.h, fontWeight: FontWeight.bold),
),
),
const SizedBox(height: 16),
Expanded(child: child)
],
);
}
}
Loading…
Cancel
Save