Completed THE Theme changes

pull/380/head
FaizHashmi 2 weeks ago
parent 8b9f4d98f3
commit fe9d76affd

@ -4,6 +4,7 @@
"start_date": null,
"end_date": null,
"primary_color": null,
"secondary_color": null,
"background_opacity_image": null,
"background_image_opacity": 0.2,
"header_image": null

@ -20,7 +20,5 @@
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>13.0</string>
</dict>
</plist>

@ -29,6 +29,7 @@
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */ = {isa = PBXBuildFile; productRef = 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@ -90,6 +91,7 @@
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
A83C76CFF9D3F92EDE3B22B4 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterGeneratedPluginSwiftPackage; path = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -97,6 +99,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */,
76B1D2512F91BF8000DBBD1B /* Penguin.xcframework in Frameworks */,
76B1D2552F91BF8000DBBD1B /* PenNavUI.xcframework in Frameworks */,
76B1D2532F91BF8000DBBD1B /* PenguinINRenderer.xcframework in Frameworks */,
@ -159,6 +162,7 @@
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */,
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
@ -230,6 +234,9 @@
productType = "com.apple.product-type.bundle.unit-test";
};
97C146ED1CF9000F007C117D /* Runner */ = {
packageProductDependencies = (
78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */,
);
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
@ -256,6 +263,9 @@
/* Begin PBXProject section */
97C146E61CF9000F007C117D /* Project object */ = {
packageReferences = (
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */,
);
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = YES;
@ -790,6 +800,18 @@
defaultConfigurationName = Debug;
};
/* End XCConfigurationList section */
/* Begin XCLocalSwiftPackageReference section */
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */ = {
isa = XCLocalSwiftPackageReference;
relativePath = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage;
};
/* End XCLocalSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */ = {
isa = XCSwiftPackageProductDependency;
productName = FlutterGeneratedPluginSwiftPackage;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = 97C146E61CF9000F007C117D /* Project object */;
}

@ -5,6 +5,24 @@
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<PreActions>
<ExecutionAction
ActionType = "Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.ShellScriptAction">
<ActionContent
title = "Run Prepare Flutter Framework Script"
scriptText = "/bin/sh &quot;$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh&quot; prepare&#10;">
<EnvironmentBuildable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</EnvironmentBuildable>
</ActionContent>
</ExecutionAction>
</PreActions>
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"

@ -5,7 +5,7 @@ import 'package:hmg_patient_app_new/core/enums.dart';
class ApiConsts {
static const maxSmallScreen = 660;
static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.preProd;
static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.prod;
// static String baseUrl = 'https://uat.hmgwebservices.com/'; // HIS API URL UAT

@ -437,8 +437,8 @@ class Utils {
onCancelTap();
}
},
backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedColor,
backgroundColor: AppColors.criticalActionColor,
borderColor: AppColors.criticalActionColor,
textColor: AppColors.whiteColor,
// icon: AppAssets.cancel,
// iconColor: AppColors.whiteColor,
@ -516,8 +516,8 @@ class Utils {
onCancelTap();
}
},
backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedColor,
backgroundColor: AppColors.criticalActionColor,
borderColor: AppColors.criticalActionColor,
textColor: AppColors.whiteColor,
// icon: AppAssets.cancel,
// iconColor: AppColors.whiteColor,

