diff --git a/assets/images/svg/bluetooth.svg b/assets/images/svg/bluetooth.svg
new file mode 100644
index 00000000..5fe2cf0c
--- /dev/null
+++ b/assets/images/svg/bluetooth.svg
@@ -0,0 +1,6 @@
+
diff --git a/assets/images/svg/watch_activity.svg b/assets/images/svg/watch_activity.svg
new file mode 100644
index 00000000..8da915fa
--- /dev/null
+++ b/assets/images/svg/watch_activity.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/images/svg/watch_activity_trailing.svg b/assets/images/svg/watch_activity_trailing.svg
new file mode 100644
index 00000000..dc09c058
--- /dev/null
+++ b/assets/images/svg/watch_activity_trailing.svg
@@ -0,0 +1,4 @@
+
diff --git a/assets/images/svg/watch_bmi.svg b/assets/images/svg/watch_bmi.svg
new file mode 100644
index 00000000..4d34d5d0
--- /dev/null
+++ b/assets/images/svg/watch_bmi.svg
@@ -0,0 +1,6 @@
+
diff --git a/assets/images/svg/watch_bmi_trailing.svg b/assets/images/svg/watch_bmi_trailing.svg
new file mode 100644
index 00000000..772d18a4
--- /dev/null
+++ b/assets/images/svg/watch_bmi_trailing.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/images/svg/watch_height.svg b/assets/images/svg/watch_height.svg
new file mode 100644
index 00000000..e70b4b89
--- /dev/null
+++ b/assets/images/svg/watch_height.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/images/svg/watch_sleep.svg b/assets/images/svg/watch_sleep.svg
new file mode 100644
index 00000000..dd21f628
--- /dev/null
+++ b/assets/images/svg/watch_sleep.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/images/svg/watch_sleep_trailing.svg b/assets/images/svg/watch_sleep_trailing.svg
new file mode 100644
index 00000000..dff5ab36
--- /dev/null
+++ b/assets/images/svg/watch_sleep_trailing.svg
@@ -0,0 +1,5 @@
+
diff --git a/assets/images/svg/watch_steps.svg b/assets/images/svg/watch_steps.svg
new file mode 100644
index 00000000..730c1892
--- /dev/null
+++ b/assets/images/svg/watch_steps.svg
@@ -0,0 +1,5 @@
+
diff --git a/assets/images/svg/watch_steps_trailing.svg b/assets/images/svg/watch_steps_trailing.svg
new file mode 100644
index 00000000..2c1b2f20
--- /dev/null
+++ b/assets/images/svg/watch_steps_trailing.svg
@@ -0,0 +1,9 @@
+
diff --git a/assets/images/svg/watch_weight.svg b/assets/images/svg/watch_weight.svg
new file mode 100644
index 00000000..3acddca5
--- /dev/null
+++ b/assets/images/svg/watch_weight.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/images/svg/watch_weight_trailing.svg b/assets/images/svg/watch_weight_trailing.svg
new file mode 100644
index 00000000..3e2b3dd8
--- /dev/null
+++ b/assets/images/svg/watch_weight_trailing.svg
@@ -0,0 +1,9 @@
+
diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json
index cb2b71ab..dd576900 100644
--- a/assets/langs/ar-SA.json
+++ b/assets/langs/ar-SA.json
@@ -1523,5 +1523,20 @@
"bmi": "مؤشر كتلة الجسم",
"yesPleaseINeedHelp": "نعم، من فضلك أريد المساعدة",
"noThanksIKnowTheClinic": "لا شكراً، أعرف العيادة",
- "unableToSendOTP": "تعذر إرسال رمز التحقق لمرة واحدة"
+ "unableToSendOTP": "تعذر إرسال رمز التحقق لمرة واحدة",
+ "applewatch": "ساعة آبل",
+ "applehealthapplicationshouldbeinstalledinyourphone": "يجب تثبيت تطبيق Apple Health على هاتفك",
+ "unabletodetectapplicationinstalledpleasecomebackonceinstalled": "لا يمكننا اكتشاف التطبيق المثبت على جهازك. يرجى العودة إلى هنا بمجرد تثبيت هذا التطبيق.",
+ "applewatchshouldbeconnected": "يجب توصيل ساعة آبل",
+ "samsungwatch": "ساعة سامسونج",
+ "samsunghealthapplicationshouldbeinstalledinyourphone": "يجب تثبيت تطبيق Samsung Health على هاتفك",
+ "samsungwatchshouldbeconnected": "يجب توصيل ساعة سامسونج",
+ "huaweiwatch": "ساعة هواوي",
+ "huaweihealthapplicationshouldbeinstalledinyourphone": "يجب تثبيت تطبيق Huawei Health على هاتفك",
+ "huaweiwatchshouldbeconnected": "يجب توصيل ساعة هواوي",
+ "whoopwatch": "ساعة Whoop",
+ "whoophealthapplicationshouldbeinstalledinyourphone": "يجب تثبيت تطبيق Whoop Health على هاتفك",
+ "whoopwatchshouldbeconnected": "يجب توصيل ساعة Whoop",
+ "updatetheinformation": "سيتيح ذلك جمع أحدث المعلومات من ساعة آبل الخاصة بك"
+
}
diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json
index d937f6bc..ef7fcb9f 100644
--- a/assets/langs/en-US.json
+++ b/assets/langs/en-US.json
@@ -1516,5 +1516,20 @@
"bmi": "BMI",
"yesPleaseINeedHelp": "Yes, Please I need help",
"noThanksIKnowTheClinic": "No, Thanks. I Know the clinic",
- "unableToSendOTP": "Unable to send Verification OTP"
+ "unableToSendOTP": "Unable to send Verification OTP",
+ "applewatch": "Apple Watch",
+ "applehealthapplicationshouldbeinstalledinyourphone": "Apple Health application should be installed in your phone",
+ "unabletodetectapplicationinstalledpleasecomebackonceinstalled": "We are unable to detect the application installed in your device. Please come back here once you have installed this application.",
+ "applewatchshouldbeconnected": "Apple Watch should be connected",
+ "samsungwatch": "Samsung Watch",
+ "samsunghealthapplicationshouldbeinstalledinyourphone": "Samsung Health application should be installed in your phone",
+ "samsungwatchshouldbeconnected": "Samsung Watch should be connected",
+ "huaweiwatch": "Huawei Watch",
+ "huaweihealthapplicationshouldbeinstalledinyourphone": "Huawei Health application should be installed in your phone",
+ "huaweiwatchshouldbeconnected": "Huawei Watch should be connected",
+ "whoopwatch": "Whoop Watch",
+ "whoophealthapplicationshouldbeinstalledinyourphone": "Whoop Health application should be installed in your phone",
+ "whoopwatchshouldbeconnected": "Whoop Watch should be connected",
+ "updatetheinformation": "This will allow to gather the most up to date information from your apple watch"
+
}
diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj
index 7a41ae2c..2a0fec9a 100644
--- a/ios/Runner.xcodeproj/project.pbxproj
+++ b/ios/Runner.xcodeproj/project.pbxproj
@@ -11,19 +11,7 @@
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
478CFA942E638C8E0064F3D7 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 478CFA932E638C8E0064F3D7 /* GoogleService-Info.plist */; };
- 61243B492EC5FA3700D46FA0 /* PenguinModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61243B422EC5FA3700D46FA0 /* PenguinModel.swift */; };
- 61243B4C2EC5FA3700D46FA0 /* HMGPenguinInPlatformBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61243B3D2EC5FA3700D46FA0 /* HMGPenguinInPlatformBridge.swift */; };
- 61243B502EC5FA3700D46FA0 /* PenguinView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61243B452EC5FA3700D46FA0 /* PenguinView.swift */; };
- 61243B542EC5FA3700D46FA0 /* PenguinPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61243B442EC5FA3700D46FA0 /* PenguinPlugin.swift */; };
- 61243B562EC5FA3700D46FA0 /* PenguinNavigator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61243B432EC5FA3700D46FA0 /* PenguinNavigator.swift */; };
- 61243B572EC5FA3700D46FA0 /* PenguinViewFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61243B462EC5FA3700D46FA0 /* PenguinViewFactory.swift */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
- 766D8CB62EC60BE600D05E07 /* Penguin.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 766D8CB32EC60BE600D05E07 /* Penguin.xcframework */; };
- 766D8CB72EC60BE600D05E07 /* Penguin.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 766D8CB32EC60BE600D05E07 /* Penguin.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
- 766D8CB82EC60BE600D05E07 /* PenNavUI.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 766D8CB42EC60BE600D05E07 /* PenNavUI.xcframework */; };
- 766D8CB92EC60BE600D05E07 /* PenNavUI.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 766D8CB42EC60BE600D05E07 /* PenNavUI.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
- 766D8CBA2EC60BE600D05E07 /* PenguinINRenderer.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 766D8CB52EC60BE600D05E07 /* PenguinINRenderer.xcframework */; };
- 766D8CBB2EC60BE600D05E07 /* PenguinINRenderer.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 766D8CB52EC60BE600D05E07 /* PenguinINRenderer.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
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 */; };
@@ -47,9 +35,6 @@
dstPath = "";
dstSubfolderSpec = 10;
files = (
- 766D8CB72EC60BE600D05E07 /* Penguin.xcframework in Embed Frameworks */,
- 766D8CBB2EC60BE600D05E07 /* PenguinINRenderer.xcframework in Embed Frameworks */,
- 766D8CB92EC60BE600D05E07 /* PenNavUI.xcframework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
@@ -64,18 +49,9 @@
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
478CFA932E638C8E0064F3D7 /* GoogleService-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; };
478CFA952E6E20A60064F3D7 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = ""; };
- 61243B3D2EC5FA3700D46FA0 /* HMGPenguinInPlatformBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HMGPenguinInPlatformBridge.swift; sourceTree = ""; };
- 61243B422EC5FA3700D46FA0 /* PenguinModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinModel.swift; sourceTree = ""; };
- 61243B432EC5FA3700D46FA0 /* PenguinNavigator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinNavigator.swift; sourceTree = ""; };
- 61243B442EC5FA3700D46FA0 /* PenguinPlugin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinPlugin.swift; sourceTree = ""; };
- 61243B452EC5FA3700D46FA0 /* PenguinView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinView.swift; sourceTree = ""; };
- 61243B462EC5FA3700D46FA0 /* PenguinViewFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinViewFactory.swift; sourceTree = ""; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
7595037DD52211B91157B0F3 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; };
- 766D8CB32EC60BE600D05E07 /* Penguin.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = Penguin.xcframework; path = Frameworks/Penguin.xcframework; sourceTree = ""; };
- 766D8CB42EC60BE600D05E07 /* PenNavUI.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = PenNavUI.xcframework; path = Frameworks/PenNavUI.xcframework; sourceTree = ""; };
- 766D8CB52EC60BE600D05E07 /* PenguinINRenderer.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = PenguinINRenderer.xcframework; path = Frameworks/PenguinINRenderer.xcframework; sourceTree = ""; };
769C9BF82E6F106D009F68A9 /* RunnerDebug.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = RunnerDebug.entitlements; sourceTree = ""; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
8E12CEEB8E334EE22D5259D7 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; };
@@ -95,9 +71,6 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 766D8CB62EC60BE600D05E07 /* Penguin.xcframework in Frameworks */,
- 766D8CBA2EC60BE600D05E07 /* PenguinINRenderer.xcframework in Frameworks */,
- 766D8CB82EC60BE600D05E07 /* PenNavUI.xcframework in Frameworks */,
DE1EF78253E64BE86845D2CC /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -113,32 +86,9 @@
path = RunnerTests;
sourceTree = "";
};
- 61243B412EC5FA3700D46FA0 /* Helper */ = {
- isa = PBXGroup;
- children = (
- 61243B3D2EC5FA3700D46FA0 /* HMGPenguinInPlatformBridge.swift */,
- );
- path = Helper;
- sourceTree = "";
- };
- 61243B472EC5FA3700D46FA0 /* Penguin */ = {
- isa = PBXGroup;
- children = (
- 61243B422EC5FA3700D46FA0 /* PenguinModel.swift */,
- 61243B432EC5FA3700D46FA0 /* PenguinNavigator.swift */,
- 61243B442EC5FA3700D46FA0 /* PenguinPlugin.swift */,
- 61243B452EC5FA3700D46FA0 /* PenguinView.swift */,
- 61243B462EC5FA3700D46FA0 /* PenguinViewFactory.swift */,
- );
- path = Penguin;
- sourceTree = "";
- };
766D8CB22EC60BE600D05E07 /* Frameworks */ = {
isa = PBXGroup;
children = (
- 766D8CB32EC60BE600D05E07 /* Penguin.xcframework */,
- 766D8CB52EC60BE600D05E07 /* PenguinINRenderer.xcframework */,
- 766D8CB42EC60BE600D05E07 /* PenNavUI.xcframework */,
D562310E31D1DDEFA02A6C12 /* Pods_Runner.framework */,
);
name = Frameworks;
@@ -189,8 +139,6 @@
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
- 61243B412EC5FA3700D46FA0 /* Helper */,
- 61243B472EC5FA3700D46FA0 /* Penguin */,
769C9BF82E6F106D009F68A9 /* RunnerDebug.entitlements */,
478CFA952E6E20A60064F3D7 /* Runner.entitlements */,
478CFA932E638C8E0064F3D7 /* GoogleService-Info.plist */,
@@ -414,12 +362,6 @@
buildActionMask = 2147483647;
files = (
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
- 61243B492EC5FA3700D46FA0 /* PenguinModel.swift in Sources */,
- 61243B4C2EC5FA3700D46FA0 /* HMGPenguinInPlatformBridge.swift in Sources */,
- 61243B502EC5FA3700D46FA0 /* PenguinView.swift in Sources */,
- 61243B542EC5FA3700D46FA0 /* PenguinPlugin.swift in Sources */,
- 61243B562EC5FA3700D46FA0 /* PenguinNavigator.swift in Sources */,
- 61243B572EC5FA3700D46FA0 /* PenguinViewFactory.swift in Sources */,
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift
index 64d7428e..308891a7 100644
--- a/ios/Runner/AppDelegate.swift
+++ b/ios/Runner/AppDelegate.swift
@@ -16,11 +16,11 @@ import GoogleMaps
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
func initializePlatformChannels(){
- if let mainViewController = window?.rootViewController as? FlutterViewController{ // platform initialization suppose to be in foreground
-
- HMGPenguinInPlatformBridge.initialize(flutterViewController: mainViewController)
-
- }
+// if let mainViewController = window?.rootViewController as? FlutterViewController{ // platform initialization suppose to be in foreground
+//
+//// HMGPenguinInPlatformBridge.initialize(flutterViewController: mainViewController)
+//
+// }
}
override func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken:Data){
// Messaging.messaging().apnsToken = deviceToken
diff --git a/lib/core/app_assets.dart b/lib/core/app_assets.dart
index 5b8d2ed5..019bd144 100644
--- a/lib/core/app_assets.dart
+++ b/lib/core/app_assets.dart
@@ -230,6 +230,21 @@ class AppAssets {
static const String forward_top_nav_icon = '$svgBasePath/forward_top_nav_icon.svg';
static const String back_top_nav_icon = '$svgBasePath/back_top_nav_icon.svg';
+ static const String bluetooth = '$svgBasePath/bluetooth.svg';
+
+ //smartwatch
+ static const String watchActivity = '$svgBasePath/watch_activity.svg';
+ static const String watchActivityTrailing = '$svgBasePath/watch_activity_trailing.svg';
+ static const String watchSteps= '$svgBasePath/watch_steps.svg';
+ static const String watchStepsTrailing= '$svgBasePath/watch_steps_trailing.svg';
+ static const String watchSleep= '$svgBasePath/watch_sleep.svg';
+ static const String watchSleepTrailing= '$svgBasePath/watch_sleep_trailing.svg';
+ static const String watchBmi= '$svgBasePath/watch_bmi.svg';
+ static const String watchBmiTrailing= '$svgBasePath/watch_bmi_trailing.svg';
+ static const String watchWeight= '$svgBasePath/watch_weight.svg';
+ static const String watchWeightTrailing= '$svgBasePath/watch_weight_trailing.svg';
+ static const String watchHeight= '$svgBasePath/watch_height.svg';
+
//bottom navigation//
static const String homeBottom = '$svgBasePath/home_bottom.svg';
diff --git a/lib/core/common_models/smart_watch.dart b/lib/core/common_models/smart_watch.dart
new file mode 100644
index 00000000..b9259f5a
--- /dev/null
+++ b/lib/core/common_models/smart_watch.dart
@@ -0,0 +1,18 @@
+enum SmartWatchTypes{
+ apple,
+ samsung,
+ huawei,
+ whoop
+}
+
+
+class SmartwatchDetails {
+ final SmartWatchTypes watchType;
+ final String watchIcon;
+ final String smallIcon;
+ final String detailsTitle;
+ final String details;
+ final String secondTitle;
+
+ SmartwatchDetails(this.watchType, this.watchIcon, this.smallIcon, this.detailsTitle, this.details, this.secondTitle);
+}
\ No newline at end of file
diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart
index 416d2a47..1ff22113 100644
--- a/lib/generated/locale_keys.g.dart
+++ b/lib/generated/locale_keys.g.dart
@@ -1515,5 +1515,19 @@ abstract class LocaleKeys {
static const yesPleaseINeedHelp = 'yesPleaseINeedHelp';
static const noThanksIKnowTheClinic = 'noThanksIKnowTheClinic';
static const unableToSendOTP = 'unableToSendOTP';
+ static const applewatch = 'applewatch';
+ static const applehealthapplicationshouldbeinstalledinyourphone = 'applehealthapplicationshouldbeinstalledinyourphone';
+ static const unabletodetectapplicationinstalledpleasecomebackonceinstalled = 'unabletodetectapplicationinstalledpleasecomebackonceinstalled';
+ static const applewatchshouldbeconnected = 'applewatchshouldbeconnected';
+ static const samsungwatch = 'samsungwatch';
+ static const samsunghealthapplicationshouldbeinstalledinyourphone = 'samsunghealthapplicationshouldbeinstalledinyourphone';
+ static const samsungwatchshouldbeconnected = 'samsungwatchshouldbeconnected';
+ static const huaweiwatch = 'huaweiwatch';
+ static const huaweihealthapplicationshouldbeinstalledinyourphone = 'huaweihealthapplicationshouldbeinstalledinyourphone';
+ static const huaweiwatchshouldbeconnected = 'huaweiwatchshouldbeconnected';
+ static const whoopwatch = 'whoopwatch';
+ static const whoophealthapplicationshouldbeinstalledinyourphone = 'whoophealthapplicationshouldbeinstalledinyourphone';
+ static const whoopwatchshouldbeconnected = 'whoopwatchshouldbeconnected';
+ static const updatetheinformation = 'updatetheinformation';
}
diff --git a/lib/presentation/smartwatches/activity_detail.dart b/lib/presentation/smartwatches/activity_detail.dart
new file mode 100644
index 00000000..cc006a61
--- /dev/null
+++ b/lib/presentation/smartwatches/activity_detail.dart
@@ -0,0 +1,247 @@
+import 'dart:math';
+
+import 'package:fl_chart/fl_chart.dart';
+import 'package:flutter/material.dart';
+import 'package:hmg_patient_app_new/core/app_export.dart';
+import 'package:hmg_patient_app_new/core/common_models/data_points.dart';
+import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
+import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
+import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
+import 'package:hmg_patient_app_new/theme/colors.dart';
+import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
+import 'package:hmg_patient_app_new/widgets/custom_tab_bar.dart';
+import 'package:hmg_patient_app_new/widgets/graph/CustomBarGraph.dart';
+import 'package:intl/intl.dart' show DateFormat;
+
+class ActivityDetails extends StatefulWidget {
+ final String selectedActivity;
+
+ const ActivityDetails({super.key, required this.selectedActivity});
+
+ @override
+ State createState() => _ActivityDetailsState();
+}
+
+class _ActivityDetailsState extends State {
+ int index = 0;
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ backgroundColor: AppColors.bgScaffoldColor,
+ body: CollapsingListView(
+ title: "All Health Data".needTranslation,
+ child: Column(
+ spacing: 16.h,
+ children: [
+ periodSelectorView((index) {}),
+ activityDetails(),
+ DecoratedBox(
+ decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 12.h),
+ child:
+ activityGraph().paddingOnly(left: 16.w, right: 16.w, top: 32.h, bottom: 16.h),)
+ ],
+ ).paddingSymmetrical(24.w, 24.h),
+ ),
+ );
+ }
+
+ Widget periodSelectorView(Function(int) onItemSelected) {
+ return DecoratedBox(
+ decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 12.h),
+ child: Row(
+ children: [
+ Expanded(
+ child: CustomTabBar(
+ activeTextColor: Color(0xffED1C2B),
+ activeBackgroundColor: Color(0xffED1C2B).withValues(alpha: .1),
+ tabs: [
+ CustomTabBarModel(null, "D"),
+ CustomTabBarModel(null, "W"),
+ CustomTabBarModel(null, "M"),
+ CustomTabBarModel(null, "6M"),
+ CustomTabBarModel(null, "Y"),
+ // CustomTabBarModel(null, "Completed".needTranslation),
+ ],
+ shouldTabExpanded: true,
+ onTabChange: (index) {
+ //todo handle the selection from viewmodel
+ setState(() {
+ this.index = index;
+ });
+ },
+ ),
+ ),
+ ],
+ ).paddingSymmetrical(4.w, 4.h));
+ }
+
+ Widget activityDetails() {
+ return DecoratedBox(
+ decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 12.h, hasShadow: true),
+ child: Column(
+ spacing: 8.h,
+ children: [
+ Column(
+ children: [widget.selectedActivity.toText32(weight: FontWeight.w600, color: AppColors.textColor), "Average".toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor)],
+ ),
+ Row(
+ children: ["3232".toText24(color: AppColors.textGreenColor, fontWeight: FontWeight.w600), "(20-21)".toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500)],
+ )
+ ],
+ ).paddingSymmetrical(16.w, 16.h));
+ }
+
+
+ Widget activityGraph() {
+ final _random = Random();
+
+ int randomBP() => 100 + _random.nextInt(51); // 100–150
+ final List data6Months = List.generate(6, (index) {
+ final date = DateTime.now().subtract(Duration(days: 30 * (5 - index)));
+
+ final value = randomBP();
+
+ return DataPoint(
+ value: value.toDouble(),
+ label: value.toString(),
+ actualValue: value.toString(),
+ displayTime: DateFormat('MMM').format(date),
+ unitOfMeasurement: 'mmHg',
+ time: date,
+ );
+ });
+ final List data12Months = List.generate(12, (index) {
+ final date = DateTime.now().subtract(Duration(days: 30 * (11 - index)));
+
+ final value = randomBP();
+
+ return DataPoint(
+ value: value.toDouble(),
+ label: value.toString(),
+ actualValue: value.toString(),
+ displayTime: DateFormat('MMM').format(date),
+ unitOfMeasurement: 'mmHg',
+ time: date,
+ );
+ });
+
+ List data =[];
+ if(index == 0){
+ data = data6Months;
+ } else if(index == 1){
+ data = data12Months;
+ } else
+ data = [
+ DataPoint(
+ value: 128,
+ label: "128",
+ actualValue: '128',
+ displayTime: 'Sun',
+ unitOfMeasurement: 'mmHg',
+ time: DateTime.now().subtract(const Duration(days: 6)),
+ ),
+ DataPoint(
+ value: 135,
+ label: "135",
+ actualValue: '135',
+ displayTime: 'Mon',
+ unitOfMeasurement: 'mmHg',
+ time: DateTime.now().subtract(const Duration(days: 5)),
+ ),
+ DataPoint(
+ value: 122,
+ label: "122",
+ actualValue: '122',
+ displayTime: 'Tue',
+ unitOfMeasurement: 'mmHg',
+ time: DateTime.now().subtract(const Duration(days: 4)),
+ ),
+ DataPoint(
+ value: 140,
+ label: "140",
+ actualValue: '140',
+ displayTime: 'Wed',
+ unitOfMeasurement: 'mmHg',
+ time: DateTime.now().subtract(const Duration(days: 3)),
+ ),
+ DataPoint(
+ value: 118,
+ label: "118",
+ actualValue: '118',
+ displayTime: 'Thu',
+ unitOfMeasurement: 'mmHg',
+ time: DateTime.now().subtract(const Duration(days: 2)),
+ ),
+ DataPoint(
+ value: 125,
+ label: "125",
+ actualValue: '125',
+ displayTime: 'Fri',
+ unitOfMeasurement: 'mmHg',
+ time: DateTime.now().subtract(const Duration(days: 1)),
+ ),
+ DataPoint(
+ value: 130,
+ label: "130",
+ actualValue: '130',
+ displayTime: 'Sat',
+ unitOfMeasurement: 'mmHg',
+ time: DateTime.now(),
+ ),
+ ];
+
+ return CustomBarChart(
+ dataPoints: data,
+ height: 300.h,
+ maxY: 150,
+ barColor: AppColors.bgGreenColor,
+ barWidth: 26.w,
+ barRadius: BorderRadius.circular(8),
+ bottomLabelColor: Colors.black,
+ bottomLabelSize: 12,
+ leftLabelInterval: .1,
+ leftLabelReservedSize: 40,
+ // Left axis label formatter (Y-axis)
+ leftLabelFormatter: (value) {
+ var labelValue = double.tryParse(value.toStringAsFixed(0));
+
+ if (labelValue == null) return SizedBox.shrink();
+ if (labelValue == 0 || labelValue == 150 / 2 || labelValue == 150) {
+ return Text(
+ labelValue.toStringAsFixed(0),
+ style: const TextStyle(
+ color: Colors.black26,
+ fontSize: 11,
+ ),
+ );
+ }
+
+ return SizedBox.shrink();
+ },
+
+ // Bottom axis label formatter (X-axis - Days)
+ bottomLabelFormatter: (value, dataPoints) {
+ final index = value.toInt();
+ if (index >= 0 && index < dataPoints.length) {
+ return Text(
+ dataPoints[index].displayTime,
+ style: const TextStyle(
+ color: Colors.grey,
+ fontSize: 11,
+ ),
+ );
+ }
+ return const Text('');
+ },
+ verticalInterval: 1/data.length,
+ getDrawingVerticalLine: (value) {
+ return FlLine(
+ color: AppColors.greyColor,
+ strokeWidth: 1,
+ );
+ },
+ showGridLines: true,
+ );
+ }
+}
diff --git a/lib/presentation/smartwatches/smart_watch_activity.dart b/lib/presentation/smartwatches/smart_watch_activity.dart
new file mode 100644
index 00000000..531139b8
--- /dev/null
+++ b/lib/presentation/smartwatches/smart_watch_activity.dart
@@ -0,0 +1,147 @@
+import 'package:flutter/material.dart';
+import 'package:hmg_patient_app_new/core/app_assets.dart';
+import 'package:hmg_patient_app_new/core/app_export.dart';
+import 'package:hmg_patient_app_new/core/dependencies.dart';
+import 'package:hmg_patient_app_new/core/utils/utils.dart';
+import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
+import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
+import 'package:hmg_patient_app_new/presentation/smartwatches/activity_detail.dart';
+import 'package:hmg_patient_app_new/services/navigation_service.dart';
+import 'package:hmg_patient_app_new/theme/colors.dart';
+import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
+
+class SmartWatchActivity extends StatelessWidget {
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ backgroundColor: AppColors.bgScaffoldColor,
+ body: CollapsingListView(
+ title: "All Health Data".needTranslation,
+ child: Column(
+ spacing: 16.h,
+ children: [
+ resultItem(
+ leadingIcon: AppAssets.watchActivity,
+ title: "Activity".needTranslation,
+ description: "Activity rings give you a quick visual reference of how active you are each day. ".needTranslation,
+ trailingIcon: AppAssets.watchActivityTrailing,
+ result: "21",
+ unitsOfMeasure: "Cal"
+ ).onPress((){
+ getIt.get().pushPage(page: ActivityDetails( selectedActivity: "Steps"));
+ }),
+ resultItem(
+ leadingIcon: AppAssets.watchSteps,
+ title: "Steps".needTranslation,
+ description: "Step count is the number of steps you take throughout the day.".needTranslation,
+ trailingIcon: AppAssets.watchStepsTrailing,
+ result: "21",
+ unitsOfMeasure: "Steps"
+ ),
+ resultItem(
+ leadingIcon: AppAssets.watchSteps,
+ title: "Walking + Running Distance".needTranslation,
+ description: "This will show you the total distance you covered in a day".needTranslation,
+ trailingIcon: AppAssets.watchStepsTrailing,
+ result: "21",
+ unitsOfMeasure: "km"
+ ),
+ resultItem(
+ leadingIcon: AppAssets.watchSleep,
+ title: "Sleep Score".needTranslation,
+ description: "This will keep track of how much hours you sleep in a day".needTranslation,
+ trailingIcon: AppAssets.watchSleepTrailing,
+ result: "21",
+ unitsOfMeasure: "hr",
+ resultSecondValue: "2",
+ unitOfSecondMeasure: "min"
+ ),
+ resultItem(
+ leadingIcon: AppAssets.watchBmi,
+ title: "Body Mass Index".needTranslation,
+ description: "This will calculate your weight and height ratio to analyze the ".needTranslation,
+ trailingIcon: AppAssets.watchBmiTrailing,
+ result: "21",
+ unitsOfMeasure: "BMI"
+ ),
+ resultItem(
+ leadingIcon: AppAssets.watchWeight,
+ title: "Weight".needTranslation,
+ description: "This will calculate your weight to keep track and update history".needTranslation,
+ trailingIcon: AppAssets.watchWeightTrailing,
+ result: "21",
+ unitsOfMeasure: "Kg"
+ ),
+ resultItem(
+ leadingIcon: AppAssets.watchWeight,
+ title: "Height".needTranslation,
+ description: "This will calculate your height to keep track and update history".needTranslation,
+ trailingIcon: AppAssets.watchWeightTrailing,
+ result: "21",
+ unitsOfMeasure: "ft"
+ )
+ ],
+ ).paddingSymmetrical(24.w, 24.h),
+ ));
+ }
+
+ Widget resultItem({
+ required String leadingIcon,
+ required String title,
+ required String description,
+ required String trailingIcon,
+ required String result,
+ required String unitsOfMeasure,
+ String? resultSecondValue,
+ String? unitOfSecondMeasure
+ }) {
+ return DecoratedBox(
+ decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 12.h),
+ child: Row(
+ spacing: 16.w,
+ children: [
+ Expanded(
+ child:Column(
+ spacing: 8.h,
+ children: [
+ Row(
+ spacing: 8.w,
+ children: [
+ Utils.buildSvgWithAssets(icon: leadingIcon, height: 16.h, width: 14.w),
+ title.toText16( weight: FontWeight.w600, color: AppColors.textColor),
+ ],
+ ),
+ description.toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor),
+ Row(
+ crossAxisAlignment: CrossAxisAlignment.baseline,
+ textBaseline: TextBaseline.alphabetic,
+ spacing: 2.h,
+ children: [
+ result.toText21(weight: FontWeight.w600, color: AppColors.textColor),
+ unitsOfMeasure.toText10(weight: FontWeight.w500, color:AppColors.greyTextColor ),
+ if(resultSecondValue != null)
+ Visibility(
+ visible: resultSecondValue != null ,
+ child: Row(
+ crossAxisAlignment: CrossAxisAlignment.baseline,
+ textBaseline: TextBaseline.alphabetic,
+ spacing: 2.h,
+ children: [
+ SizedBox(width: 2.w,),
+ resultSecondValue.toText21(weight: FontWeight.w600, color: AppColors.textColor),
+ unitOfSecondMeasure!.toText10(weight: FontWeight.w500, color:AppColors.greyTextColor )
+ ],
+ ),
+ )
+ ],
+ ),
+
+ ],
+ ) ,
+ ),
+ Utils.buildSvgWithAssets(icon: trailingIcon, width: 72.w, height: 72.h),
+ ],
+ ).paddingSymmetrical(16.w, 16.h)
+ );
+ }
+}
diff --git a/lib/presentation/smartwatches/smartwatch_home_page.dart b/lib/presentation/smartwatches/smartwatch_home_page.dart
index 8fd79098..050cbf7d 100644
--- a/lib/presentation/smartwatches/smartwatch_home_page.dart
+++ b/lib/presentation/smartwatches/smartwatch_home_page.dart
@@ -3,12 +3,16 @@ import 'dart:io';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
+import 'package:hmg_patient_app_new/core/common_models/smart_watch.dart';
+import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/smartwatch_health_data/health_provider.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
+import 'package:hmg_patient_app_new/presentation/smartwatches/smartwatch_instructions_page.dart';
import 'package:hmg_patient_app_new/presentation/smartwatches/widgets/supported_watches_list.dart';
+import 'package:hmg_patient_app_new/services/navigation_service.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
@@ -81,6 +85,14 @@ class SmartwatchHomePage extends StatelessWidget {
text: LocaleKeys.select.tr(context: context),
onPressed: () {
context.read().setSelectedWatchType("apple", "assets/images/png/smartwatches/apple-watch-5.jpg");
+ getIt.get().pushPage(page: SmartwatchInstructionsPage(
+ smartwatchDetails: SmartwatchDetails(SmartWatchTypes.apple,
+ "assets/images/png/smartwatches/apple-watch-5.jpg",
+ AppAssets.bluetooth,
+ LocaleKeys.applehealthapplicationshouldbeinstalledinyourphone.tr(context: context),
+ LocaleKeys.unabletodetectapplicationinstalledpleasecomebackonceinstalled.tr(context: context),
+ LocaleKeys.applewatchshouldbeconnected.tr(context: context)),
+ ));
},
backgroundColor: AppColors.primaryRedColor.withAlpha(40),
borderColor: AppColors.primaryRedColor.withAlpha(0),
@@ -106,7 +118,14 @@ class SmartwatchHomePage extends StatelessWidget {
text: LocaleKeys.select.tr(context: context),
onPressed: () {
context.read().setSelectedWatchType("samsung", "assets/images/png/smartwatches/galaxy_watch_8_classic.jpeg");
- },
+ getIt.get().pushPage(page: SmartwatchInstructionsPage(
+ smartwatchDetails: SmartwatchDetails(SmartWatchTypes.samsung,
+ "assets/images/png/smartwatches/galaxy_watch_8_classic.jpeg",
+ AppAssets.bluetooth,
+ LocaleKeys.samsunghealthapplicationshouldbeinstalledinyourphone.tr(context: context),
+ LocaleKeys.unabletodetectapplicationinstalledpleasecomebackonceinstalled.tr(context: context),
+ LocaleKeys.samsungwatchshouldbeconnected.tr(context: context)),
+ )); },
backgroundColor: AppColors.primaryRedColor.withAlpha(40),
borderColor: AppColors.primaryRedColor.withAlpha(0),
textColor: AppColors.primaryRedColor,
@@ -131,6 +150,14 @@ class SmartwatchHomePage extends StatelessWidget {
text: LocaleKeys.select.tr(context: context),
onPressed: () {
context.read().setSelectedWatchType("huawei", "assets/images/png/smartwatches/Huawei_Watch.png");
+ getIt.get().pushPage(page: SmartwatchInstructionsPage(
+ smartwatchDetails: SmartwatchDetails(SmartWatchTypes.huawei,
+ "assets/images/png/smartwatches/Huawei_Watch.png",
+ AppAssets.bluetooth,
+ LocaleKeys.huaweihealthapplicationshouldbeinstalledinyourphone.tr(context: context),
+ LocaleKeys.unabletodetectapplicationinstalledpleasecomebackonceinstalled.tr(context: context),
+ LocaleKeys.huaweiwatchshouldbeconnected.tr(context: context)),
+ ));
},
backgroundColor: AppColors.primaryRedColor.withAlpha(40),
borderColor: AppColors.primaryRedColor.withAlpha(0),
@@ -156,6 +183,14 @@ class SmartwatchHomePage extends StatelessWidget {
text: LocaleKeys.select.tr(context: context),
onPressed: () {
context.read().setSelectedWatchType("whoop", "assets/images/png/smartwatches/Whoop_Watch.png");
+ getIt.get().pushPage(page: SmartwatchInstructionsPage(
+ smartwatchDetails: SmartwatchDetails(SmartWatchTypes.whoop,
+ "assets/images/png/smartwatches/Whoop_Watch.png",
+ AppAssets.bluetooth,
+ LocaleKeys.whoophealthapplicationshouldbeinstalledinyourphone.tr(context: context),
+ LocaleKeys.unabletodetectapplicationinstalledpleasecomebackonceinstalled.tr(context: context),
+ LocaleKeys.whoopwatchshouldbeconnected.tr(context: context)),
+ ));
},
backgroundColor: AppColors.primaryRedColor.withAlpha(40),
borderColor: AppColors.primaryRedColor.withAlpha(0),
diff --git a/lib/presentation/smartwatches/smartwatch_instructions_page.dart b/lib/presentation/smartwatches/smartwatch_instructions_page.dart
index 48683d50..949b460f 100644
--- a/lib/presentation/smartwatches/smartwatch_instructions_page.dart
+++ b/lib/presentation/smartwatches/smartwatch_instructions_page.dart
@@ -1,15 +1,24 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
+import 'package:hmg_patient_app_new/core/app_assets.dart';
+import 'package:hmg_patient_app_new/core/common_models/smart_watch.dart';
+import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
+import 'package:hmg_patient_app_new/presentation/smartwatches/smart_watch_activity.dart' show SmartWatchActivity;
+import 'package:hmg_patient_app_new/services/navigation_service.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
+import '../../core/utils/utils.dart';
+
class SmartwatchInstructionsPage extends StatelessWidget {
- const SmartwatchInstructionsPage({super.key});
+ final SmartwatchDetails smartwatchDetails;
+
+ const SmartwatchInstructionsPage({super.key, required this.smartwatchDetails});
@override
Widget build(BuildContext context) {
@@ -25,6 +34,7 @@ class SmartwatchInstructionsPage extends StatelessWidget {
child: CustomButton(
text: LocaleKeys.getStarted.tr(context: context),
onPressed: () {
+ getIt.get().pushPage(page: SmartWatchActivity());
},
backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedColor,
@@ -35,8 +45,55 @@ class SmartwatchInstructionsPage extends StatelessWidget {
height: 50.h,
).paddingSymmetrical(24.w, 30.h),
),
- child: SingleChildScrollView(),
+ child: Column(
+ mainAxisSize: MainAxisSize.max,
+ spacing: 18.h,
+ children: [
+ Image.asset(smartwatchDetails.watchIcon, fit: BoxFit.contain, height: 280.h,width: 280.w,),
+ DecoratedBox(
+ decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 12.h),
+ child: Column(
+ children: [
+ watchContentDetails(
+ title: smartwatchDetails.detailsTitle,
+ description: smartwatchDetails.details,
+ icon: smartwatchDetails.smallIcon,
+ descriptionTextColor: AppColors.primaryRedColor
+ ),
+ Divider(
+ color: AppColors.dividerColor,
+ thickness: 1.h,
+ ).paddingOnly(top: 16.h, bottom: 16.h),
+ watchContentDetails(
+ title: smartwatchDetails.secondTitle,
+ description: LocaleKeys.updatetheinformation.tr(),
+ icon: AppAssets.bluetooth,
+ descriptionTextColor: AppColors.greyTextColor
+ ),
+ ],
+ ).paddingSymmetrical(16.w, 16.h),
+ )
+ ],
+ ).paddingSymmetrical(24.w, 16.h),
),
);
}
+
+
+ Widget watchContentDetails({required String title, required String description, required String icon, required Color descriptionTextColor}) {
+ return Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ spacing: 8.h,
+ children: [
+ DecoratedBox(
+ decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 12.h),
+ child: Utils.buildSvgWithAssets(icon: icon, width: 40.w, height: 40.h),
+
+ ),
+
+ title.toText16(weight: FontWeight.w600, color: AppColors.textColor),
+ description.toText12(fontWeight: FontWeight.w500, color: descriptionTextColor)
+ ],
+ );
+ }
}
diff --git a/lib/routes/app_routes.dart b/lib/routes/app_routes.dart
index 9cf0ed91..8af9789d 100644
--- a/lib/routes/app_routes.dart
+++ b/lib/routes/app_routes.dart
@@ -39,6 +39,7 @@ import '../features/monthly_reports/monthly_reports_repo.dart';
import '../features/monthly_reports/monthly_reports_view_model.dart';
import '../features/qr_parking/qr_parking_view_model.dart';
import '../presentation/parking/paking_page.dart';
+import '../presentation/smartwatches/smartwatch_instructions_page.dart';
import '../services/error_handler_service.dart';
class AppRoutes {
diff --git a/lib/theme/colors.dart b/lib/theme/colors.dart
index d56178b7..f450aebb 100644
--- a/lib/theme/colors.dart
+++ b/lib/theme/colors.dart
@@ -113,4 +113,5 @@ class AppColors {
static const Color covid29Color = Color(0xff2563EB); // #2563EB
static const Color lightGreyTextColor = Color(0xFF959595);
static const Color labelColorYellow = Color(0xFFFBCB6E);
+ static const Color tooltipColor = Color(0xFF1AACACAC);
}
diff --git a/lib/widgets/custom_tab_bar.dart b/lib/widgets/custom_tab_bar.dart
index c30c0700..03f1b25a 100644
--- a/lib/widgets/custom_tab_bar.dart
+++ b/lib/widgets/custom_tab_bar.dart
@@ -21,6 +21,7 @@ class CustomTabBar extends StatefulWidget {
final Color inActiveTextColor;
final Color inActiveBackgroundColor;
final Function(int)? onTabChange;
+ final bool shouldTabExpanded;
const CustomTabBar({
super.key,
@@ -31,6 +32,7 @@ class CustomTabBar extends StatefulWidget {
this.activeBackgroundColor = const Color(0x142E3039),
this.inActiveBackgroundColor = Colors.white,
this.onTabChange,
+ this.shouldTabExpanded = false
});
@override
@@ -58,6 +60,11 @@ class CustomTabBarState extends State {
@override
Widget build(BuildContext context) {
late Widget parentWidget;
+ if(widget.shouldTabExpanded){
+ return Row(
+ children:List.generate(widget.tabs.length, (index)=>myTab(widget.tabs[index], index).expanded),
+ );
+ }
if (widget.tabs.length > 3) {
parentWidget = ListView.separated(
diff --git a/lib/widgets/graph/CustomBarGraph.dart b/lib/widgets/graph/CustomBarGraph.dart
new file mode 100644
index 00000000..b90ddb00
--- /dev/null
+++ b/lib/widgets/graph/CustomBarGraph.dart
@@ -0,0 +1,240 @@
+import 'package:easy_localization/easy_localization.dart';
+import 'package:fl_chart/fl_chart.dart';
+import 'package:flutter/material.dart';
+import 'package:hmg_patient_app_new/core/common_models/data_points.dart';
+import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
+import 'package:hmg_patient_app_new/theme/colors.dart';
+
+/// A customizable bar chart widget using `fl_chart`.
+///
+/// Displays a bar chart with configurable axis labels, colors, and data points.
+/// Useful for visualizing comparative data, categories, or grouped values.
+///
+/// **Parameters:**
+/// - [dataPoints]: List of `DataPoint` objects to plot.
+/// - [secondaryDataPoints]: Optional list for grouped bars (e.g., comparison data).
+/// - [leftLabelFormatter]: Function to build left axis labels.
+/// - [bottomLabelFormatter]: Function to build bottom axis labels.
+/// - [width]: Optional width of the chart.
+/// - [height]: Required height of the chart.
+/// - [maxY], [maxX], [minX]: Axis bounds.
+/// - [barColor]: Color of the bars.
+/// - [secondaryBarColor]: Color of the secondary bars.
+/// - [barRadius]: Border radius for bar corners.
+/// - [barWidth]: Width of each bar.
+/// - [bottomLabelColor]: Color of bottom axis labels.
+/// - [bottomLabelSize]: Font size for bottom axis labels.
+/// - [bottomLabelFontWeight]: Font weight for bottom axis labels.
+/// - [leftLabelInterval]: Interval between left axis labels.
+/// - [leftLabelReservedSize]: Reserved space for left axis labels.
+/// - [showBottomTitleDates]: Whether to show bottom axis labels.
+/// - [isFullScreeGraph]: Whether the graph is fullscreen.
+/// - [makeGraphBasedOnActualValue]: Use `actualValue` for plotting.
+///
+/// Example usage:
+/// ```dart
+/// CustomBarChart(
+/// dataPoints: sampleData,
+/// leftLabelFormatter: (value) => ...,
+/// bottomLabelFormatter: (value, dataPoints) => ...,
+/// height: 300,
+/// maxY: 100,
+/// )
+class CustomBarChart extends StatelessWidget {
+ final List dataPoints;
+ final List? secondaryDataPoints; // For grouped bar charts
+ final double? width;
+ final double height;
+ final double? maxY;
+ final double? maxX;
+ final double? minX;
+ final Color barColor;
+ final Color? secondaryBarColor;
+ final Color barGridColor;
+ final Color bottomLabelColor;
+ final double? bottomLabelSize;
+ final FontWeight? bottomLabelFontWeight;
+ final double? leftLabelInterval;
+ final double? leftLabelReservedSize;
+ final double? bottomLabelReservedSize;
+ final bool? showGridLines;
+ final GetDrawingGridLine? getDrawingVerticalLine;
+ final double? verticalInterval;
+ final double? minY;
+ final BorderRadius? barRadius;
+ final double barWidth;
+
+ /// Creates the left label and provides it to the chart
+ final Widget Function(double) leftLabelFormatter;
+ final Widget Function(double, List) bottomLabelFormatter;
+
+ final bool showBottomTitleDates;
+ final bool isFullScreeGraph;
+ final bool makeGraphBasedOnActualValue;
+
+ const CustomBarChart(
+ {super.key,
+ required this.dataPoints,
+ this.secondaryDataPoints,
+ required this.leftLabelFormatter,
+ this.width,
+ required this.height,
+ this.maxY,
+ this.maxX,
+ this.showBottomTitleDates = true,
+ this.isFullScreeGraph = false,
+ this.barColor = AppColors.bgGreenColor,
+ this.secondaryBarColor,
+ this.barGridColor = AppColors.graphGridColor,
+ this.bottomLabelColor = AppColors.textColor,
+ this.bottomLabelFontWeight = FontWeight.w500,
+ this.bottomLabelSize,
+ this.leftLabelInterval,
+ this.leftLabelReservedSize,
+ this.bottomLabelReservedSize,
+ this.makeGraphBasedOnActualValue = false,
+ required this.bottomLabelFormatter,
+ this.minX,
+ this.showGridLines = false,
+ this.getDrawingVerticalLine,
+ this.verticalInterval,
+ this.minY,
+ this.barRadius,
+ this.barWidth = 16});
+
+ @override
+ Widget build(BuildContext context) {
+ return Material(
+ color: Colors.white,
+ child: SizedBox(
+ width: width,
+ height: height,
+ child: BarChart(
+ BarChartData(
+ minY: minY ?? 0,
+ maxY: maxY,
+
+ barTouchData: BarTouchData(
+ handleBuiltInTouches: true,
+ touchCallback: (FlTouchEvent event, BarTouchResponse? touchResponse) {
+ // Let fl_chart handle the touch
+ },
+
+ touchTooltipData: BarTouchTooltipData(
+ getTooltipColor: (_)=>AppColors.tooltipColor,
+ getTooltipItem: (group, groupIndex, rod, rodIndex) {
+ final dataPoint = dataPoints[groupIndex];
+ return BarTooltipItem(
+ '${dataPoint.actualValue} ${dataPoint.unitOfMeasurement ?? ""}\n${DateFormat('dd MMM, yyyy').format(dataPoint.time)}',
+ TextStyle(
+ color: Colors.black,
+ fontSize: 12.f,
+ fontWeight: FontWeight.w500,
+ ),
+ );
+ },
+ ),
+ enabled: true,
+ ),
+ titlesData: FlTitlesData(
+ leftTitles: AxisTitles(
+ sideTitles: SideTitles(
+ showTitles: true,
+ reservedSize: leftLabelReservedSize ?? 80,
+ interval: leftLabelInterval ?? .1,
+ getTitlesWidget: (value, _) {
+ return leftLabelFormatter(value);
+ },
+ ),
+ ),
+ bottomTitles: AxisTitles(
+ axisNameSize: 20,
+ sideTitles: SideTitles(
+ showTitles: showBottomTitleDates,
+ reservedSize: bottomLabelReservedSize ?? 30,
+ getTitlesWidget: (value, _) {
+ return bottomLabelFormatter(value, dataPoints);
+ },
+ interval: 1,
+ ),
+ ),
+ topTitles: AxisTitles(),
+ rightTitles: AxisTitles(),
+ ),
+ borderData: FlBorderData(
+ show: true,
+ border: const Border(
+ bottom: BorderSide.none,
+ left: BorderSide(color: Colors.grey, width: .5),
+ right: BorderSide.none,
+ top: BorderSide.none,
+ ),
+ ),
+ barGroups: _buildBarGroups(dataPoints),
+
+ gridData: FlGridData(
+ show: showGridLines ?? true,
+ drawHorizontalLine: false,
+ verticalInterval: verticalInterval,
+ getDrawingVerticalLine: getDrawingVerticalLine ??
+ (value) {
+ return FlLine(
+ color: barGridColor,
+ strokeWidth: 1,
+ dashArray: [5, 5],
+ );
+ },
+ )),
+ ),
+ ),
+ );
+ }
+
+ /// Builds bar chart groups from data points
+ List _buildBarGroups(List dataPoints) {
+ return dataPoints.asMap().entries.map((entry) {
+ final index = entry.key;
+ final dataPoint = entry.value;
+ double value = (makeGraphBasedOnActualValue)
+ ? double.tryParse(dataPoint.actualValue) ?? 0.0
+ : dataPoint.value;
+
+ final barRods = [
+ BarChartRodData(
+ toY: value,
+ color: barColor,
+ width: barWidth,
+ borderRadius: barRadius ?? BorderRadius.circular(6),
+ // backDrawRodData: BackgroundBarChartRodData(
+ // show: true,
+ // toY: maxY,
+ // color: Colors.grey[100],
+ // ),
+ ),
+ ];
+
+ // Add secondary bar if provided (for grouped bar charts)
+ if (secondaryDataPoints != null && index < secondaryDataPoints!.length) {
+ final secondaryDataPoint = secondaryDataPoints![index];
+ double secondaryValue = (makeGraphBasedOnActualValue)
+ ? double.tryParse(secondaryDataPoint.actualValue) ?? 0.0
+ : secondaryDataPoint.value;
+
+ barRods.add(
+ BarChartRodData(
+ toY: secondaryValue,
+ color: secondaryBarColor ?? AppColors.blueColor,
+ width: barWidth,
+ borderRadius: barRadius ?? BorderRadius.circular(6),
+ ),
+ );
+ }
+
+ return BarChartGroupData(
+ x: index,
+ barRods: barRods,
+ barsSpace: 8.w
+ );
+ }).toList();
+ }
+}
\ No newline at end of file