@ -95,6 +95,12 @@ class OccasionConfigModel {
/// Parsed [Color] from [primaryColorHex], or null if not configured.
Color? get primaryColor => _hexToColor(primaryColorHex);
/// Lighter/translucent variant of [primaryColor] — 11% opacity of the same
/// hue (e.g. for chip/badge backgrounds). Derived automatically from
/// [primaryColor]; not an independent remote-config field. Null unless
/// [primaryColor] is configured.
Color? get secondaryColor => primaryColor?.withValues(alpha: 0.11);
static Color? _hexToColor(String? hex) {
if (hex == null || hex.isEmpty) return null;
var value = hex.trim().replaceFirst('#', '');

@ -1,6 +1,7 @@
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/painting.dart' show Color;
import 'package:hmg_patient_app_new/features/occasion_theme/occasion_config_model.dart';
import 'package:hmg_patient_app_new/services/cache_service.dart';
import 'package:hmg_patient_app_new/services/logger_service.dart';
@ -45,6 +46,11 @@ class OccasionThemeViewModel extends ChangeNotifier {
/// banner), rendered at full opacity. Null unless an occasion is active.
String? get headerImage => isOccasionActive ? _config.headerImage : null;
/// Lighter/translucent variant of the active occasion's primary color
/// (11% opacity) — e.g. for chip/badge backgrounds. Null unless an
/// occasion is active.
Color? get secondaryColor => isOccasionActive ? _config.secondaryColor : null;
/// Call once at app startup (before the first frame) to restore the last
/// known-good config instantly (offline-safe), then kick off a remote
/// fetch in the background.
@ -97,6 +103,7 @@ class OccasionThemeViewModel extends ChangeNotifier {
void _applyToAppColors() {
AppColors.isOccasionThemeActive = isOccasionActive;
AppColors.occasionPrimaryColor = _config.primaryColor;
AppColors.occasionSecondaryColor = _config.secondaryColor;
}
}

@ -150,7 +150,7 @@ class AppointmentQueuePage extends StatelessWidget {
textColor: myAppointmentsVM.patientQueueDetailsList[index].callType == 1 ? AppColors.primaryRedColor : AppColors.successColor,
iconSize: 14.w,
backgroundColor: myAppointmentsVM.patientQueueDetailsList[index].callType == 1
? AppColors.primaryRedColorBase.withValues(alpha: 0.1)
? AppColors.primaryRedColor.withValues(alpha: 0.1)
: AppColors.successColor.withValues(alpha: 0.1),
labelPadding: EdgeInsetsDirectional.only(start: 8.h, end: -2.h),
),

@ -68,7 +68,7 @@ class AskDoctorAppointmentCard extends StatelessWidget {
),
AppCustomChipWidget(
labelText: LocaleKeys.outPatient.tr(context: context),
backgroundColor: AppColors.primaryRedColorBase.withValues(alpha: 0.1),
backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.1),
textColor: AppColors.primaryRedColor,
),
AppCustomChipWidget(

@ -94,17 +94,18 @@ class QuickLoginState extends State<QuickLogin> {
mainAxisAlignment: MainAxisAlignment.end,
children: [
Expanded(
child: CustomButton(
text: LocaleKeys.enableQuickLoginBtn.tr(context: context),
onPressed: () {
widget.onPressed();
},
backgroundColor: Color(0xffED1C2B),
borderColor: Color(0xffED1C2B),
textColor: Colors.white,
icon: AppAssets.apple_finder,
height: 56.h,
)),
child: CustomButton(
text: LocaleKeys.enableQuickLoginBtn.tr(context: context),
onPressed: () {
widget.onPressed();
},
backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedColor,
textColor: Colors.white,
icon: AppAssets.apple_finder,
height: 56.h,
),
),
],
),
SizedBox(
@ -113,16 +114,16 @@ class QuickLoginState extends State<QuickLogin> {
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Expanded(
Expanded(
child: CustomButton(
text: LocaleKeys.notNow.tr(context: context),
onPressed: () {
cacheService.saveBool(key: CacheConst.quickLoginEnabled, value: false);
Navigator.pop(context, "true");
},
backgroundColor: Color(0xffFEE9EA),
borderColor: Color(0xffFEE9EA),
textColor: Colors.red,
backgroundColor: AppColors.secondaryLightRedColor,
borderColor: AppColors.secondaryLightRedColor,
textColor: AppColors.primaryRedColor,
height: 56.h,
// icon: "assets/images/svg/apple-finder.svg",
)),

@ -327,9 +327,9 @@ class _SavedLogin extends State<SavedLogin> with RouteAware {
// MaterialPageRoute(builder: (BuildContext context) => LandingNavigation())
// );
},
backgroundColor: Color(0xffFEE9EA),
borderColor: Color(0xffFEE9EA),
textColor: Color(0xffED1C2B),
backgroundColor: AppColors.secondaryLightRedColor,
borderColor: Colors.transparent,
textColor: AppColors.primaryRedColor,
fontSize: 16.f,
fontWeight: FontWeight.w600,
borderRadius: 12.r,
@ -352,9 +352,9 @@ class _SavedLogin extends State<SavedLogin> with RouteAware {
MaterialPageRoute(builder: (BuildContext context) => LoginScreen()),
);
},
backgroundColor: Color(0xffFEE9EA),
borderColor: Color(0xffFEE9EA),
textColor: Color(0xffED1C2B),
backgroundColor: AppColors.secondaryLightRedColor,
borderColor: Colors.transparent,
textColor: AppColors.primaryRedColor,
fontSize: 15.f,
fontWeight: FontWeight.w600,
borderRadius: 12.r,

@ -232,7 +232,7 @@ class _BloodDonationPageState extends State<BloodDonationPage> {
Container(
padding: EdgeInsets.all(16.h),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.bgRedLightColor.withValues(alpha: 0.1),
color: AppColors.secondaryLightRedColorBase.withValues(alpha: 0.1),
borderRadius: 12.r,
hasShadow: false,
),
@ -244,7 +244,7 @@ class _BloodDonationPageState extends State<BloodDonationPage> {
Container(
padding: EdgeInsets.all(8.h),
decoration: BoxDecoration(
color: AppColors.primaryRedColorBase.withValues(alpha: 0.1),
color: AppColors.primaryRedColor.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(8.r),
),
child: Utils.buildSvgWithAssets(

@ -59,7 +59,7 @@ class FeedbackPage extends StatelessWidget {
SizedBox(height: 16.h),
CustomTabBar(
activeTextColor: AppColors.primaryRedColor,
activeBackgroundColor: AppColors.primaryRedColorBase.withValues(alpha: .1),
activeBackgroundColor: AppColors.primaryRedColor.withValues(alpha: .1),
tabs: [
CustomTabBarModel(null, LocaleKeys.send.tr(context: context)),
CustomTabBarModel(null, LocaleKeys.status.tr(context: context)), //TODO: Need to be Disabled This Tab For Now

@ -44,7 +44,7 @@ class FindUsPage extends StatelessWidget {
? SizedBox.shrink()
: CustomTabBar(
activeTextColor: AppColors.primaryRedColor,
activeBackgroundColor: AppColors.primaryRedColorBase.withValues(alpha: .1),
activeBackgroundColor: AppColors.primaryRedColor.withValues(alpha: .1),
tabs: [
CustomTabBarModel(null, LocaleKeys.hmgHospitals.tr()),
CustomTabBarModel(null, LocaleKeys.hmgPharmacy.tr()),

@ -667,7 +667,7 @@ class _ServicesPageState extends State<ServicesPage> {
borderWidth: 0.w,
isBold: true,
borderColor: Colors.transparent,
backgroundColor: AppColors.primaryRedColorBase.withValues(alpha: 0.08),
backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.08),
padding: EdgeInsets.all(8.w),
fontSize: 14.f,
onPressed: () {

@ -9,192 +9,190 @@ import 'package:hmg_patient_app_new/theme/colors.dart';
class LandingPageData {
static List<ServiceCardData> get getNotLoggedInServiceCardsList => [
ServiceCardData(
serviceName: "emergency",
icon: AppAssets.emergency_services_icon,
title: getIt.get<AppState>().isArabic()?LocaleKeys.services3 :LocaleKeys.emergency2,
subtitle: getIt.get<AppState>().isArabic()?LocaleKeys.emergency2:LocaleKeys.services3,
backgroundColor: AppColors.primaryRedColor,
iconColor: Colors.white,
textColor: Colors.white,
isBold: true,
),
ServiceCardData(
serviceName: "search_doctor",
icon: AppAssets.search_doctor_icon,
title: LocaleKeys.finda,
subtitle: LocaleKeys.doctor,
backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor,
textColor: AppColors.blackColor,
isBold: false,
),
ServiceCardData(
serviceName: "health_calculators_and_converts",
icon: AppAssets.health_calculators_icon,
title: getIt.get<AppState>().isArabic()? LocaleKeys.calculators:LocaleKeys.health ,
subtitle: getIt.get<AppState>().isArabic()? LocaleKeys.health:LocaleKeys.calculators,
backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor,
textColor: AppColors.blackColor,
isBold: false,
),
ServiceCardData(
serviceName: "health_converters",
icon: AppAssets.health_converters_icon,
title: getIt.get<AppState>().isArabic()? LocaleKeys.converters:LocaleKeys.health,
subtitle: getIt.get<AppState>().isArabic()? LocaleKeys.health:LocaleKeys.converters,
backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor,
textColor: AppColors.blackColor,
isBold: false,
),
// ServiceCardData(
// serviceName: "parking_guide",
// icon: AppAssets.car_parking_icon,
// title: getIt.get<AppState>().isArabic()? LocaleKeys.guide:LocaleKeys.parking2,
// subtitle: getIt.get<AppState>().isArabic()? LocaleKeys.parking2:LocaleKeys.guide,
// backgroundColor: AppColors.whiteColor,
// iconColor: AppColors.blackColor,
// textColor: AppColors.blackColor,
// isBold: false,
// ),
ServiceCardData(
serviceName: "indoor_navigation",
icon: AppAssets.indoor_nav_icon,
title: LocaleKeys.indoor,
subtitle: LocaleKeys.thehospital,
backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor,
textColor: AppColors.blackColor,
isBold: false,
),
];
ServiceCardData(
serviceName: "emergency",
icon: AppAssets.emergency_services_icon,
title: getIt.get<AppState>().isArabic() ? LocaleKeys.services3 : LocaleKeys.emergency2,
subtitle: getIt.get<AppState>().isArabic() ? LocaleKeys.emergency2 : LocaleKeys.services3,
backgroundColor: AppColors.primaryRedColorBase,
iconColor: Colors.white,
textColor: Colors.white,
isBold: true,
),
ServiceCardData(
serviceName: "search_doctor",
icon: AppAssets.search_doctor_icon,
title: LocaleKeys.finda,
subtitle: LocaleKeys.doctor,
backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor,
textColor: AppColors.blackColor,
isBold: false,
),
ServiceCardData(
serviceName: "health_calculators_and_converts",
icon: AppAssets.health_calculators_icon,
title: getIt.get<AppState>().isArabic() ? LocaleKeys.calculators : LocaleKeys.health,
subtitle: getIt.get<AppState>().isArabic() ? LocaleKeys.health : LocaleKeys.calculators,
backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor,
textColor: AppColors.blackColor,
isBold: false,
),
ServiceCardData(
serviceName: "health_converters",
icon: AppAssets.health_converters_icon,
title: getIt.get<AppState>().isArabic() ? LocaleKeys.converters : LocaleKeys.health,
subtitle: getIt.get<AppState>().isArabic() ? LocaleKeys.health : LocaleKeys.converters,
backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor,
textColor: AppColors.blackColor,
isBold: false,
),
// ServiceCardData(
// serviceName: "parking_guide",
// icon: AppAssets.car_parking_icon,
// title: getIt.get<AppState>().isArabic()? LocaleKeys.guide:LocaleKeys.parking2,
// subtitle: getIt.get<AppState>().isArabic()? LocaleKeys.parking2:LocaleKeys.guide,
// backgroundColor: AppColors.whiteColor,
// iconColor: AppColors.blackColor,
// textColor: AppColors.blackColor,
// isBold: false,
// ),
ServiceCardData(
serviceName: "indoor_navigation",
icon: AppAssets.indoor_nav_icon,
title: LocaleKeys.indoor,
subtitle: LocaleKeys.thehospital,
backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor,
textColor: AppColors.blackColor,
isBold: false,
),
];
List<ServiceCardData> get getLoggedInServiceCardsList => [
ServiceCardData(
serviceName: "emergency",
icon: AppAssets.emergency_services_icon,
title: getIt.get<AppState>().isArabic()?LocaleKeys.services3 :LocaleKeys.emergency2,
subtitle: getIt.get<AppState>().isArabic()?LocaleKeys.emergency2:LocaleKeys.services3,
backgroundColor: AppColors.primaryRedColor,
iconColor: Colors.white,
textColor: Colors.white,
isBold: true,
),
ServiceCardData(
serviceName: "lab_results",
icon: AppAssets.home_lab_result_icon,
title: getIt.get<AppState>().isArabic()?LocaleKeys.labSubtitle:LocaleKeys.lab,
subtitle: getIt.get<AppState>().isArabic()?LocaleKeys.lab:LocaleKeys.labSubtitle ,
backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor,
textColor: AppColors.blackColor,
isBold: false,
),
ServiceCardData(
serviceName: "radiology_results",
icon: AppAssets.my_radiology_icon,
title: getIt.get<AppState>().isArabic()?LocaleKeys.labSubtitle:LocaleKeys.radiology,
subtitle: getIt.get<AppState>().isArabic()?LocaleKeys.radiology:LocaleKeys.labSubtitle ,
backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor,
textColor: AppColors.blackColor,
isBold: false,
),
ServiceCardData(
serviceName: "prescriptions",
icon: AppAssets.my_prescription_icon,
title: getIt.get<AppState>().isArabic()?LocaleKeys.medicinesSubtitle:LocaleKeys.medicalKey,
subtitle: getIt.get<AppState>().isArabic()?LocaleKeys.medicalKey:LocaleKeys.medicinesSubtitle,
backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor,
textColor: AppColors.blackColor,
isBold: false,
),
ServiceCardData(
serviceName: "insurance_update",
icon: AppAssets.insurance_update_icon,
title: getIt.get<AppState>().isArabic()?LocaleKeys.insurance :LocaleKeys.insurance,
subtitle: getIt.get<AppState>().isArabic()?LocaleKeys.medical: LocaleKeys.details2,
backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor,
textColor: AppColors.blackColor,
isBold: false,
),
ServiceCardData(
serviceName: "my_doctors",
icon: AppAssets.my_doctors_icon,
title: getIt.get<AppState>().isArabic() ? LocaleKeys.myDoctorSubtitle2.tr() : "My",
subtitle: getIt.get<AppState>().isArabic() ? LocaleKeys.myDoctor.tr() : "Doctors",
backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor,
textColor: AppColors.blackColor,
isBold: false,
),
ServiceCardData(
serviceName: "sick_leaves",
icon: AppAssets.my_sick_leave_icon,
title: getIt.get<AppState>().isArabic()?LocaleKeys.sickSubtitle:LocaleKeys.sick2,
subtitle: getIt.get<AppState>().isArabic()?LocaleKeys.sick2:LocaleKeys.sickSubtitle,
backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor,
textColor: AppColors.blackColor,
isBold: false,
),
ServiceCardData(
serviceName: "my_invoice",
icon: AppAssets.invoiceListIcon,
title: getIt.get<AppState>().isArabic()?LocaleKeys.myDoctorSubtitle2:LocaleKeys.invoiceList2,
subtitle: getIt.get<AppState>().isArabic()?LocaleKeys.invoiceList2:LocaleKeys.myDoctorSubtitle2,
backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor,
textColor: AppColors.blackColor,
isBold: false,
),
];
ServiceCardData(
serviceName: "emergency",
icon: AppAssets.emergency_services_icon,
title: getIt.get<AppState>().isArabic() ? LocaleKeys.services3 : LocaleKeys.emergency2,
subtitle: getIt.get<AppState>().isArabic() ? LocaleKeys.emergency2 : LocaleKeys.services3,
backgroundColor: AppColors.primaryRedColorBase,
iconColor: Colors.white,
textColor: Colors.white,
isBold: true,
),
ServiceCardData(
serviceName: "lab_results",
icon: AppAssets.home_lab_result_icon,
title: getIt.get<AppState>().isArabic() ? LocaleKeys.labSubtitle : LocaleKeys.lab,
subtitle: getIt.get<AppState>().isArabic() ? LocaleKeys.lab : LocaleKeys.labSubtitle,
backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor,
textColor: AppColors.blackColor,
isBold: false,
),
ServiceCardData(
serviceName: "radiology_results",
icon: AppAssets.my_radiology_icon,
title: getIt.get<AppState>().isArabic() ? LocaleKeys.labSubtitle : LocaleKeys.radiology,
subtitle: getIt.get<AppState>().isArabic() ? LocaleKeys.radiology : LocaleKeys.labSubtitle,
backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor,
textColor: AppColors.blackColor,
isBold: false,
),
ServiceCardData(
serviceName: "prescriptions",
icon: AppAssets.my_prescription_icon,
title: getIt.get<AppState>().isArabic() ? LocaleKeys.medicinesSubtitle : LocaleKeys.medicalKey,
subtitle: getIt.get<AppState>().isArabic() ? LocaleKeys.medicalKey : LocaleKeys.medicinesSubtitle,
backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor,
textColor: AppColors.blackColor,
isBold: false,
),
ServiceCardData(
serviceName: "insurance_update",
icon: AppAssets.insurance_update_icon,
title: getIt.get<AppState>().isArabic() ? LocaleKeys.insurance : LocaleKeys.insurance,
subtitle: getIt.get<AppState>().isArabic() ? LocaleKeys.medical : LocaleKeys.details2,
backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor,
textColor: AppColors.blackColor,
isBold: false,
),
ServiceCardData(
serviceName: "my_doctors",
icon: AppAssets.my_doctors_icon,
title: getIt.get<AppState>().isArabic() ? LocaleKeys.myDoctorSubtitle2.tr() : "My",
subtitle: getIt.get<AppState>().isArabic() ? LocaleKeys.myDoctor.tr() : "Doctors",
backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor,
textColor: AppColors.blackColor,
isBold: false,
),
ServiceCardData(
serviceName: "sick_leaves",
icon: AppAssets.my_sick_leave_icon,
title: getIt.get<AppState>().isArabic() ? LocaleKeys.sickSubtitle : LocaleKeys.sick2,
subtitle: getIt.get<AppState>().isArabic() ? LocaleKeys.sick2 : LocaleKeys.sickSubtitle,
backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor,
textColor: AppColors.blackColor,
isBold: false,
),
ServiceCardData(
serviceName: "my_invoice",
icon: AppAssets.invoiceListIcon,
title: getIt.get<AppState>().isArabic() ? LocaleKeys.myDoctorSubtitle2 : LocaleKeys.invoiceList2,
subtitle: getIt.get<AppState>().isArabic() ? LocaleKeys.invoiceList2 : LocaleKeys.myDoctorSubtitle2,
backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor,
textColor: AppColors.blackColor,
isBold: false,
),
];
static List<ServiceCardData> get getServiceCardsList => [
ServiceCardData(
serviceName: "livecare",
icon: AppAssets.small_livecare_icon,
title: LocaleKeys.liveCare,
subtitle: LocaleKeys.liveCareServiceDesc,
largeCardIcon: AppAssets.liveCareService,
backgroundColor: AppColors.successColor,
iconColor: AppColors.whiteColor,
isBold: false,
isPNG: false
),
// ServiceCardData(
// icon: AppAssets.homeBottom,
// title: "Dermatology",
// subtitle: "Explore our app, View our services and offers",
// largeCardIcon: AppAssets.homeBottom,
// backgroundColor: AppColors.primaryRedColor,
// isBold: false,
// ),
ServiceCardData(
serviceName: "home_health_care",
icon: AppAssets.homeBottom,
title: LocaleKeys.homeHealthCare,
subtitle: LocaleKeys.homeHealthCareText,
largeCardIcon: AppAssets.homeHealthCareService,
backgroundColor: AppColors.primaryRedColor,
iconColor: AppColors.whiteColor,
isBold: false,
isPNG: false
),
ServiceCardData(
serviceName: "pharmacy",
icon: AppAssets.defaultMEP, //359846
title: LocaleKeys.hmgPharmacy,
subtitle: LocaleKeys.hmgPharmacyText,
largeCardIcon: AppAssets.pharmacyService,
backgroundColor: AppColors.pharmacyBGColor,
iconColor: null,
isBold: true,
isPNG: true
),
];
ServiceCardData(
serviceName: "livecare",
icon: AppAssets.small_livecare_icon,
title: LocaleKeys.liveCare,
subtitle: LocaleKeys.liveCareServiceDesc,
largeCardIcon: AppAssets.liveCareService,
backgroundColor: AppColors.successColor,
iconColor: AppColors.whiteColor,
isBold: false,
isPNG: false),
// ServiceCardData(
// icon: AppAssets.homeBottom,
// title: "Dermatology",
// subtitle: "Explore our app, View our services and offers",
// largeCardIcon: AppAssets.homeBottom,
// backgroundColor: AppColors.primaryRedColor,
// isBold: false,
// ),
ServiceCardData(
serviceName: "home_health_care",
icon: AppAssets.homeBottom,
title: LocaleKeys.homeHealthCare,
subtitle: LocaleKeys.homeHealthCareText,
largeCardIcon: AppAssets.homeHealthCareService,
backgroundColor: AppColors.primaryRedColor,
iconColor: AppColors.whiteColor,
isBold: false,
isPNG: false),
ServiceCardData(
serviceName: "pharmacy",
icon: AppAssets.defaultMEP,
//359846
title: LocaleKeys.hmgPharmacy,
subtitle: LocaleKeys.hmgPharmacyText,
largeCardIcon: AppAssets.pharmacyService,
backgroundColor: AppColors.pharmacyBGColor,
iconColor: null,
isBold: true,
isPNG: true),
];
}

@ -5,6 +5,7 @@ import 'dart:ui' as ui;
import 'package:clarity_flutter/clarity_flutter.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
import 'package:flutter_swiper_view/flutter_swiper_view.dart';
import 'package:get_it/get_it.dart';
@ -128,10 +129,7 @@ class _LandingPageState extends State<LandingPage> {
authVM.savePushTokenToAppState();
if (mounted) {
final user = appState.getAuthenticatedUser();
final hasUserQuickLoginData =
user != null &&
(user.mobileNumber?.isNotEmpty ?? false) &&
(user.patientIdentificationNo?.isNotEmpty ?? false);
final hasUserQuickLoginData = user != null && (user.mobileNumber?.isNotEmpty ?? false) && (user.patientIdentificationNo?.isNotEmpty ?? false);
if (hasUserQuickLoginData) {
authVM.checkLastLoginStatus(() {
@ -193,7 +191,7 @@ class _LandingPageState extends State<LandingPage> {
onSuccess: ((response) {
// Only open dialog if details are loaded AND widget is mounted
if (!mounted || appointmentRatingViewModel.appointmentDetails == null) return;
appointmentRatingViewModel.setClinicOrDoctor(false);
appointmentRatingViewModel.setTitle(LocaleKeys.rateDoctor.tr());
appointmentRatingViewModel.setSubTitle(LocaleKeys.howWasYourLastVisitWithDoctor.tr());
@ -231,6 +229,11 @@ class _LandingPageState extends State<LandingPage> {
body: Consumer<InsuranceViewModel>(builder: (context, insuranceVM, child) {
return Stack(
children: [
// Renders nothing unless a remote-config occasion theme (e.g.
// National Day) is currently active — fills the whole page,
// behind all other content below.
const OccasionBackgroundWidget(),
RefreshIndicator(
color: AppColors.primaryRedColor,
onRefresh: () async {
@ -275,7 +278,6 @@ class _LandingPageState extends State<LandingPage> {
// }
// },
// );
}
},
child: SingleChildScrollView(
@ -287,11 +289,9 @@ class _LandingPageState extends State<LandingPage> {
: kToolbarHeight + 16.h,
bottom: 24.h),
child: Column(
spacing: 16.h,
children: [
// Renders nothing (zero height) unless a remote-config
// occasion theme (e.g. National Day) is currently active.
const OccasionBannerWidget(),
Row(
spacing: 8.h,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -384,7 +384,7 @@ class _LandingPageState extends State<LandingPage> {
height: 18.h,
padding: EdgeInsets.all(2),
decoration: BoxDecoration(
color: AppColors.primaryRedColor,
color: AppColors.primaryRedColorBase,
borderRadius: BorderRadius.circular(20.r),
),
child: Text(
@ -450,6 +450,7 @@ class _LandingPageState extends State<LandingPage> {
}),
],
).paddingSymmetrical(24.h, 0.h),
SizedBox(height: 16.h),
!appState.isAuthenticated
? Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
@ -495,6 +496,7 @@ class _LandingPageState extends State<LandingPage> {
),
).paddingSymmetrical(24.w, 0.h)
: SizedBox.shrink(),
SizedBox(height: 16.h),
// Offers And Discounts Carousel - Auto-scrolling from right to left
// appState.isAuthenticated && appState.isEnabledOffersAndDiscountsCarousel
@ -725,7 +727,7 @@ class _LandingPageState extends State<LandingPage> {
// // children: [
// // AppCustomChipWidget(
// // labelText: LocaleKeys.erOnlineCheckInRequest.tr(context: context),
// // backgroundColor: AppColors.primaryRedColorBase.withValues(alpha: 0.10),
// // backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.10),
// // textColor: AppColors.primaryRedColor,
// // ),
// // Utils.buildSvgWithAssets(icon: AppAssets.appointment_checkin_icon, width: 24.h, height: 24.h, iconColor: AppColors.primaryRedColor),
@ -917,6 +919,7 @@ class _LandingPageState extends State<LandingPage> {
],
),
).paddingSymmetrical(24.h, 0.h),
SizedBox(height: 16.h),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
@ -932,6 +935,7 @@ class _LandingPageState extends State<LandingPage> {
}),
],
).paddingSymmetrical(24.w, 0.h),
SizedBox(height: 16.h),
ConstrainedBox(
constraints: BoxConstraints(maxHeight: isFoldable ? 450.h : (isTablet ? 440.h : 431.h), minHeight: 411.h),
child: ListView.separated(
@ -961,6 +965,7 @@ class _LandingPageState extends State<LandingPage> {
separatorBuilder: (BuildContext cxt, int index) => SizedBox(width: 16.w),
),
),
SizedBox(height: 16.h),
appState.isAuthenticated
? Column(
crossAxisAlignment: CrossAxisAlignment.start,
@ -1245,7 +1250,7 @@ class _LandingPageState extends State<LandingPage> {
iconColor: isVitalCall ? AppColors.primaryRedColor : AppColors.successColor,
textColor: isVitalCall ? AppColors.primaryRedColor : AppColors.successColor,
iconSize: 14.w,
backgroundColor: isVitalCall ? AppColors.primaryRedColorBase.withValues(alpha: 0.1) : AppColors.successColor.withValues(alpha: 0.1),
backgroundColor: isVitalCall ? AppColors.primaryRedColor.withValues(alpha: 0.1) : AppColors.successColor.withValues(alpha: 0.1),
labelPadding: EdgeInsetsDirectional.only(
start: 8.h,
end: -2.h,

@ -1,17 +1,23 @@
import 'dart:developer';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/occasion_theme/occasion_theme_view_model.dart';
import 'package:provider/provider.dart';
/// Renders the remotely-configured occasion imagery:
/// - `background_opacity_image`: a decorative backdrop/watermark drawn at
/// [OccasionThemeViewModel.backgroundImageOpacity].
/// - `header_image`: the occasion's main header/banner (e.g. the National
/// Day greeting banner), drawn on top at full opacity.
/// Renders the occasion's main header/banner (`header_image`, e.g. the
/// National Day greeting banner) inline at the top of the landing page's
/// scrollable content, drawn at full opacity.
///
/// Fully data-driven: when no occasion is active (the default), this widget
/// renders nothing and takes zero space — the existing layout/UI is
/// completely unaffected.
///
/// See also [OccasionBackgroundWidget], which renders the decorative
/// backdrop image as a full-page background instead of inline content.
class OccasionBannerWidget extends StatelessWidget {
const OccasionBannerWidget({super.key});
@ -19,43 +25,76 @@ class OccasionBannerWidget extends StatelessWidget {
Widget build(BuildContext context) {
return Consumer<OccasionThemeViewModel>(
builder: (context, occasionThemeVm, _) {
final backgroundImageUrl = occasionThemeVm.backgroundOpacityImage;
final headerImageUrl = occasionThemeVm.headerImage;
final hasBackgroundImage = occasionThemeVm.isOccasionActive && (backgroundImageUrl?.isNotEmpty ?? false);
final hasHeaderImage = occasionThemeVm.isOccasionActive && (headerImageUrl?.isNotEmpty ?? false);
if (!hasBackgroundImage && !hasHeaderImage) {
return const SizedBox.shrink();
if (!hasHeaderImage) {
return const SizedBox(height: 0);
}
return Stack(
alignment: Alignment.center,
children: [
if (hasBackgroundImage)
Opacity(
opacity: occasionThemeVm.backgroundImageOpacity.clamp(0.0, 1.0),
child: CachedNetworkImage(
imageUrl: backgroundImageUrl!,
width: double.infinity,
fit: BoxFit.cover,
placeholder: (_, __) => const SizedBox.shrink(),
errorWidget: (_, __, ___) => const SizedBox.shrink(),
),
),
if (hasHeaderImage)
CachedNetworkImage(
imageUrl: headerImageUrl!,
width: double.infinity,
fit: BoxFit.cover,
placeholder: (_, __) => const SizedBox.shrink(),
errorWidget: (_, __, ___) => const SizedBox.shrink(),
),
],
);
return buildOccasionImage(headerImageUrl!).paddingOnly(bottom: 16.h);
},
);
}
}
/// Renders the occasion's decorative backdrop/watermark
/// (`background_opacity_image`) as a full-page background. Place this as
/// the first child of the landing page's outer [Stack] (behind the
/// scrollable content) so it fills the whole screen and sits behind
/// everything else, drawn at [OccasionThemeViewModel.backgroundImageOpacity].
///
/// Fully data-driven: when no occasion is active (the default), this widget
/// renders nothing — the existing layout/UI is completely unaffected.
class OccasionBackgroundWidget extends StatelessWidget {
const OccasionBackgroundWidget({super.key});
@override
Widget build(BuildContext context) {
return Consumer<OccasionThemeViewModel>(
builder: (context, occasionThemeVm, _) {
final backgroundImageUrl = occasionThemeVm.backgroundOpacityImage;
final hasBackgroundImage = occasionThemeVm.isOccasionActive && (backgroundImageUrl?.isNotEmpty ?? false);
log("occasionThemeVm.backgroundImageOpacity: ${occasionThemeVm.backgroundImageOpacity}");
if (!hasBackgroundImage) {
return const SizedBox.shrink();
}
return Positioned.fill(
child: Opacity(
opacity: occasionThemeVm.backgroundImageOpacity.clamp(0.0, 1.0),
child: buildOccasionImage(backgroundImageUrl!),
),
);
},
);
}
}
/// Remote-config image URLs may point to either an SVG (e.g. the National
/// Day banner) or a raster image (PNG/JPG). [CachedNetworkImage] cannot
/// decode SVG — it silently renders nothing — so SVG URLs are routed to
/// [SvgPicture.network] instead, based on the URL's file extension.
Widget buildOccasionImage(String url) {
final isSvg = url.split('?').first.toLowerCase().endsWith('.svg');
if (isSvg) {
return SvgPicture.network(
url,
width: double.infinity,
fit: BoxFit.cover,
placeholderBuilder: (_) => const SizedBox.shrink(),
);
}
return CachedNetworkImage(
imageUrl: url,
width: double.infinity,
fit: BoxFit.cover,
placeholder: (_, __) => const SizedBox.shrink(),
errorWidget: (_, __, error) {
log('OccasionImage: failed to load $url -> $error');
return const SizedBox.shrink();
},
);
}

@ -38,7 +38,7 @@ class SmallServiceCard extends StatelessWidget {
final Color? backgroundColor;
final bool isBold;
SmallServiceCard({
const SmallServiceCard({
super.key,
this.icon = "",
this.serviceName = "",

@ -58,7 +58,7 @@ class InsuranceApprovalDetailsPage extends StatelessWidget {
? AppColors.successColor.withValues(alpha: 0.1)
: (insuranceApprovalResponseModel.approvalStatusDescption?.toLowerCase().contains('partial') == true || insuranceApprovalResponseModel.status == 8)
? AppColors.warningColorYellow.withValues(alpha: 0.1)
: AppColors.primaryRedColorBase.withValues(alpha: 0.1),
: AppColors.primaryRedColor.withValues(alpha: 0.1),
textColor: insuranceApprovalResponseModel.status == 9
? AppColors.successColor
: (insuranceApprovalResponseModel.approvalStatusDescption?.toLowerCase().contains('partial') == true || insuranceApprovalResponseModel.status == 8)

@ -37,7 +37,7 @@ class InsuranceApprovalCard extends StatelessWidget {
} else if (_isPartiallyApproved()) {
return AppColors.warningColorYellow.withValues(alpha: 0.1);
} else {
return AppColors.primaryRedColorBase.withValues(alpha: 0.1);
return AppColors.primaryRedColor.withValues(alpha: 0.1);
}
}
@ -126,7 +126,7 @@ class InsuranceApprovalCard extends StatelessWidget {
runSpacing: 4.h,
children: [
// AppCustomChipWidget(labelText: isLoading ? "Approved" : insuranceApprovalResponseModel.approvalStatusDescption!,
// backgroundColor: insuranceApprovalResponseModel.status == 9 ? AppColors.successColor.withValues(alpha: 0.1) : AppColors.primaryRedColorBase.withValues(alpha: 0.1),
// backgroundColor: insuranceApprovalResponseModel.status == 9 ? AppColors.successColor.withValues(alpha: 0.1) : AppColors.primaryRedColor.withValues(alpha: 0.1),
// textColor: insuranceApprovalResponseModel.status == 9 ? AppColors.successColor : AppColors.primaryRedColor,
// ).toShimmer2(isShow: isLoading),
AppCustomChipWidget(labelText: isLoading ? "Cardiology" : insuranceApprovalResponseModel.clinicName ?? "").toShimmer2(isShow: isLoading),

@ -69,8 +69,8 @@ class InsuranceHistory extends StatelessWidget {
CustomButton(
text: insuranceVM.patientInsuranceCardHistoryList[index].statusDescription ?? "",
onPressed: () {},
backgroundColor: AppColors.primaryRedColorBase.withOpacity(0.1),
borderColor: AppColors.primaryRedColorBase.withOpacity(0.0),
backgroundColor: AppColors.secondaryLightRedColor,
borderColor: Colors.transparent,
textColor: AppColors.primaryRedColor,
fontSize: 10,
isBold: true,

@ -117,7 +117,7 @@ class PatientInsuranceCard extends StatelessWidget {
}
},
backgroundColor: isCurrentPatientInsuranceExpired(insuranceCardDetailsModel.cardValidTo!)
? AppColors.primaryRedColorBase.withOpacity(0.1)
? AppColors.secondaryLightRedColor
: insuranceViewModel.isInsuranceActive
? AppColors.successColor.withOpacity(0.1)
: AppColors.warningColorYellow.withOpacity(0.1),

@ -47,7 +47,7 @@ class EyeMeasurementDetailsPage extends StatelessWidget {
SizedBox(height: 16.h),
CustomTabBar(
activeTextColor: AppColors.primaryRedColor,
activeBackgroundColor: AppColors.primaryRedColorBase.withValues(alpha: .1),
activeBackgroundColor: AppColors.primaryRedColor.withValues(alpha: .1),
tabs: [
CustomTabBarModel(null, LocaleKeys.classes.tr()),
CustomTabBarModel(null, LocaleKeys.contactLens.tr()),

@ -340,7 +340,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
}
},
backgroundColor: insuranceVM.isInsuranceExpired
? AppColors.primaryRedColorBase.withOpacity(0.1)
? AppColors.secondaryLightRedColor
: insuranceVM.isInsuranceActive
? AppColors.successColor.withOpacity(0.1)
: AppColors.warningColorYellow.withOpacity(0.1),

@ -34,14 +34,13 @@ class _FamilyMedicalScreenState extends State<FamilyMedicalScreen> {
super.initState();
medicalVM = context.read<MedicalFileViewModel>();
WidgetsBinding.instance.addPostFrameCallback((_) async {
if(medicalVM!.isFamilyFilesLoading) {
if (medicalVM!.isFamilyFilesLoading) {
LoaderBottomSheet.showLoader();
} else {
LoaderBottomSheet.hideLoader();
}
medicalVM?.onFamilyFileTabChange(0);
medicalVM?.getAllPendingRecordsByResponseId();
});
}
@ -71,6 +70,8 @@ class _FamilyMedicalScreenState extends State<FamilyMedicalScreen> {
medicalVM!.addFamilyFile(otpTypeEnum: OTPTypeEnum.sms);
});
},
borderColor: AppColors.primaryRedColor,
backgroundColor: AppColors.primaryRedColor,
icon: AppAssets.add_icon,
fontSize: 16.f,
borderRadius: 12.r,
@ -104,9 +105,7 @@ class _FamilyMedicalScreenState extends State<FamilyMedicalScreen> {
),
shouldRebuild: (previous, next) {
// Only rebuild if something actually changed
return previous.selectedIndex != next.selectedIndex ||
!identical(previous.patientFiles, next.patientFiles) ||
!identical(previous.pendingFiles, next.pendingFiles);
return previous.selectedIndex != next.selectedIndex || !identical(previous.patientFiles, next.patientFiles) || !identical(previous.pendingFiles, next.pendingFiles);
},
builder: (context, data, child) => getFamilyTabs(
index: data.selectedIndex,
@ -127,7 +126,6 @@ class _FamilyMedicalScreenState extends State<FamilyMedicalScreen> {
}) {
switch (index) {
case 0:
return FamilyCards(
profiles: patientFiles,
onSelect: (FamilyFileResponseModelLists profile) {

@ -165,67 +165,63 @@ class _FamilyCardsState extends State<FamilyCards> {
title: LocaleKeys.whoCanViewMyMedicalFile.tr(context: context).toText18(isBold: true),
expandedBackgroundColor: Colors.transparent,
initiallyExpanded: true,
children: [
SizedBox(height: 10.h),
manageFamily()
],
children: [SizedBox(height: 10.h), manageFamily()],
),
ExpandableListItem(title: LocaleKeys.notifications.tr(context: context).toText18(isBold: true), expandedBackgroundColor: Colors.transparent, initiallyExpanded: true, children: [
SizedBox(height: 10.h),
widget.profileViewList!.where((profile) => profile.isRequestFromMySide ?? false).isEmpty
? Utils.getNoDataWidget(context)
: ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
padding: EdgeInsets.zero,
itemCount: widget.profileViewList!.where((profile) => profile.isRequestFromMySide ?? false).length,
itemBuilder: (context, index) {
final mySideProfiles = widget.profileViewList!.where((profile) => profile.isRequestFromMySide ?? false).toList();
FamilyFileResponseModelLists profile = mySideProfiles[index];
return Container(
margin: EdgeInsets.only(bottom: 12.h),
padding: EdgeInsets.symmetric(vertical: 15.h, horizontal: 15.h),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24),
child: Opacity(
opacity: 1.0,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
AppCustomChipWidget(
labelText: profile.statusDescription ?? " N/A",
backgroundColor: profile.status == FamilyFileEnum.pending.toInt
? AppColors.alertLightColor.withValues(alpha: 0.20)
: profile.status == FamilyFileEnum.rejected.toInt
? AppColors.primaryRedColorBase.withValues(alpha: 0.20)
: profile.status == FamilyFileEnum.active.toInt
? AppColors.lightGreenColor
: AppColors.lightGrayBGColor,
textColor: profile.status == FamilyFileEnum.pending.toInt
? AppColors.alertLightColor
: profile.status == FamilyFileEnum.rejected.toInt
? AppColors.primaryRedColor
: profile.status == FamilyFileEnum.active.toInt
? AppColors.textGreenColor
: AppColors.alertColor
),
SizedBox(height: 8.h),
Wrap(alignment: WrapAlignment.start, crossAxisAlignment: WrapCrossAlignment.start, runAlignment: WrapAlignment.start, spacing: 0.h, children: [
(profile.patientName ?? "").toText14(isBold: true, isCenter: false, maxlines: 1),
(getStatusTextByRequest(FamilyFileEnum.values.firstWhere((e) => e.toInt == profile.status), profile.isRequestFromMySide ?? false))
.toText12(isCenter: false, maxLine: 1, isBold: true, color: AppColors.greyTextColor),
]),
SizedBox(height: 8.h),
AppCustomChipWidget(
labelText: "Medical File: ${profile.responseId ?? "N/A"}",
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
padding: EdgeInsets.zero,
itemCount: widget.profileViewList!.where((profile) => profile.isRequestFromMySide ?? false).length,
itemBuilder: (context, index) {
final mySideProfiles = widget.profileViewList!.where((profile) => profile.isRequestFromMySide ?? false).toList();
FamilyFileResponseModelLists profile = mySideProfiles[index];
return Container(
margin: EdgeInsets.only(bottom: 12.h),
padding: EdgeInsets.symmetric(vertical: 15.h, horizontal: 15.h),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24),
child: Opacity(
opacity: 1.0,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
AppCustomChipWidget(
labelText: profile.statusDescription ?? " N/A",
backgroundColor: profile.status == FamilyFileEnum.pending.toInt
? AppColors.alertLightColor.withValues(alpha: 0.20)
: profile.status == FamilyFileEnum.rejected.toInt
? AppColors.primaryRedColor.withValues(alpha: 0.20)
: profile.status == FamilyFileEnum.active.toInt
? AppColors.lightGreenColor
: AppColors.lightGrayBGColor,
textColor: profile.status == FamilyFileEnum.pending.toInt
? AppColors.alertLightColor
: profile.status == FamilyFileEnum.rejected.toInt
? AppColors.primaryRedColor
: profile.status == FamilyFileEnum.active.toInt
? AppColors.textGreenColor
: AppColors.alertColor),
SizedBox(height: 8.h),
Wrap(alignment: WrapAlignment.start, crossAxisAlignment: WrapCrossAlignment.start, runAlignment: WrapAlignment.start, spacing: 0.h, children: [
(profile.patientName ?? "").toText14(isBold: true, isCenter: false, maxlines: 1),
(getStatusTextByRequest(FamilyFileEnum.values.firstWhere((e) => e.toInt == profile.status), profile.isRequestFromMySide ?? false))
.toText12(isCenter: false, maxLine: 1, isBold: true, color: AppColors.greyTextColor),
]),
SizedBox(height: 8.h),
AppCustomChipWidget(
labelText: "Medical File: ${profile.responseId ?? "N/A"}",
),
],
),
),
],
),
);
},
),
);
},
),
])
],
theme: ExpandableListTheme.custom(
@ -410,7 +406,7 @@ class _FamilyCardsState extends State<FamilyCards> {
}
},
backgroundColor: insuranceVM.isInsuranceExpired
? AppColors.primaryRedColorBase.withValues(alpha: 0.1)
? AppColors.primaryRedColor.withValues(alpha: 0.1)
: insuranceVM.isInsuranceActive
? AppColors.successColor.withValues(alpha: 0.1)
: AppColors.warningColorYellow.withValues(alpha: 0.1),
@ -517,7 +513,7 @@ class _FamilyCardsState extends State<FamilyCards> {
},
text: isActive ? LocaleKeys.active.tr(context: context) : LocaleKeys.switchLogin.tr(context: context),
backgroundColor: isActive || !canSwitch ? Colors.grey.shade200 : AppColors.secondaryLightRedColor,
borderColor: isActive || !canSwitch ? Colors.grey.shade200 : AppColors.secondaryLightRedColor,
borderColor: Colors.transparent,
textColor: isActive || !canSwitch ? AppColors.greyTextColor : AppColors.primaryRedColor,
fontSize: 13.h,
icon: isActive ? AppAssets.activeCheck : AppAssets.switch_user,
@ -527,13 +523,15 @@ class _FamilyCardsState extends State<FamilyCards> {
],
),
if (widget.isShowRemoveButton) ...[
isParentUser ? Positioned(
top: 0,
right: 0,
child: Utils.buildSvgWithAssets(icon: AppAssets.deleteIcon).onPress(() {
if (!isActive) widget.onRemove(profile);
}),
) : SizedBox(),
isParentUser
? Positioned(
top: 0,
right: 0,
child: Utils.buildSvgWithAssets(icon: AppAssets.deleteIcon).onPress(() {
if (!isActive) widget.onRemove(profile);
}),
)
: SizedBox(),
],
],
),
@ -575,7 +573,7 @@ class _FamilyCardsState extends State<FamilyCards> {
backgroundColor: profile.status == FamilyFileEnum.pending.toInt
? AppColors.alertLightColor.withValues(alpha: 0.20)
: profile.status == FamilyFileEnum.rejected.toInt
? AppColors.primaryRedColorBase.withValues(alpha: 0.20)
? AppColors.primaryRedColor.withValues(alpha: 0.20)
: profile.status == FamilyFileEnum.active.toInt
? AppColors.lightGreenColor
: AppColors.lightGrayBGColor,

@ -201,8 +201,8 @@ class InvoiceListCard extends StatelessWidget {
onTap!();
}
},
backgroundColor: AppColors.primaryRedColorBase.withValues(alpha: 0.1),
borderColor: AppColors.primaryRedColorBase.withValues(alpha: 0.01),
backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.1),
borderColor: AppColors.primaryRedColor.withValues(alpha: 0.01),
textColor: AppColors.primaryRedColor,
fontSize: 14.f,
fontWeight: FontWeight.w600,
@ -223,7 +223,7 @@ class InvoiceListCard extends StatelessWidget {
// icon: AppAssets.refundIcon,
// iconColor: AppColors.caloriesCalculatorColor,
// backgroundColor: AppColors.blueColor.withValues(alpha: 0.14),
// borderColor: AppColors.primaryRedColorBase.withValues(alpha: 0.01),
// borderColor: AppColors.primaryRedColor.withValues(alpha: 0.01),
// textColor: AppColors.caloriesCalculatorColor,
// fontSize: 14.f,
// fontWeight: FontWeight.w600,

@ -57,7 +57,7 @@ class PharmacyInvoiceCard extends StatelessWidget {
// if (pharmacyInvoice.totalAmount != null)
// AppCustomChipWidget(
// labelText: '${pharmacyInvoice.totalAmount!.toStringAsFixed(2)} ${LocaleKeys.sar.tr(context: context)}',
// backgroundColor: AppColors.primaryRedColorBase.withValues(alpha: 0.1),
// backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.1),
// textColor: AppColors.primaryRedColor,
// isEnglishOnly: true,
// ),
@ -158,8 +158,8 @@ class PharmacyInvoiceCard extends StatelessWidget {
? LocaleKeys.sendEmail.tr(context: context)
: LocaleKeys.downloadInvoice.tr(context: context),
onPressed: onTap,
backgroundColor: AppColors.primaryRedColorBase.withValues(alpha: 0.1),
borderColor: AppColors.primaryRedColorBase.withValues(alpha: 0.01),
backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.1),
borderColor: AppColors.primaryRedColor.withValues(alpha: 0.01),
textColor: AppColors.primaryRedColor,
fontSize: 14.f,
fontWeight: FontWeight.w600,

@ -52,14 +52,13 @@ class ProfileSettings extends StatefulWidget {
}
class ProfileSettingsState extends State<ProfileSettings> {
final InAppReview inAppReview = InAppReview.instance;
@override
void initState() {
super.initState();
_loadPermissions();
// Load data after first frame
WidgetsBinding.instance.addPostFrameCallback((_) {
if (mounted) {
@ -434,7 +433,15 @@ class ProfileSettingsState extends State<ProfileSettings> {
if (trailingLabel.isNotEmpty)
ConstrainedBox(
constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width * 0.35),
child: isEnglishOnly ? Directionality(textDirection: ui.TextDirection.ltr, child: trailingLabel.toText14(color: AppColors.greyTextColor, isBold: true, textOverflow: TextOverflow.ellipsis, maxlines: 1, isEnglishOnly: isEnglishOnly).toShimmer2(isShow: isShowLoading)) : trailingLabel.toText14(color: AppColors.greyTextColor, isBold: true, textOverflow: TextOverflow.ellipsis, maxlines: 1, isEnglishOnly: isEnglishOnly).toShimmer2(isShow: isShowLoading),
child: isEnglishOnly
? Directionality(
textDirection: ui.TextDirection.ltr,
child: trailingLabel
.toText14(color: AppColors.greyTextColor, isBold: true, textOverflow: TextOverflow.ellipsis, maxlines: 1, isEnglishOnly: isEnglishOnly)
.toShimmer2(isShow: isShowLoading))
: trailingLabel
.toText14(color: AppColors.greyTextColor, isBold: true, textOverflow: TextOverflow.ellipsis, maxlines: 1, isEnglishOnly: isEnglishOnly)
.toShimmer2(isShow: isShowLoading),
),
switchValue != null
? Switch(
@ -452,8 +459,10 @@ class ProfileSettingsState extends State<ProfileSettings> {
);
}
Widget socialMedia(String icon, String label,
) {
Widget socialMedia(
String icon,
String label,
) {
return SizedBox(
height: 56.h,
child: Row(
@ -461,14 +470,13 @@ class ProfileSettingsState extends State<ProfileSettings> {
children: [
Utils.buildSvgWithAssets(icon: icon, iconColor: AppColors.greyTextColor),
label.toText14(isBold: true, textOverflow: TextOverflow.ellipsis, maxlines: 1).expanded,
Row(
spacing: 24.w,
children: [
Utils.buildSvgWithAssets(icon: AppAssets.x2).onPress(()=> launchUrl(Uri.parse("https://twitter.com/HMG"))),
Utils.buildSvgWithAssets(icon: AppAssets.fb).onPress(()=> launchUrl(Uri.parse("https://www.facebook.com/DrSulaimanAlHabib?ref=tn_tnmn"))),
Utils.buildSvgWithAssets(icon: AppAssets.linkedin).onPress(()=> launchUrl(Uri.parse("https://www.linkedin.com/company/drsulaiman-alhabib-medical-group"))),
Utils.buildSvgWithAssets(icon: AppAssets.youtube).onPress(()=> launchUrl(Uri.parse("https://www.youtube.com/c/DrsulaimanAlhabibHospitals"))),
Utils.buildSvgWithAssets(icon: AppAssets.x2).onPress(() => launchUrl(Uri.parse("https://twitter.com/HMG"))),
Utils.buildSvgWithAssets(icon: AppAssets.fb).onPress(() => launchUrl(Uri.parse("https://www.facebook.com/DrSulaimanAlHabib?ref=tn_tnmn"))),
Utils.buildSvgWithAssets(icon: AppAssets.linkedin).onPress(() => launchUrl(Uri.parse("https://www.linkedin.com/company/drsulaiman-alhabib-medical-group"))),
Utils.buildSvgWithAssets(icon: AppAssets.youtube).onPress(() => launchUrl(Uri.parse("https://www.youtube.com/c/DrsulaimanAlhabibHospitals"))),
],
)
],
@ -546,9 +554,7 @@ class _FamilyCardWidgetState extends State<FamilyCardWidget> {
// final isParentUser = appState.getAuthenticatedUser()?.isParentUser ?? false;
// final canSwitch = isParentUser || (!isParentUser && widget.profile.responseId == appState.getSuperUserID);
return Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 24.r, hasShadow: true, hasDenseShadow: true),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true, hasDenseShadow: true),
child: Column(
children: [
Column(
@ -607,12 +613,14 @@ class _FamilyCardWidgetState extends State<FamilyCardWidget> {
labelText: "${LocaleKeys.fileno.tr(context: context)}: ${widget.profile.responseId}",
iconSize: 12.w,
),
isActive ? AppCustomChipWidget(
icon: AppAssets.checkmark_icon,
labelText: LocaleKeys.verified.tr(context: context),
iconColor: AppColors.successColor,
labelPadding: EdgeInsetsDirectional.only(start: -6.w, end: 6.w),
) : SizedBox.shrink(),
isActive
? AppCustomChipWidget(
icon: AppAssets.checkmark_icon,
labelText: LocaleKeys.verified.tr(context: context),
iconColor: AppColors.successColor,
labelPadding: EdgeInsetsDirectional.only(start: -6.w, end: 6.w),
)
: SizedBox.shrink(),
],
),
],
@ -639,73 +647,76 @@ class _FamilyCardWidgetState extends State<FamilyCardWidget> {
),
// isActive && appState.getAuthenticatedUser()!.bloodGroup != null
// ?
isActive ? AppCustomChipWidget(
icon: AppAssets.blood_icon,
isActive
? AppCustomChipWidget(
icon: AppAssets.blood_icon,
labelPadding: EdgeInsetsDirectional.only(start: -6.w, end: 8.w),
labelText: appState.getAuthenticatedUser()!.bloodGroup ?? "N/A",
iconColor: AppColors.primaryRedColor)
: SizedBox(),
labelText: appState.getAuthenticatedUser()!.bloodGroup ?? "N/A",
iconColor: AppColors.primaryRedColor)
: SizedBox(),
Consumer<InsuranceViewModel>(builder: (context, insuranceVM, child) {
return isActive
? AppCustomChipWidget(
icon: insuranceVM.isInsuranceExpired
? AppAssets.cancel_circle_icon
: insuranceVM.isInsuranceActive
? AppAssets.insurance_active_icon
: AppAssets.alertSquare,
labelText: insuranceVM.isInsuranceExpired
? LocaleKeys.insuranceExpired.tr(context: context)
: insuranceVM.isInsuranceActive
? LocaleKeys.insuranceActive.tr(context: context)
: LocaleKeys.insuranceInActive.tr(context: context),
iconColor: insuranceVM.isInsuranceExpired
? AppColors.primaryRedColor
: insuranceVM.isInsuranceActive
? AppColors.successColor
: AppColors.warningColorYellow,
textColor: insuranceVM.isInsuranceExpired
? AppColors.primaryRedColor
: insuranceVM.isInsuranceActive
? AppColors.successColor
: AppColors.warningColorYellow,
iconSize: 12.w,
deleteIcon: insuranceVM.isInsuranceActive ? null : AppAssets.forward_chevron_icon,
deleteIconColor: insuranceVM.isInsuranceExpired
? AppColors.primaryRedColor
: insuranceVM.isInsuranceActive
? AppColors.successColor
: AppColors.warningColorYellow,
deleteIconHasColor: true,
onChipTap: () {
if (!insuranceVM.isInsuranceActive) {
insuranceVM.setIsInsuranceUpdateDetailsLoading(true);
insuranceVM.getPatientInsuranceDetailsForUpdate(appState.getAuthenticatedUser()!.patientId.toString(), appState.getAuthenticatedUser()!.patientIdentificationNo.toString());
showCommonBottomSheetWithoutHeight(context, child: PatientInsuranceCardUpdateCard(), callBackFunc: () {}, title: "", isCloseButtonVisible: false, isFullScreen: false);
// showCommonBottomSheetWithoutHeight(
// title: LocaleKeys.notice.tr(context: context),
// context,
// child: Utils.getWarningWidget(
// loadingText: LocaleKeys.insuranceInActiveContactSupport.tr(context: context),
// confirmText: LocaleKeys.contactUs.tr(context: context),
// isShowActionButtons: true,
// onCancelTap: () {
// Navigator.pop(context);
// },
// onConfirmTap: () async {
// launchUrl(Uri.parse("tel://" + "+966 92 006 6666"));
// }),
// callBackFunc: () {},
// isFullScreen: false,
// isCloseButtonVisible: true,
// );
}
},
backgroundColor: insuranceVM.isInsuranceExpired
? AppColors.primaryRedColorBase.withValues(alpha: 0.1)
: insuranceVM.isInsuranceActive
? AppColors.successColor.withValues(alpha: 0.1)
: AppColors.warningColorYellow.withValues(alpha: 0.1),
labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: insuranceVM.isInsuranceActive ? 6.w : 0.w),
? AppAssets.insurance_active_icon
: AppAssets.alertSquare,
labelText: insuranceVM.isInsuranceExpired
? LocaleKeys.insuranceExpired.tr(context: context)
: insuranceVM.isInsuranceActive
? LocaleKeys.insuranceActive.tr(context: context)
: LocaleKeys.insuranceInActive.tr(context: context),
iconColor: insuranceVM.isInsuranceExpired
? AppColors.primaryRedColor
: insuranceVM.isInsuranceActive
? AppColors.successColor
: AppColors.warningColorYellow,
textColor: insuranceVM.isInsuranceExpired
? AppColors.primaryRedColor
: insuranceVM.isInsuranceActive
? AppColors.successColor
: AppColors.warningColorYellow,
iconSize: 12.w,
deleteIcon: insuranceVM.isInsuranceActive ? null : AppAssets.forward_chevron_icon,
deleteIconColor: insuranceVM.isInsuranceExpired
? AppColors.primaryRedColor
: insuranceVM.isInsuranceActive
? AppColors.successColor
: AppColors.warningColorYellow,
deleteIconHasColor: true,
onChipTap: () {
if (!insuranceVM.isInsuranceActive) {
insuranceVM.setIsInsuranceUpdateDetailsLoading(true);
insuranceVM.getPatientInsuranceDetailsForUpdate(
appState.getAuthenticatedUser()!.patientId.toString(), appState.getAuthenticatedUser()!.patientIdentificationNo.toString());
showCommonBottomSheetWithoutHeight(context,
child: PatientInsuranceCardUpdateCard(), callBackFunc: () {}, title: "", isCloseButtonVisible: false, isFullScreen: false);
// showCommonBottomSheetWithoutHeight(
// title: LocaleKeys.notice.tr(context: context),
// context,
// child: Utils.getWarningWidget(
// loadingText: LocaleKeys.insuranceInActiveContactSupport.tr(context: context),
// confirmText: LocaleKeys.contactUs.tr(context: context),
// isShowActionButtons: true,
// onCancelTap: () {
// Navigator.pop(context);
// },
// onConfirmTap: () async {
// launchUrl(Uri.parse("tel://" + "+966 92 006 6666"));
// }),
// callBackFunc: () {},
// isFullScreen: false,
// isCloseButtonVisible: true,
// );
}
},
backgroundColor: insuranceVM.isInsuranceExpired
? AppColors.primaryRedColor.withValues(alpha: 0.1)
: insuranceVM.isInsuranceActive
? AppColors.successColor.withValues(alpha: 0.1)
: AppColors.warningColorYellow.withValues(alpha: 0.1),
labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: insuranceVM.isInsuranceActive ? 6.w : 0.w),
).toShimmer2(isShow: insuranceVM.isInsuranceLoading)
: SizedBox.shrink();
}),
@ -747,7 +758,7 @@ class _FamilyCardWidgetState extends State<FamilyCardWidget> {
height: isFoldable ? 50.h : 45.h,
fontSize: 14.f,
).paddingOnly(top: 12.h, right: 16.w, left: 16.w, bottom: 16.h);
}
}
Widget _buildNonParentUserButton(int? superUserId) {
final canSwitchBack = superUserId != null && superUserId == widget.profile.responseId;

@ -123,7 +123,7 @@ class FamilyCardWidget extends StatelessWidget {
icon = AppAssets.cancel_circle_icon;
labelText = LocaleKeys.insuranceExpired.tr(context: context);
iconColor = AppColors.primaryRedColor;
backgroundColor = AppColors.primaryRedColorBase.withValues(alpha: 0.15);
backgroundColor = AppColors.primaryRedColor.withValues(alpha: 0.15);
} else {
icon = AppAssets.insurance_active_icon;
labelText = LocaleKeys.insuranceActive.tr(context: context);

@ -173,8 +173,8 @@ class _RefundHistoryScreenState extends State<RefundHistoryScreen> {
CustomButton(
text: LocaleKeys.viewDetails.tr(context: context),
onPressed: () => Navigator.of(context).push(CustomPageRoute(page: RefundRequestDetailScreen(invoice: invoice!))),
backgroundColor: AppColors.primaryRedColorBase.withValues(alpha: 0.1),
borderColor: AppColors.primaryRedColorBase.withValues(alpha: 0.01),
backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.1),
borderColor: AppColors.primaryRedColor.withValues(alpha: 0.01),
textColor: AppColors.primaryRedColor,
fontSize: 14.f,
fontWeight: FontWeight.w600,

@ -480,7 +480,7 @@ class _OrganSelectorPageState extends State<OrganSelectorPage> with SingleTicker
backgroundColor: AppColors.secondaryLightRedColor,
textColor: AppColors.primaryRedColor,
deleteIcon: AppAssets.cancel,
deleteIconColor: AppColors.primaryRedColor,
deleteIconColor: AppColors.criticalActionColor,
deleteIconHasColor: false,
onDeleteTap: () {
viewModel.removeOrgan(organ.id);
@ -500,6 +500,7 @@ class _OrganSelectorPageState extends State<OrganSelectorPage> with SingleTicker
isDisabled: viewModel.selectedOrgans.isEmpty,
backgroundColor: AppColors.primaryRedColor,
textColor: AppColors.whiteColor,
borderColor: Colors.transparent,
),
);
}

@ -289,7 +289,7 @@ class _RiskFactorsScreenState extends State<RiskFactorsScreen> {
child: CustomButton(
text: LocaleKeys.previous.tr(context: context),
onPressed: _onPreviousPressed,
backgroundColor: AppColors.primaryRedColorBase.withValues(alpha: 0.11),
backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.11),
borderColor: Colors.transparent,
textColor: AppColors.primaryRedColor,
fontSize: 16.f,

@ -268,7 +268,7 @@ class _SuggestionsScreenState extends State<SuggestionsScreen> {
child: CustomButton(
text: LocaleKeys.previous.tr(),
onPressed: _onPreviousPressed,
backgroundColor: AppColors.primaryRedColorBase.withValues(alpha: 0.11),
backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.11),
borderColor: Colors.transparent,
textColor: AppColors.primaryRedColor,
fontSize: 16.f,

@ -360,7 +360,7 @@ class _SymptomsSelectorPageState extends State<SymptomsSelectorPage> {
child: CustomButton(
text: LocaleKeys.previous.tr(context: context),
onPressed: _onPreviousPressed,
backgroundColor: AppColors.primaryRedColorBase.withValues(alpha: 0.11),
backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.11),
borderColor: Colors.transparent,
textColor: AppColors.primaryRedColor,
fontSize: 16.f,

@ -750,7 +750,7 @@ class _TriagePageState extends State<TriagePage> {
percentage: probability.toInt(),
paddingBetween: 5.h,
color: AppColors.primaryRedColor,
backgroundColor: AppColors.primaryRedColorBase.withValues(alpha: 0.17),
backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.17),
height: 8.h,
titleWidget: RichText(
text: TextSpan(
@ -785,7 +785,7 @@ class _TriagePageState extends State<TriagePage> {
text: LocaleKeys.previous.tr(context: context),
onPressed: _onPreviousPressed,
isDisabled: viewModel.isTriageDiagnosisLoading,
backgroundColor: AppColors.primaryRedColorBase.withValues(alpha: 0.11),
backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.11),
borderColor: Colors.transparent,
textColor: AppColors.primaryRedColor,
fontSize: 16.f,

@ -148,7 +148,7 @@ class _UserInfoFlowManagerState extends State<UserInfoFlowManager> {
boxShadow: isCurrentStep && value > 0
? [
BoxShadow(
color: AppColors.primaryRedColorBase.withValues(alpha: 0.4),
color: AppColors.primaryRedColor.withValues(alpha: 0.4),
blurRadius: 8.r,
spreadRadius: 1.r,
),
@ -191,8 +191,8 @@ class _UserInfoFlowManagerState extends State<UserInfoFlowManager> {
isDisabled: !(viewModel.isCurrentUserInfoPageValid),
onPressed: () => viewModel.isCurrentUserInfoPageValid ? _onNext() : () {},
backgroundColor:
viewModel.isCurrentUserInfoPageValid ? AppColors.primaryRedColor : AppColors.primaryRedColorBase.withValues(alpha: 0.5),
borderColor: viewModel.isCurrentUserInfoPageValid ? AppColors.primaryRedColor : AppColors.primaryRedColorBase.withValues(alpha: 0.5),
viewModel.isCurrentUserInfoPageValid ? AppColors.primaryRedColor : AppColors.primaryRedColor.withValues(alpha: 0.5),
borderColor: viewModel.isCurrentUserInfoPageValid ? AppColors.primaryRedColor : AppColors.primaryRedColor.withValues(alpha: 0.5),
textColor: AppColors.whiteColor,
fontSize: 16.f,
)
@ -204,7 +204,7 @@ class _UserInfoFlowManagerState extends State<UserInfoFlowManager> {
child: CustomButton(
text: LocaleKeys.previous.tr(context: context),
onPressed: _onPrevious,
backgroundColor: AppColors.primaryRedColorBase.withValues(alpha: 0.11),
backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.11),
borderColor: Colors.transparent,
textColor: AppColors.primaryRedColor,
fontSize: 16.f,

@ -296,7 +296,7 @@ class _UserInfoSelectionScreenState extends State<UserInfoSelectionScreen> {
context.read<SymptomsCheckerViewModel>().setUserInfoPage(0, isSinglePageEdit: false);
context.navigateWithName(AppRoutes.userInfoFlowManager);
},
backgroundColor: AppColors.primaryRedColorBase.withValues(alpha: 0.11),
backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.11),
borderColor: Colors.transparent,
textColor: AppColors.primaryRedColor,
fontSize: 16.f,

@ -188,7 +188,7 @@ class _PinchZoomTutorialOverlayState extends State<PinchZoomTutorialOverlay> wit
width: 48.w,
height: 48.h,
decoration: BoxDecoration(
color: AppColors.primaryRedColorBase.withValues(alpha: 0.1),
color: AppColors.primaryRedColor.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(12.r),
),
child: Icon(

@ -121,7 +121,7 @@ class _SelectedOrgansSectionState extends State<SelectedOrgansSection> {
backgroundColor: AppColors.secondaryLightRedColor,
textColor: AppColors.primaryRedColor,
deleteIcon: AppAssets.cross_circle,
deleteIconColor: AppColors.primaryRedColor,
deleteIconColor: AppColors.criticalActionColor,
deleteIconHasColor: true,
onDeleteTap: () => widget.onRemoveOrgan(organ.id),
padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 8.h),

@ -94,7 +94,7 @@ class _TriageLevelCardState extends State<TriageLevelCard> with SingleTickerProv
switch (triageLevel) {
case 'emergency_ambulance':
case 'emergency':
return AppColors.primaryRedColorBase.withValues(alpha: 0.1);
return AppColors.primaryRedColor.withValues(alpha: 0.1);
case 'consultation_24':
case 'consultation':
return AppColors.chipColorSeekMedicalAdvice.withValues(alpha: 0.1);

@ -91,7 +91,7 @@ class SwitchCupBottomSheet extends StatelessWidget {
width: 60.w,
height: 60.w,
decoration: BoxDecoration(
color: isSelected ? AppColors.primaryRedColorBase.withOpacity(0.08) : Colors.transparent,
color: isSelected ? AppColors.secondaryLightRedColor : Colors.transparent,
borderRadius: BorderRadius.circular(12.r),
border: Border.all(
color: isSelected ? AppColors.primaryRedColor : AppColors.bgScaffoldColor,
@ -271,9 +271,9 @@ class _CustomizeCupBottomSheetState extends State<CustomizeCupBottomSheet> {
SliderTheme(
data: SliderTheme.of(context).copyWith(
activeTrackColor: AppColors.primaryRedColor,
inactiveTrackColor: AppColors.primaryRedColorBase.withOpacity(0.2),
inactiveTrackColor: AppColors.secondaryLightRedColor,
thumbColor: AppColors.primaryRedColor,
overlayColor: AppColors.primaryRedColorBase.withOpacity(0.2),
overlayColor: AppColors.secondaryLightRedColor,
trackHeight: 4.h,
thumbShape: RoundSliderThumbShape(enabledThumbRadius: 10.w),
),

@ -62,7 +62,7 @@ class _WeatherDetailsPageState extends State<WeatherDetailsPage> {
case ColorName.ORANGE:
return AppColors.warningLightColor.withValues(alpha: 0.1);
case ColorName.RED:
return AppColors.primaryRedColorBase.withValues(alpha: 0.1);
return AppColors.primaryRedColor.withValues(alpha: 0.1);
}
}
@ -120,7 +120,7 @@ class _WeatherDetailsPageState extends State<WeatherDetailsPage> {
}
// Red: Very High, At High Risk
else if (category.contains('very high') || category.contains('at high risk')) {
return AppColors.primaryRedColorBase.withValues(alpha: 0.1);
return AppColors.primaryRedColor.withValues(alpha: 0.1);
}
// Orange: Risk, High (but not "very high" or "at high risk")
else if (category.contains('risk') || category.contains('high')) {

@ -81,4 +81,3 @@ class RemoteConfigServiceImp implements RemoteConfigService {
static const String _fallbackDisabledJson = '{"key":"none","enabled":false}';
}

@ -14,20 +14,33 @@ class AppColors {
/// (e.g. National Day). Null unless an occasion theme is active.
static Color? occasionPrimaryColor;
/// Lighter/translucent (11% opacity) variant of [occasionPrimaryColor],
/// derived automatically by OccasionThemeViewModel. Null unless an
/// occasion theme is active.
static Color? occasionSecondaryColor;
static const transparent = Colors.transparent;
// ── Scaffold / Background ─────────────────────────────────────────────────
static Color get scaffoldBgColor => isDarkMode ? dark.scaffoldBgColor : const Color(0xFFF8F8F8);
static Color get bottomSheetBgColor => isDarkMode ? dark.bottomSheetBgColor : const Color(0xFFF8F8FA);
static Color get lightGreyEFColor => isDarkMode ? dark.lightGreyEFColor : const Color(0xffeaeaff);
static Color get greyF7Color => isDarkMode ? dark.greyF7Color : const Color(0xffF7F7F7);
static Color get greyInfoTextColor => isDarkMode ? dark.greyInfoTextColor : const Color(0xff777777);
static Color get lightGrayColor => isDarkMode ? dark.lightGrayColor : const Color(0xff808080);
static Color get greyTextColorLight => isDarkMode ? dark.greyTextColorLight : const Color(0xFFA2A2A2);
static Color get mainPurple => isDarkMode ? dark.mainPurple : const Color(0xFF7954F7);
// ── Core Colors ───────────────────────────────────────────────────────────
static Color get whiteColor => isDarkMode ? dark.whiteColor : const Color(0xFFffffff);
// static const Color primaryRedColor = Color(0xFFED1C2B);
/// Occasion-aware primary brand color. Resolves to the remotely-configured
/// occasion color when active (e.g. National Day green), otherwise falls
@ -36,32 +49,71 @@ class AppColors {
/// NOTE: Do NOT use this getter for `.withOpacity()/.withValues()` derived
/// (translucent) colors — use [primaryRedColorBase] for those instead, so
/// occasion theming never affects translucent overlays/backgrounds.
static Color get primaryRedColor =>
(isOccasionThemeActive && occasionPrimaryColor != null) ? occasionPrimaryColor! : primaryRedColorBase;
static Color get primaryRedColor => (isOccasionThemeActive && occasionPrimaryColor != null) ? occasionPrimaryColor! : primaryRedColorBase;
/// The original, non-themed brand red (or its dark-mode variant). Always
/// stable regardless of any active occasion theme — intended for opacity
/// derived usages (e.g. `AppColors.primaryRedColorBase.withOpacity(0.1)`).
static Color get primaryRedColorBase => isDarkMode ? dark.primaryRedColor : const Color(0xFFED1C2B);
static Color get secondaryLightRedColor => isDarkMode ? dark.secondaryLightRedColor : const Color(0xFFFEE9EA);
static Color get primaryRedColorBase => isDarkMode ? const Color(0xFFED1C2B) : const Color(0xFFED1C2B);
/// Semantic color for critical/negative actions (delete/deactivate account,
/// cancel appointment, clear/reset, emergency, etc.). Same light/dark
/// values as [primaryRedColorBase] — respects dark mode, but is never
/// affected by the active occasion/remote-config theme, so destructive
/// actions always read as "red" regardless of any occasion branding.
static Color get criticalActionColor => primaryRedColorBase;
/// Occasion-aware light/tint variant of [primaryRedColor] (e.g. chip and
/// badge backgrounds). Resolves to the remotely-configured occasion's
/// secondary color when active (e.g. National Day's light green),
/// otherwise falls back to the original dark/light tint — identical to
/// current behavior.
///
/// NOTE: Do NOT use this getter for `.withOpacity()/.withValues()` derived
/// colors — use [secondaryLightRedColorBase] for those instead, so
/// occasion theming never affects translucent overlays/backgrounds.
static Color get secondaryLightRedColor => (isOccasionThemeActive && occasionSecondaryColor != null) ? occasionSecondaryColor! : secondaryLightRedColorBase;
/// The original, non-themed light-red tint (or its dark-mode variant).
/// Always stable regardless of any active occasion theme — intended for
/// opacity derived usages.
static Color get secondaryLightRedColorBase => isDarkMode ? dark.secondaryLightRedColor : const Color(0xFFFEE9EA);
static const Color successColor = Color(0xFF18C273);
static Color get successLightBgColor => isDarkMode ? dark.successLightBgColor : const Color(0xffDDF6EA);
static Color get greyColor => isDarkMode ? dark.greyColor : const Color(0xFFEFEFF0);
static Color get chipBgColor => isDarkMode ? dark.chipBgColor : const Color(0xFFEFEFF0);
static Color get textColor => isDarkMode ? dark.textColor : const Color(0xFF2E3039);
static Color get iconColor => isDarkMode ? dark.iconColor : const Color(0xFF2E3039);
static Color get borderGrayColor => isDarkMode ? dark.borderGrayColor : const Color(0x332E3039);
static Color get textColorLight => isDarkMode ? dark.textColorLight : const Color(0xFF5E5E5E);
static Color get dividerColor => isDarkMode ? dark.dividerColor : const Color(0x40D2D2D2);
static Color get warningColorYellow => isDarkMode ? dark.warningColorYellow : const Color(0xFFF4A308);
static Color get inputLabelTextColor => isDarkMode ? dark.inputLabelTextColor : const Color(0xff898A8D);
static Color get greyTextColor => isDarkMode ? dark.greyTextColor : const Color(0xFF8F9AA3);
static Color get lightGrayBGColor => isDarkMode ? dark.lightGrayBGColor : const Color(0x142E3039);
static Color get checkBoxBorderColor => isDarkMode ? dark.checkBoxBorderColor : const Color(0xffD2D2D2);
static Color get pharmacyBGColor => isDarkMode ? dark.pharmacyBGColor : const Color(0xFF359846);
static Color get lightGreenColor => isDarkMode ? dark.lightGreenColor : const Color(0xFF0ccedde);
static Color get ratingColorYellow => isDarkMode ? dark.ratingColorYellow : const Color(0xFFFFAF15);
static Color get spacerLineColor => isDarkMode ? dark.spacerLineColor : const Color(0x2E30391A);
static Color get habibPharmacyColor => const Color(0xFF2d9137);
// ── Doctor Rating Colors ──────────────────────────────────────────────────
@ -74,92 +126,147 @@ class AppColors {
static const Color ratingBadgeFiveStarColor = Color(0xFF5BBD8E); // Green badge for ≥4.0
static const Color ratingPercentageTextColor = Color(0xFF4A4A4A); // Dark grey for percentage text
// ── Semantic / Status Colors ──────────────────────────────────────────────
static Color get errorColor => isDarkMode ? dark.errorColor : const Color(0xFFED1C2B);
static Color get alertColor => isDarkMode ? dark.alertColor : const Color(0xFFD48D05);
static Color get infoColor => isDarkMode ? dark.infoColor : const Color(0xFF0B85F7);
static Color get warningColor => isDarkMode ? dark.warningColor : const Color(0xFFFFCC00);
static Color get switchBackgroundColor => isDarkMode ? dark.switchBackgroundColor : const Color(0x2618C273);
static Color get bottomNAVBorder => isDarkMode ? dark.bottomNAVBorder : const Color(0xFFEEEEEE);
static Color get quickLoginColor => isDarkMode ? dark.quickLoginColor : const Color(0xFF666666);
static Color get tooltipTextColor => isDarkMode ? dark.tooltipTextColor : const Color(0xFF414D55);
static Color get graphGridColor => isDarkMode ? dark.graphGridColor : const Color(0x4D18C273);
static Color get highAndLow => isDarkMode ? dark.highAndLow : const Color(0xFFFFAF15);
static Color get labelTextColor => isDarkMode ? dark.labelTextColor : const Color(0xFF838383);
static Color get calenderTextColor => isDarkMode ? dark.calenderTextColor : const Color(0xFFD0D0D0);
static Color get lightGreenButtonColor => isDarkMode ? dark.lightGreenButtonColor : const Color(0x2618C273);
static Color get lightRedButtonColor => isDarkMode ? dark.lightRedButtonColor : const Color(0x1AED1C2B);
// ── Status Colors ─────────────────────────────────────────────────────────
static Color get statusPendingColor => isDarkMode ? dark.statusPendingColor : const Color(0xffCC9B14);
static Color get statusProcessingColor => isDarkMode ? dark.statusProcessingColor : const Color(0xff2E303A);
static Color get statusCompletedColor => isDarkMode ? dark.statusCompletedColor : const Color(0xff359846);
static Color get statusRejectedColor => isDarkMode ? dark.statusRejectedColor : const Color(0xffD02127);
// ── Info Banner Colors ────────────────────────────────────────────────────
static Color get infoBannerBgColor => isDarkMode ? dark.infoBannerBgColor : const Color(0xFFFFF4E6);
static Color get infoBannerBorderColor => isDarkMode ? dark.infoBannerBorderColor : const Color(0xFFFFE5B4);
static Color get infoBannerIconColor => isDarkMode ? dark.infoBannerIconColor : const Color(0xFFCC9B14);
static Color get infoBannerTextColor => isDarkMode ? dark.infoBannerTextColor : const Color(0xFF856404);
// ── Symptoms Checker ─────────────────────────────────────────────<EFBFBD><EFBFBD>────────
static Color get chipColorSeekMedicalAdvice => isDarkMode ? dark.chipColorSeekMedicalAdvice : const Color(0xFFFFAF15);
static Color get chipTextColorSeekMedicalAdvice => isDarkMode ? dark.chipTextColorSeekMedicalAdvice : const Color(0xFFD48D05);
// ── Services Page Colors ──────────────────────────────────────────────────
static Color get eReferralCardColor => isDarkMode ? dark.eReferralCardColor : const Color(0xFFFF8012);
static Color get bloodDonationCardColor => isDarkMode ? dark.bloodDonationCardColor : const Color(0xFFFF5662);
static Color get myChildVaccineCardColor => isDarkMode ? dark.myChildVaccineCardColor : const Color(0xFFFF2D78);
static Color get bookAppointment => isDarkMode ? dark.bookAppointment : const Color(0xFF415364);
// ── Health Calculators Colors ─────────────────────────────────────────────
static Color get bmiCalculatorColor => isDarkMode ? dark.bmiCalculatorColor : const Color(0xFFF43333);
static Color get caloriesCalculatorColor => isDarkMode ? dark.caloriesCalculatorColor : const Color(0xFF0B85F7);
static Color get bmrCalculatorColor => isDarkMode ? dark.bmrCalculatorColor : const Color(0xFF18C273);
static Color get idealBodyWeightColor => isDarkMode ? dark.idealBodyWeightColor : const Color(0xFFFF8012);
static Color get bodyFatCalculatorColor => isDarkMode ? dark.bodyFatCalculatorColor : const Color(0xFFFF5662);
static Color get carbsProteinFatColor => isDarkMode ? dark.carbsProteinFatColor : const Color(0xFF18C273);
static Color get ovulationPeriodColor => isDarkMode ? dark.ovulationPeriodColor : const Color(0xFFFF47A9);
static Color get deliveryDueDateColor => isDarkMode ? dark.deliveryDueDateColor : const Color(0xFFFF2D78);
// ── Water Monitor ─────────────────────────────────────────────────────────
static Color get blueColor => isDarkMode ? dark.blueColor : const Color(0xFF4EB5FF);
static Color get blueGradientColorOne => isDarkMode ? dark.blueGradientColorOne : const Color(0xFFF1F7FD);
static Color get blueGradientColorTwo => isDarkMode ? dark.blueGradientColorTwo : const Color(0xFFD9EFFF);
// ── Shimmer ───────────────────────────────────────────────────────────────
static Color get shimmerBaseColor => isDarkMode ? dark.shimmerBaseColor : const Color(0xFFE0E0E0);
static Color get shimmerHighlightColor => isDarkMode ? dark.shimmerHighlightColor : const Color(0xFFF5F5F5);
static Color get covid29Color => isDarkMode ? dark.covid29Color : const Color(0xff2563EB);
static Color get lightGreyTextColor => isDarkMode ? dark.lightGreyTextColor : const Color(0xFF959595);
static Color get labelColorYellow => isDarkMode ? dark.labelColorYellow : const Color(0xFFFBCB6E);
static const LinearGradient aiLinearGradient =
LinearGradient(colors: [Color(0xFF8A38F5), Color(0xFFE20BBB)], begin: Alignment.topLeft, end: Alignment.bottomRight);
static const LinearGradient aiLinearGradient = LinearGradient(colors: [Color(0xFF8A38F5), Color(0xFFE20BBB)], begin: Alignment.topLeft, end: Alignment.bottomRight);
// ── Aliases ───────────────────────────────────────────────────────────────
static Color get bgScaffoldColor => scaffoldBgColor;
static Color get primaryRedBorderColor => primaryRedColor;
static Color get chipPrimaryRedBorderColor => primaryRedColor;
static Color get criticalLowAndHigh => primaryRedColor;
static Color get chipColorEmergency => primaryRedColor;
static Color get errorLightColor => primaryRedColor;
static Color get secondaryLightRedBorderColor => secondaryLightRedColor;
static Color get bgRedLightColor => secondaryLightRedColor;
static Color get chipSecondaryLightRedColor => secondaryLightRedColor;
static Color get blackBgColor => textColor;
static Color get blackColor => textColor;
static Color get borderOnlyColor => textColor;
static Color get chipBorderColorOpacity20 => borderGrayColor;
static Color get bgGreenColor => successColor;
static Color get textGreenColor => successColor;
static Color get successLightColor => successColor;
static Color get thumbColor => successColor;
static Color get chipColorMonitor => successColor;
static Color get greyLightColor => greyColor;
static Color get alertLightColor => alertColor;
static Color get infoLightColor => infoColor;
static Color get warningLightColor => warningColor;
// ── Dark Mode Palette ─────────────────────────────────────────────────────
@ -174,11 +281,17 @@ class AppColorsDark {
// Scaffold / Background
Color get scaffoldBgColor => const Color(0xFF191919);
Color get bottomSheetBgColor => const Color(0xFF1C1C1E);
Color get lightGreyEFColor => const Color(0xFF2A2A3A);
Color get greyF7Color => const Color(0xFF1E1E1E);
Color get greyInfoTextColor => const Color(0xFF9E9E9E);
Color get lightGrayColor => const Color(0xFF9E9E9E);
Color get greyTextColorLight => const Color(0xFF757575);
// ⚠️ NEW — was missing from AppColorsDark
@ -186,114 +299,192 @@ class AppColorsDark {
// Core
Color get baseColor => const Color(0xFF1E1E1E);
// ⚠️ NEW — maps whiteColor → dark surface color
Color get whiteColor => const Color(0xFF1E1E1E); // surface replacement for white
Color get primaryRedColor => const Color(0xFFDE5C5D);
Color get secondaryLightRedColor => const Color(0xFF3A1015);
Color get successColor => const Color(0xFF18C273);
Color get successLightBgColor => const Color(0xFF0D2E1F);
Color get textColor => const Color(0xFFFFFFFF);
Color get iconColor => const Color(0xFFFFFFFF);
Color get borderGrayColor => const Color(0x55ECECEC);
Color get textColorLight => const Color(0xFFB0B0B0);
Color get dividerColor => const Color(0x33FFFFFF);
Color get warningColorYellow => const Color(0xFFF4A308);
Color get inputLabelTextColor => const Color(0xFF9E9E9E);
Color get greyTextColor => const Color(0xFF8F9AA3);
Color get lightGrayBGColor => const Color(0x22FFFFFF);
Color get checkBoxBorderColor => const Color(0xFF555555);
Color get pharmacyBGColor => const Color(0xFF359846);
// ⚠️ NEW — was missing from AppColorsDark
Color get lightGreenColor => const Color(0xFF0ccedde); // same teal accent — works on dark
Color get ratingColorYellow => const Color(0xFFFFAF15);
Color get spacerLineColor => const Color(0x22FFFFFF);
// Semantic / Status
Color get errorColor => const Color(0xFFD63D48);
Color get alertColor => const Color(0xFFD48D05);
Color get infoColor => const Color(0xFF4DA6FF);
Color get warningColor => const Color(0xFFFFCC00);
Color get greyColor => const Color(0xFF2C2C2E);
Color get chipBgColor => const Color(0xFF3E3E3E);
Color get cardDarkBorderColor => const Color(0x0DEAEAEA);
Color get serviceCardButtonColor => const Color(0xFF3E3E3E);
Color get switchBackgroundColor => const Color(0x2618C273);
Color get bottomNAVBorder => const Color(0xFF2C2C2E);
Color get quickLoginColor => const Color(0xFF9E9E9E);
Color get tooltipTextColor => const Color(0xFFCFD8DC);
Color get graphGridColor => const Color(0x4D18C273);
Color get highAndLow => const Color(0xFFFFAF15);
Color get labelTextColor => const Color(0xFF9E9E9E);
Color get calenderTextColor => const Color(0xFF555555);
Color get lightGreenButtonColor => const Color(0x2618C273);
Color get lightRedButtonColor => const Color(0x1AED1C2B);
// Status
Color get statusPendingColor => const Color(0xFFCC9B14);
Color get statusProcessingColor => const Color(0xFFECECEC);
Color get statusCompletedColor => const Color(0xFF359846);
Color get statusRejectedColor => const Color(0xFFD02127);
// Info Banner
Color get infoBannerBgColor => const Color(0xFF2A1F0A);
Color get infoBannerBorderColor => const Color(0xFF5A3D0A);
Color get infoBannerIconColor => const Color(0xFFCC9B14);
Color get infoBannerTextColor => const Color(0xFFFFCB6B);
// Symptoms Checker
Color get chipColorSeekMedicalAdvice => const Color(0xFFFFAF15);
Color get chipTextColorSeekMedicalAdvice => const Color(0xFFD48D05);
// Services Page
Color get eReferralCardColor => const Color(0xFFFF8012);
Color get bloodDonationCardColor => const Color(0xFFFF5662);
Color get myChildVaccineCardColor => const Color(0xFFFF2D78);
Color get bookAppointment => const Color(0xFF415364);
// Health Calculators
Color get bmiCalculatorColor => const Color(0xFFF43333);
Color get caloriesCalculatorColor => const Color(0xFF0B85F7);
Color get bmrCalculatorColor => const Color(0xFF18C273);
Color get idealBodyWeightColor => const Color(0xFFFF8012);
Color get bodyFatCalculatorColor => const Color(0xFFFF5662);
Color get carbsProteinFatColor => const Color(0xFF18C273);
Color get ovulationPeriodColor => const Color(0xFFFF47A9);
Color get deliveryDueDateColor => const Color(0xFFFF2D78);
// Water Monitor
Color get blueColor => const Color(0xFF4EB5FF);
Color get blueGradientColorOne => const Color(0xFF101C2A);
Color get blueGradientColorTwo => const Color(0xFF0D2235);
// Shimmer
Color get shimmerBaseColor => const Color(0xFF2C2C2C);
Color get shimmerHighlightColor => const Color(0xFF3D3D3D);
Color get covid29Color => const Color(0xFF2563EB);
Color get lightGreyTextColor => const Color(0xFF757575);
Color get labelColorYellow => const Color(0xFFFBCB6E);
// Aliases
Color get bgScaffoldColor => scaffoldBgColor;
Color get primaryRedBorderColor => primaryRedColor;
Color get chipPrimaryRedBorderColor => primaryRedColor;
Color get criticalLowAndHigh => primaryRedColor;
Color get chipColorEmergency => primaryRedColor;
Color get errorLightColor => primaryRedColor;
Color get secondaryLightRedBorderColor => secondaryLightRedColor;
Color get bgRedLightColor => secondaryLightRedColor;
Color get chipSecondaryLightRedColor => secondaryLightRedColor;
Color get blackBgColor => textColor;
Color get blackColor => textColor;
Color get borderOnlyColor => textColor;
Color get chipBorderColorOpacity20 => borderGrayColor;
Color get bgGreenColor => successColor;
Color get textGreenColor => successColor;
Color get successLightColor => successColor;
Color get thumbColor => successColor;
Color get chipColorMonitor => successColor;
Color get greyLightColor => greyColor;
Color get alertLightColor => alertColor;
Color get infoLightColor => infoColor;
Color get warningLightColor => warningColor;
}
@ -305,61 +496,99 @@ extension AppColorsContext on BuildContext {
// Scaffold / Background
Color get scaffoldBgColor => _isDark ? AppColors.dark.scaffoldBgColor : const Color(0xFFF8F8F8);
Color get bottomSheetBgColor => _isDark ? AppColors.dark.bottomSheetBgColor : const Color(0xFFF8F8FA);
Color get greyF7Color => _isDark ? AppColors.dark.greyF7Color : const Color(0xffF7F7F7);
Color get greyInfoTextColor => _isDark ? AppColors.dark.greyInfoTextColor : const Color(0xff777777);
Color get lightGrayColor => _isDark ? AppColors.dark.lightGrayColor : const Color(0xff808080);
// Core
Color get cardBaseColor => _isDark ? AppColors.dark.baseColor : const Color(0xFFFFFFFF);
Color get primaryRedColor => _isDark ? AppColors.dark.primaryRedColor : AppColors.primaryRedColor;
Color get secondaryLightRedColor => _isDark ? AppColors.dark.serviceCardButtonColor : const Color(0xFFFEE9EA);
Color get secondaryLightRedForegroundColor => _isDark ? const Color(0xFFFFFFFF) : AppColors.primaryRedColor;
Color get successColor => AppColors.successColor;
Color get successLightBgColor => _isDark ? AppColors.dark.successLightBgColor : const Color(0xffDDF6EA);
Color get textColor => _isDark ? AppColors.dark.textColor : const Color(0xFF2E3039);
Color get iconColor => _isDark ? AppColors.dark.iconColor : const Color(0xFF2E3039);
Color get borderGrayColor => _isDark ? AppColors.dark.borderGrayColor : const Color(0x332E3039);
Color get textColorLight => _isDark ? AppColors.dark.textColorLight : const Color(0xFF5E5E5E);
Color get dividerColor => _isDark ? AppColors.dark.dividerColor : const Color(0x40D2D2D2);
Color get inputLabelTextColor => _isDark ? AppColors.dark.inputLabelTextColor : const Color(0xff898A8D);
Color get greyTextColor => AppColors.greyTextColor;
Color get lightGrayBGColor => _isDark ? AppColors.dark.lightGrayBGColor : const Color(0x142E3039);
Color get checkBoxBorderColor => _isDark ? AppColors.dark.checkBoxBorderColor : const Color(0xffD2D2D2);
// Status / Semantic
Color get errorColor => _isDark ? AppColors.dark.errorColor : const Color(0xFFED1C2B);
Color get alertColor => AppColors.alertColor;
Color get infoColor => _isDark ? AppColors.dark.infoColor : const Color(0xFF0B85F7);
Color get warningColor => AppColors.warningColor;
Color get greyColor => _isDark ? AppColors.dark.greyColor : const Color(0xFFEFEFF0);
Color get chipBgColor => _isDark ? AppColors.dark.chipBgColor : const Color(0xFFEFEFF0);
Color get cardDarkBorderColor => _isDark ? AppColors.dark.cardDarkBorderColor : Colors.transparent;
Color get serviceCardButtonColor => _isDark ? AppColors.dark.serviceCardButtonColor : const Color(0xFF2E3039);
Color get bottomNAVBorder => _isDark ? AppColors.dark.bottomNAVBorder : const Color(0xFFEEEEEE);
Color get labelTextColor => _isDark ? AppColors.dark.labelTextColor : const Color(0xFF838383);
Color get lightGreyTextColor => _isDark ? AppColors.dark.lightGreyTextColor : const Color(0xFF959595);
// Info Banner
Color get infoBannerBgColor => _isDark ? AppColors.dark.infoBannerBgColor : const Color(0xFFFFF4E6);
Color get infoBannerBorderColor => _isDark ? AppColors.dark.infoBannerBorderColor : const Color(0xFFFFE5B4);
Color get infoBannerIconColor => AppColors.infoBannerIconColor;
Color get infoBannerTextColor => _isDark ? AppColors.dark.infoBannerTextColor : const Color(0xFF856404);
// Water Monitor
Color get blueColor => AppColors.blueColor;
Color get blueGradientColorOne => _isDark ? AppColors.dark.blueGradientColorOne : const Color(0xFFF1F7FD);
Color get blueGradientColorTwo => _isDark ? AppColors.dark.blueGradientColorTwo : const Color(0xFFD9EFFF);
// Shimmer
Color get shimmerBaseColor => _isDark ? AppColors.dark.shimmerBaseColor : const Color(0xFFE0E0E0);
Color get shimmerHighlightColor => _isDark ? AppColors.dark.shimmerHighlightColor : const Color(0xFFF5F5F5);
static const Color tooltipColor = Color(0xFF1AACACAC);
// Aliases
Color get bgScaffoldColor => scaffoldBgColor;
Color get bgGreenColor => successColor;
Color get bgRedLightColor => secondaryLightRedColor;
Color get blackColor => textColor;
Color get blackBgColor => textColor;
}

@ -115,8 +115,7 @@ class CollapsingListView extends StatelessWidget {
margin: EdgeInsets.fromLTRB(24.w, 0, 24.w, 0),
child: Transform.flip(
flipX: appState.isArabic(),
child: Utils.buildSvgWithAssets(
icon: isClose ? AppAssets.close_bottom_nav_trans : AppAssets.arrow_back_new, width: 24.h, height: 24.h),
child: Utils.buildSvgWithAssets(icon: isClose ? AppAssets.close_bottom_nav_trans : AppAssets.arrow_back_new, width: 24.h, height: 24.h),
),
).onPress(() {
if (leadingCallback != null) {
@ -289,8 +288,7 @@ class _ScrollAnimatedTitleState extends State<ScrollAnimatedTitle> {
return Container(
// height: (widget.preferredSize.height - _fontSize / 2).h,
height: 56.h,
alignment:
isRtl ? (widget.showBack ? Alignment.topRight : Alignment.centerRight) : (widget.showBack ? Alignment.topLeft : Alignment.centerLeft),
alignment: isRtl ? (widget.showBack ? Alignment.topRight : Alignment.centerRight) : (widget.showBack ? Alignment.topLeft : Alignment.centerLeft),
padding: EdgeInsets.fromLTRB(24.w, 0, 24.w, 0),
child: Row(
spacing: 4.h,
@ -306,38 +304,19 @@ class _ScrollAnimatedTitleState extends State<ScrollAnimatedTitle> {
),
).expanded,
...[
if (widget.logout != null)
actionButton(context, t, title: LocaleKeys.logout.tr(context: context), icon: AppAssets.logout).onPress(widget.logout!),
if (widget.report != null)
actionButton(context, t, title: LocaleKeys.feedback.tr(context: context), icon: AppAssets.report_icon).onPress(widget.report!),
if (widget.history != null)
actionButton(context, t, title: LocaleKeys.history.tr(context: context), icon: AppAssets.insurance_history_icon)
.onPress(widget.history!),
if (widget.instructions != null)
actionButton(context, t, title: LocaleKeys.instructions.tr(context: context), icon: AppAssets.requests).onPress(widget.instructions!),
if (widget.requests != null)
actionButton(context, t, title: LocaleKeys.requests.tr(context: context), icon: AppAssets.insurance_history_icon)
.onPress(widget.requests!),
if (widget.sendEmail != null)
actionButton(context, t, title: LocaleKeys.sendEmail.tr(context: context), icon: AppAssets.email).onPress(widget.sendEmail!),
if (widget.doctorResponse != null)
actionButton(context, t, title: LocaleKeys.doctorResponses.tr(context: context), icon: AppAssets.doctorResponseIcon)
.onPress(widget.doctorResponse!),
if (widget.logout != null) actionButton(context, t, title: LocaleKeys.logout.tr(context: context), icon: AppAssets.logout).onPress(widget.logout!),
if (widget.report != null) actionButton(context, t, title: LocaleKeys.feedback.tr(context: context), icon: AppAssets.report_icon).onPress(widget.report!),
if (widget.history != null) actionButton(context, t, title: LocaleKeys.history.tr(context: context), icon: AppAssets.insurance_history_icon).onPress(widget.history!),
if (widget.instructions != null) actionButton(context, t, title: LocaleKeys.instructions.tr(context: context), icon: AppAssets.requests).onPress(widget.instructions!),
if (widget.requests != null) actionButton(context, t, title: LocaleKeys.requests.tr(context: context), icon: AppAssets.insurance_history_icon).onPress(widget.requests!),
if (widget.sendEmail != null) actionButton(context, t, title: LocaleKeys.sendEmail.tr(context: context), icon: AppAssets.email).onPress(widget.sendEmail!),
if (widget.doctorResponse != null) actionButton(context, t, title: LocaleKeys.doctorResponses.tr(context: context), icon: AppAssets.doctorResponseIcon).onPress(widget.doctorResponse!),
if (widget.search != null) Utils.buildSvgWithAssets(icon: AppAssets.search_icon).onPress(widget.search!),
if (widget.aiOverview != null)
actionButton(context, t, title: LocaleKeys.aiOverView.tr(context: context), icon: AppAssets.aiOverView, isAiButton: true)
.onPress(widget.aiOverview!),
if (widget.downloadReport != null)
actionButton(context, t, title: LocaleKeys.downloadReport.tr(context: context), icon: AppAssets.download)
.onPress(widget.downloadReport!),
if (widget.viewImage != null)
actionButton(context, t, title: LocaleKeys.viewRadiologyImage.tr(context: context), icon: AppAssets.download)
.onPress(widget.viewImage!),
if (widget.location != null)
actionButton(context, t, title: LocaleKeys.sortByLocation.tr(context: context), icon: AppAssets.location).onPress(widget.location!),
if (widget.downloadInvoice != null)
actionButton(context, t, title: LocaleKeys.downloadInvoice.tr(context: context), icon: AppAssets.download)
.onPress(widget.downloadInvoice!),
if (widget.aiOverview != null) actionButton(context, t, title: LocaleKeys.aiOverView.tr(context: context), icon: AppAssets.aiOverView, isAiButton: true).onPress(widget.aiOverview!),
if (widget.downloadReport != null) actionButton(context, t, title: LocaleKeys.downloadReport.tr(context: context), icon: AppAssets.download).onPress(widget.downloadReport!),
if (widget.viewImage != null) actionButton(context, t, title: LocaleKeys.viewRadiologyImage.tr(context: context), icon: AppAssets.download).onPress(widget.viewImage!),
if (widget.location != null) actionButton(context, t, title: LocaleKeys.sortByLocation.tr(context: context), icon: AppAssets.location).onPress(widget.location!),
if (widget.downloadInvoice != null) actionButton(context, t, title: LocaleKeys.downloadInvoice.tr(context: context), icon: AppAssets.download).onPress(widget.downloadInvoice!),
if (widget.trailing != null) widget.trailing!,
]
],
@ -353,8 +332,7 @@ class _ScrollAnimatedTitleState extends State<ScrollAnimatedTitle> {
child: Container(
height: isFoldable ? 50.h : 40.h,
padding: EdgeInsets.all(8.w),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor, borderRadius: 8.r, side: BorderSide(width: 1, color: AppColors.borderGrayColor)),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 8.r, side: BorderSide(width: 1, color: AppColors.borderGrayColor)),
child: ShaderMask(
blendMode: BlendMode.srcIn,
shaderCallback: (bounds) => AppColors.aiLinearGradient.createShader(bounds),

@ -163,7 +163,7 @@ class _DateRangeSelectorState extends State<DateRangeSelector> {
),
startRangeSelectionColor: AppColors.primaryRedColor,
endRangeSelectionColor: AppColors.primaryRedColor,
rangeSelectionColor: AppColors.primaryRedColorBase.withOpacity(0.1),
rangeSelectionColor: AppColors.secondaryLightRedColor,
rangeTextStyle: TextStyle(
fontFamily: "Poppins",
),
@ -963,7 +963,7 @@ class _DateRangeSelectorState extends State<DateRangeSelector> {
children: [
AppCustomChipWidget(
labelText: LocaleKeys.thisWeek.tr(context: context),
backgroundColor: model.currentlySelectedRange == Range.WEEKLY ? AppColors.primaryRedColorBase.withOpacity(0.1) : AppColors.whiteColor,
backgroundColor: model.currentlySelectedRange == Range.WEEKLY ? AppColors.secondaryLightRedColor : AppColors.whiteColor,
shape: RoundedRectangleBorder(
side: BorderSide(
color: model.currentlySelectedRange == Range.WEEKLY ? AppColors.primaryRedBorderColor : AppColors.chipBorderColorOpacity20,
@ -977,7 +977,7 @@ class _DateRangeSelectorState extends State<DateRangeSelector> {
}),
AppCustomChipWidget(
labelText: LocaleKeys.lastMonth.tr(context: context),
backgroundColor: model.currentlySelectedRange == Range.LAST_MONTH ? AppColors.primaryRedColorBase.withOpacity(0.1) : AppColors.whiteColor,
backgroundColor: model.currentlySelectedRange == Range.LAST_MONTH ? AppColors.secondaryLightRedColor : AppColors.whiteColor,
shape: RoundedRectangleBorder(
side: BorderSide(
color: model.currentlySelectedRange == Range.LAST_MONTH ? AppColors.primaryRedBorderColor : AppColors.chipBorderColorOpacity20,
@ -991,7 +991,7 @@ class _DateRangeSelectorState extends State<DateRangeSelector> {
}),
AppCustomChipWidget(
labelText: LocaleKeys.lastSixMonths.tr(context: context),
backgroundColor: model.currentlySelectedRange == Range.LAST_6MONTH ? AppColors.primaryRedColorBase.withOpacity(0.1) : AppColors.whiteColor,
backgroundColor: model.currentlySelectedRange == Range.LAST_6MONTH ? AppColors.secondaryLightRedColor : AppColors.whiteColor,
shape: RoundedRectangleBorder(
side: BorderSide(
color: model.currentlySelectedRange == Range.LAST_6MONTH ? AppColors.primaryRedBorderColor : AppColors.chipBorderColorOpacity20,
@ -1012,7 +1012,7 @@ class _DateRangeSelectorState extends State<DateRangeSelector> {
],
),
labelText: "${LocaleKeys.year.tr(context: context)} ${model.getCurrentYear}",
backgroundColor: model.currentlySelectedRange == Range.THIS_YEAR ? AppColors.primaryRedColorBase.withOpacity(0.1) : AppColors.whiteColor,
backgroundColor: model.currentlySelectedRange == Range.THIS_YEAR ? AppColors.secondaryLightRedColor : AppColors.whiteColor,
shape: RoundedRectangleBorder(
side: BorderSide(
color: model.currentlySelectedRange == Range.THIS_YEAR ? AppColors.primaryRedBorderColor : AppColors.chipBorderColorOpacity20,

@ -56,21 +56,22 @@ class _LanguageSelectorState extends State<LanguageSelector> {
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
// currentLangData['name']?.toUpperCase() ?? 'EN',
widget.currentLanguage == 'ar' ? "ENGLISH" : "العربية",
style: context.dynamicTextStyle(
fontWeight: FontWeight.w600,
fontSize: 14.f,
color: AppColors.primaryRedColor,
letterSpacing: 0.1,
isLanguageSwitcher: true,
fontSize: 14.f,
color: AppColors.primaryRedColor,
letterSpacing: 0.1,
isLanguageSwitcher: true,
fontFamily: widget.currentLanguage == 'ar' ? "Poppins" : "CairoArabic"),
),
SizedBox(width: 6.h),
Utils.buildSvgWithAssets(icon: AppAssets.language),
Utils.buildSvgWithAssets(
icon: AppAssets.language,
iconColor: AppColors.primaryRedColor,
),
],
),
),

@ -220,7 +220,7 @@ class _MapTypeItem extends StatelessWidget {
padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 8.h),
decoration: BoxDecoration(
color: isSelected
? AppColors.primaryRedColorBase.withOpacity(0.1)
? AppColors.secondaryLightRedColor
: Colors.transparent,
borderRadius: BorderRadius.circular(8.r),
),

@ -372,7 +372,7 @@ class _MapTypeItem extends StatelessWidget {
padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 8.h),
decoration: BoxDecoration(
color: isSelected
? AppColors.primaryRedColorBase.withOpacity(0.1)
? AppColors.secondaryLightRedColor
: Colors.transparent,
borderRadius: BorderRadius.circular(8.r),
),

@ -486,6 +486,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.10.10"
firebase_remote_config:
dependency: "direct main"
description:
name: firebase_remote_config
sha256: e1635b1e8713f4a823920ec3a56a14034b90ce455d47746ab0da994857f370cf
url: "https://pub.dev"
source: hosted
version: "5.5.0"
firebase_remote_config_platform_interface:
dependency: transitive
description:
name: firebase_remote_config_platform_interface
sha256: ce836c5c62056edbe23ef501e6876691ee32476afd12fe95b76e57bba9d25485
url: "https://pub.dev"
source: hosted
version: "2.0.0"
firebase_remote_config_web:
dependency: transitive
description:
name: firebase_remote_config_web
sha256: "9dbd75024bfcd47c05046c95f9cf648a8fc862b096bcf8ea1e4b855d50ea19ad"
url: "https://pub.dev"
source: hosted
version: "1.8.9"
fixnum:
dependency: transitive
description:
@ -797,10 +821,10 @@ packages:
dependency: "direct main"
description:
name: flutter_zoom_videosdk
sha256: "46a4dea664b1c969099328a499c198a1755adf9ac333dea28bea5187910b3bf9"
sha256: "87caad07b994f09b9d8c4b8054c0dff5659029abae38dd6ec223460c3f1bcb7d"
url: "https://pub.dev"
source: hosted
version: "2.1.10"
version: "2.5.10"
fluttertoast:
dependency: "direct main"
description:
@ -809,6 +833,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "8.2.14"
freerasp:
dependency: "direct main"
description:
name: freerasp
sha256: a3d019fa2c1a8f4bb15504d86997f583d1066fe0832172fd68ea6cd521e6fdcc
url: "https://pub.dev"
source: hosted
version: "8.2.2"
fwfh_cached_network_image:
dependency: transitive
description:
@ -1657,6 +1689,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.28.0"
safe_device:
dependency: "direct main"
description:
name: safe_device
sha256: ad1b32a564484c710f6d52b5a526838c8a7d999c8ab2e14890ff55c06a018248
url: "https://pub.dev"
source: hosted
version: "1.4.1"
sanitize_html:
dependency: transitive
description:

Loading…
Cancel
Save