diff --git a/assets/images/HealthSnap/Frame.svg b/assets/images/HealthSnap/Frame.svg
new file mode 100644
index 00000000..985f06ce
--- /dev/null
+++ b/assets/images/HealthSnap/Frame.svg
@@ -0,0 +1,48 @@
+
diff --git a/assets/images/HealthSnap/Icon.svg b/assets/images/HealthSnap/Icon.svg
new file mode 100644
index 00000000..aba5948c
--- /dev/null
+++ b/assets/images/HealthSnap/Icon.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/images/HealthSnap/background.svg b/assets/images/HealthSnap/background.svg
new file mode 100644
index 00000000..2460ab54
--- /dev/null
+++ b/assets/images/HealthSnap/background.svg
@@ -0,0 +1,37 @@
+
diff --git a/assets/images/HealthSnap/circle-arrow-doun-right.svg b/assets/images/HealthSnap/circle-arrow-doun-right.svg
new file mode 100644
index 00000000..a2510857
--- /dev/null
+++ b/assets/images/HealthSnap/circle-arrow-doun-right.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/images/HealthSnap/circle-arrow-down-02.svg b/assets/images/HealthSnap/circle-arrow-down-02.svg
new file mode 100644
index 00000000..868edb1b
--- /dev/null
+++ b/assets/images/HealthSnap/circle-arrow-down-02.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/images/HealthSnap/circle-arrow-up 02.svg b/assets/images/HealthSnap/circle-arrow-up 02.svg
new file mode 100644
index 00000000..d9ad2a6a
--- /dev/null
+++ b/assets/images/HealthSnap/circle-arrow-up 02.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/images/HealthSnap/circle-arrow-up-right.svg b/assets/images/HealthSnap/circle-arrow-up-right.svg
new file mode 100644
index 00000000..4254f8b2
--- /dev/null
+++ b/assets/images/HealthSnap/circle-arrow-up-right.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/images/HealthSnap/close_icon.svg b/assets/images/HealthSnap/close_icon.svg
new file mode 100644
index 00000000..a36264b1
--- /dev/null
+++ b/assets/images/HealthSnap/close_icon.svg
@@ -0,0 +1,4 @@
+
diff --git a/assets/images/HealthSnap/female.svg b/assets/images/HealthSnap/female.svg
new file mode 100644
index 00000000..c3e7c610
--- /dev/null
+++ b/assets/images/HealthSnap/female.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/images/HealthSnap/male.svg b/assets/images/HealthSnap/male.svg
new file mode 100644
index 00000000..bd895311
--- /dev/null
+++ b/assets/images/HealthSnap/male.svg
@@ -0,0 +1,3 @@
+
diff --git a/lib/pages/landing/home_page_2.dart b/lib/pages/landing/home_page_2.dart
index 61eaafc9..f4a0c69e 100644
--- a/lib/pages/landing/home_page_2.dart
+++ b/lib/pages/landing/home_page_2.dart
@@ -64,133 +64,160 @@ class _HomePageState2 extends State {
// child:
// SingleChildScrollView(
// physics: BouncingScrollPhysics(),
- body: SingleChildScrollView(
- child: Material(
- color: CustomColors.backgroudGreyColor,
- child: Padding(
- padding: const EdgeInsets.all(16.0),
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- // crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- SvgPicture.asset(
- 'assets/images/new/cloud_logo.svg',
- width: 150,
- height: 150,
- ),
- mHeight(16.0),
- Text(
- "Contact-Less Vitals",
- style: TextStyle(color: Colors.black, fontSize: 22, letterSpacing: -0.68, fontWeight: FontWeight.bold),
- ),
- mHeight(16.0),
- Text(
- "Select Gender:",
- textAlign: TextAlign.start,
- style: TextStyle(color: Colors.black, fontSize: 14, letterSpacing: -0.68, fontWeight: FontWeight.bold),
- ),
- mHeight(8.0),
- Container(
- padding: EdgeInsets.only(left: 6, right: 6),
- child: Row(
+ body: SafeArea(
+ child: SingleChildScrollView(
+ child: Container(
+ height: MediaQuery.of(context).size.height,
+ decoration: BoxDecoration(
+ gradient: LinearGradient(
+ begin: Alignment.topRight,
+ end: Alignment.bottomLeft,
+ // stops: [0.1, 0.3, 0.5],
+ colors: [
+ Color(0xff2B35E),
+ Color(0xff596C7C),
+ ],
+ ),
+ ),
+ child: Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 16),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+ children: [
+ SvgPicture.asset(
+ 'assets/images/new/cloud_logo.svg',
+ width: 80,
+ height: 80,
+ ),
+ // mHeight(48.0),
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
children: [
- Flexible(
+ Text(
+ "Welcome To",
+ style: TextStyle(color: Color(0XFF2B353E), fontSize: 22, letterSpacing: 1.28, fontWeight: FontWeight.normal),
+ ),
+ Text(
+ "HealthSnap",
+ style: TextStyle(color: Color(0XFF2B353E), fontSize: 26, letterSpacing: 1.28, fontWeight: FontWeight.bold),
+ ),
+ mHeight(8.0),
+ Container(
+ padding: EdgeInsets.only(left: 6, right: 6),
child: Row(
children: [
- Radio(
- value: TranslationBase.of(context).male,
- groupValue: radioValue,
- onChanged: (v) {
- setState(() {
- radioValue = v!;
- });
- },
+ Flexible(
+ child: Row(
+ children: [
+ Radio(
+ value: TranslationBase.of(context).male,
+ groupValue: radioValue,
+ onChanged: (v) {
+ setState(() {
+ radioValue = v!;
+ });
+ },
+ ),
+ Text(
+ TranslationBase.of(context).male,
+ style: TextStyle(
+ fontSize: 12,
+ letterSpacing: -0.48,
+ fontWeight: FontWeight.w600,
+ ),
+ ),
+ ],
+ ),
),
- Text(
- TranslationBase.of(context).male,
- style: TextStyle(
- fontSize: 12,
- letterSpacing: -0.48,
- fontWeight: FontWeight.w600,
+ Flexible(
+ child: Row(
+ children: [
+ Radio(
+ value: TranslationBase.of(context).female,
+ groupValue: radioValue,
+ onChanged: (v) {
+ setState(() {
+ radioValue = v!;
+ });
+ },
+ ),
+ Text(
+ TranslationBase.of(context).female,
+ style: TextStyle(
+ fontSize: 12,
+ letterSpacing: -0.48,
+ fontWeight: FontWeight.w600,
+ ),
+ ),
+ ],
),
),
],
),
),
- Flexible(
- child: Row(
- children: [
- Radio(
- value: TranslationBase.of(context).female,
- groupValue: radioValue,
- onChanged: (v) {
- setState(() {
- radioValue = v!;
- });
+ Row(
+ children: [
+ Expanded(
+ child: inputWidget(TranslationBase.of(context).weightAdd + " (kg)", "Enter", weightTextController),
+ ),
+ mWidth(8),
+ Expanded(
+ child: inputWidget(TranslationBase.of(context).height + " (cm)", "Enter", heightTextController),
+ ),
+ ],
+ ),
+ mHeight(16.0),
+ inputWidget(TranslationBase.of(context).age, "Enter", ageTextController),
+ mHeight(16.0),
+ // inputWidget(TranslationBase.of(context).weightAdd + " (kg)", "Enter", weightTextController),
+ // mHeight(16.0),
+ // inputWidget(TranslationBase.of(context).height + " (cm)", "Enter", heightTextController),
+ // mHeight(16.0),
+ DefaultButton(
+ TranslationBase.of(context).start,
+ (ageTextController.text == "" || weightTextController.text == "" || heightTextController.text == "")
+ ? null
+ : () {
+ final UserInfo userInfo = UserInfo(
+ age: double.parse(ageTextController.text),
+ gender: radioValue == TranslationBase.of(context).male ? Gender.male : Gender.female,
+ weight: double.parse(weightTextController.text),
+ // kg, Optional
+ height: double.parse(heightTextController.text),
+ // cm, Optional
+ waistCircumference: 0,
+ // cm Optional
+ userId: 'dbd13e86-47f4-4a43-85f6-cf62fa750117');
+ Navigator.push(context, FadePage(page: VitalSigns(userInfo: userInfo)));
},
- ),
- Text(
- TranslationBase.of(context).female,
- style: TextStyle(
- fontSize: 12,
- letterSpacing: -0.48,
- fontWeight: FontWeight.w600,
- ),
- ),
- ],
- ),
+ color: Color(0XFF2B353E),
+ disabledColor: CustomColors.grey,
),
],
),
- ),
- mHeight(16.0),
- inputWidget(TranslationBase.of(context).age, "0", ageTextController),
- mHeight(16.0),
- inputWidget(TranslationBase.of(context).weightAdd + " (kg)", "0", weightTextController),
- mHeight(16.0),
- inputWidget(TranslationBase.of(context).height + " (cm)", "0", heightTextController),
- mHeight(16.0),
- DefaultButton(
- TranslationBase.of(context).start,
- (ageTextController.text == "" || weightTextController.text == "" || heightTextController.text == "")
- ? null
- : () {
- final UserInfo userInfo = UserInfo(
- age: double.parse(ageTextController.text),
- gender: radioValue == TranslationBase.of(context).male ? Gender.male : Gender.female,
- weight: double.parse(weightTextController.text),
- // kg, Optional
- height: double.parse(heightTextController.text),
- // cm, Optional
- waistCircumference: 0,
- // cm Optional
- userId: 'dbd13e86-47f4-4a43-85f6-cf62fa750117');
- Navigator.push(context, FadePage(page: VitalSigns(userInfo: userInfo)));
- },
- color: CustomColors.green,
- disabledColor: CustomColors.grey,
- ),
- // HomePageFragment2(
- // model,
- // onLoginClick: () {
- // widget.onLoginClick!();
- // // FirebaseCrashlytics.instance.crash();
- // // Navigator.pushNamed(
- // // context,
- // // "zoom_call_page",
- // // arguments: CallArguments("h9qkpf02", "123", "Patient", "40", "1", false),
- // // );
- // },
- // onPharmacyClick: () {
- // // getPharmacyToken(model);
- // Uri uri = Uri.parse(PHARMACY_REDIRECT_URL);
- // launchUrl(uri, mode: LaunchMode.externalApplication);
- // },
- // onMedicalFileClick: () {
- // widget.onMedicalFileClick!();
- // },
- // )
- ],
+ // HomePageFragment2(
+ // model,
+ // onLoginClick: () {
+ // widget.onLoginClick!();
+ // // FirebaseCrashlytics.instance.crash();
+ // // Navigator.pushNamed(
+ // // context,
+ // // "zoom_call_page",
+ // // arguments: CallArguments("h9qkpf02", "123", "Patient", "40", "1", false),
+ // // );
+ // },
+ // onPharmacyClick: () {
+ // // getPharmacyToken(model);
+ // Uri uri = Uri.parse(PHARMACY_REDIRECT_URL);
+ // launchUrl(uri, mode: LaunchMode.externalApplication);
+ // },
+ // onMedicalFileClick: () {
+ // widget.onMedicalFileClick!();
+ // },
+ // )
+ ],
+ ),
),
),
),
@@ -225,11 +252,11 @@ class _HomePageState2 extends State {
Widget inputWidget(String _labelText, String _hintText, TextEditingController _controller, {String? prefix, bool isEnable = true, bool hasSelection = false}) {
return Container(
- padding: EdgeInsets.only(left: 16, right: 16, bottom: 15, top: 15),
+ padding: EdgeInsets.only(left: 16, right: 16, bottom: 10, top: 10),
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
- color: Colors.white,
+ color: CustomColors.appBackgroudGreyColor,
border: Border.all(
color: Color(0xffefefef),
width: 1,
diff --git a/lib/pages/landing/landing_page.dart b/lib/pages/landing/landing_page.dart
index 618dc894..751dc5f6 100644
--- a/lib/pages/landing/landing_page.dart
+++ b/lib/pages/landing/landing_page.dart
@@ -479,96 +479,101 @@ class _LandingPageState extends State with WidgetsBindingObserver {
model = Provider.of(context);
// currentTab == 0 ? 45 : 0.0
return Scaffold(
- appBar: currentTab == 0
- ? PreferredSize(
- preferredSize: Size.fromHeight(currentTab == 0 ? 45 : 0.0),
- child: AppBar(
- elevation: 0,
- backgroundColor: CustomColors.backgroudGreyColor,
- //Changed By Aamir
- // textTheme: TextTheme(
- // headline6: TextStyle(color: Theme.of(context).textTheme.headline1!.color, fontWeight: FontWeight.bold),
- // ),
- title: Text(
- getText(currentTab).toUpperCase(),
- style: TextStyle(
- fontWeight: FontWeight.bold,
- color: currentTab == 0 ? CustomColors.backgroudGreyColor : CustomColors.accentColor,
- // : Theme.of(context).textTheme.headline1!.color,
- fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins'),
- // bold: true,
- ),
- leading: Builder(
- builder: (BuildContext context) {
- return new Stack(
- children: [
- currentTab == 0
- ? IconButton(
- icon: SvgPicture.asset("assets/images/new/menu.svg"),
- // color: Theme.of(context).textTheme.headline1!.color,
- color: CustomColors.white,
- onPressed: () => Scaffold.of(context).openDrawer(),
- )
- : IconButton(
- icon: Icon(Icons.arrow_back),
- onPressed: () {
- setState(() {
- currentTab = 0;
- });
- pageController.jumpToPage(0);
- },
- ),
- projectViewModel.isLogin && model.notificationsCount != null && !projectViewModel.isLoginChild
- ? Positioned(
- right: projectViewModel.isArabic ? 35 : 0,
- top: 5,
- child: new Container(
- padding: EdgeInsets.all(4),
- decoration: new BoxDecoration(
- color: CustomColors.accentColor,
- borderRadius: BorderRadius.circular(20),
- ),
- constraints: BoxConstraints(
- minWidth: 20,
- minHeight: 20,
- ),
- child: Text(
- model.notificationsCount.toString(),
- style: TextStyle(
- color: Colors.white,
- fontSize: projectViewModel.isArabic ? 8 : 9,
- ),
- textAlign: TextAlign.center,
- ),
- ),
- )
- : SizedBox()
- ],
- );
- },
- ),
- actions: [
- // IconButton(
- // //iconSize: 70,
- // icon: Icon(
- // projectViewModel.isLogin ? Icons.settings : Icons.login,
- // color: Theme.of(context).textTheme.headline1.color,
- // ),
- // onPressed: () {
- // if (projectViewModel.isLogin)
- // Navigator.of(context).pushNamed(
- // SETTINGS,
- // );
- // else
- // login();
- // }, //do something,
- // )
- ],
- centerTitle: true,
- ),
- )
- : null,
- drawer: SafeArea(child: AppDrawer()),
+ appBar:
+ // currentTab == 0
+ // ?
+ // PreferredSize(
+ // preferredSize: Size.fromHeight(currentTab == 0 ? 45 : 0.0),
+ // child: AppBar(
+ // elevation: 0,
+ // backgroundColor: CustomColors.backgroudGreyColor,
+ // //Changed By Aamir
+ // // textTheme: TextTheme(
+ // // headline6: TextStyle(color: Theme.of(context).textTheme.headline1!.color, fontWeight: FontWeight.bold),
+ // // ),
+ // title: Text(
+ // getText(currentTab).toUpperCase(),
+ // style: TextStyle(
+ // fontWeight: FontWeight.bold,
+ // color: currentTab == 0 ? CustomColors.backgroudGreyColor : CustomColors.accentColor,
+ // // : Theme.of(context).textTheme.headline1!.color,
+ // fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins'),
+ // // bold: true,
+ // ),
+ // leading: Builder(
+ // builder: (BuildContext context) {
+ // return new Stack(
+ // children: [
+ // // currentTab == 0
+ // // ?
+ // // IconButton(
+ // // icon: SvgPicture.asset("assets/images/new/menu.svg"),
+ // // // color: Theme.of(context).textTheme.headline1!.color,
+ // // color: CustomColors.white,
+ // // onPressed: () => Scaffold.of(context).openDrawer(),
+ // // )
+ // // :
+ // // IconButton(
+ // // icon: Icon(Icons.arrow_back),
+ // // onPressed: () {
+ // // setState(() {
+ // // currentTab = 0;
+ // // });
+ // // pageController.jumpToPage(0);
+ // // },
+ // // ),
+ // projectViewModel.isLogin && model.notificationsCount != null && !projectViewModel.isLoginChild
+ // ? Positioned(
+ // right: projectViewModel.isArabic ? 35 : 0,
+ // top: 5,
+ // child: new Container(
+ // padding: EdgeInsets.all(4),
+ // decoration: new BoxDecoration(
+ // color: CustomColors.accentColor,
+ // borderRadius: BorderRadius.circular(20),
+ // ),
+ // constraints: BoxConstraints(
+ // minWidth: 20,
+ // minHeight: 20,
+ // ),
+ // child: Text(
+ // model.notificationsCount.toString(),
+ // style: TextStyle(
+ // color: Colors.white,
+ // fontSize: projectViewModel.isArabic ? 8 : 9,
+ // ),
+ // textAlign: TextAlign.center,
+ // ),
+ // ),
+ // )
+ // : SizedBox()
+ // ],
+ // );
+ // },
+ // ),
+ // actions: [
+ // // IconButton(
+ // // //iconSize: 70,
+ // // icon: Icon(
+ // // projectViewModel.isLogin ? Icons.settings : Icons.login,
+ // // color: Theme.of(context).textTheme.headline1.color,
+ // // ),
+ // // onPressed: () {
+ // // if (projectViewModel.isLogin)
+ // // Navigator.of(context).pushNamed(
+ // // SETTINGS,
+ // // );
+ // // else
+ // // login();
+ // // }, //do something,
+ // // )
+ // ],
+ // centerTitle: true,
+ // ),
+ // )
+ // :
+ null,
+ // drawer: SafeArea(child: AppDrawer()),
extendBody: false,
body: WillPopScope(
onWillPop: onWillPop,
diff --git a/lib/theme/colors.dart b/lib/theme/colors.dart
index a9d4e437..46d87856 100644
--- a/lib/theme/colors.dart
+++ b/lib/theme/colors.dart
@@ -18,7 +18,7 @@ class CustomColors {
static const Color pharmacyGreyColor = Color(0xFFDBDBDB);
static const Color backgroudGreyColor = Color(0xFFEFEFEF);
static const Color appBackgroudGreyColor = Color(0xFFF7F7F7);
- static const Color appBackgroudGrey2Color = Color(0xFFF8F8F8);
+ static const Color appBackgroudGrey2Color = Color(0xFFFAFAFA);
static const Color green = Color(0xFF359846);
static const Color orange = Color(0xFFCC9B14);
static const Color darkOrange = Color(0xFFE16F17);
diff --git a/lib/vital_signs/components/barWidget.dart b/lib/vital_signs/components/barWidget.dart
new file mode 100644
index 00000000..6ef40422
--- /dev/null
+++ b/lib/vital_signs/components/barWidget.dart
@@ -0,0 +1,457 @@
+import 'dart:math';
+
+import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
+import 'package:diplomaticquarterapp/uitl/utils.dart';
+import 'package:flutter/material.dart';
+
+enum ResultTypes { criticalLow, low, normal, high, criticalHigh }
+
+class ItemResultCardWidget extends StatelessWidget {
+ final Widget child;
+
+ const ItemResultCardWidget({
+ Key? key,
+ required this.child,
+ }) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ return Row(
+ children: [
+ Expanded(
+ child: Padding(
+ padding: const EdgeInsets.only(left: 12, right: 12, bottom: 12),
+ child: child,
+ ),
+ ),
+ ],
+ );
+ }
+}
+
+class CustomResultProgressBar extends StatelessWidget {
+ final double percentage;
+ final String value;
+ final ResultTypes type;
+
+ const CustomResultProgressBar({Key? key, required this.percentage, required this.value, required this.type}) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ return LayoutBuilder(builder: (context, constraints) {
+ final double totalWidth = constraints.maxWidth;
+ final double spacing = 2;
+ final double tooltipPosition = (totalWidth * (percentage / 100)).clamp(0, totalWidth - 50);
+ return Stack(
+ children: [
+ Row(
+ children: [
+ _buildResultBar(
+ flex: 2,
+ color: Color(0xFFDE7676),
+ title: "Poor",
+ ),
+ SizedBox(
+ width: spacing,
+ ),
+ _buildResultBar(
+ flex: 3,
+ color: Color(0xff84d368),
+ title: "Good",
+ ),
+ SizedBox(
+ width: spacing,
+ ),
+ _buildResultBar(
+ flex: 2,
+ color: Color(0xFF14a45f),
+ title: "Excellent",
+ ),
+ SizedBox(
+ width: spacing,
+ ),
+ // _buildResultBar(
+ // flex: 2,
+ // color: Color(0xFFEAB157),
+ // title: "High",
+ // ),
+ // SizedBox(
+ // width: spacing,
+ // ),
+ // _buildResultBar(
+ // flex: 3,
+ // color: Color(0xFFDE7676),
+ // title: "Critical High",
+ // ),
+ ],
+ ),
+ Positioned(
+ left: tooltipPosition,
+ top: 33,
+ child: Column(
+ children: [
+ TextCloud(
+ text: "${value}",
+ color: percentage == 4 ? Color(0xFFDE7676) : percentage == 40 ? Color(0xff84d368) : Color(0xFF14a45f),
+ // color: type == ResultTypes.criticalLow || type == ResultTypes.criticalHigh
+ // ? Color(0xFFDE7676)
+ // : type == ResultTypes.low || type == ResultTypes.high
+ // ? Color(0xFFEAB157)
+ // : type == ResultTypes.normal
+ // ? Color(0xFF09AA28)
+ // : Color(0xFF09AA28),
+ width: 50,
+ height: 20,
+ padding: EdgeInsets.zero,
+ axisDirection: AxisDirection.up,
+ ),
+ ],
+ ),
+ ),
+ ],
+ );
+ });
+ }
+
+ Widget _buildResultBar({
+ required int flex,
+ required Color color,
+ required String title,
+ }) {
+ return Expanded(
+ flex: flex,
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ Text(
+ title,
+ style: const TextStyle(fontSize: 10, fontFamily: 'Poppins', letterSpacing: -0.24, fontWeight: FontWeight.w500),
+ textAlign: TextAlign.center,
+ ),
+ const SizedBox(height: 5),
+ Container(
+ height: 5,
+ decoration: BoxDecoration(
+ color: color,
+ borderRadius: BorderRadius.all(Radius.circular(10)),
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+}
+
+class TextCloud extends StatelessWidget {
+ final String text; // write here box content
+ final Color color; // Set box Color
+ final EdgeInsets padding; // Set content padding
+ final double width; // Box width
+ final double height; // Box Height
+ final AxisDirection axisDirection; // Set triangle location up,left,right,down
+ final double locationOfArrow; // set between 0 and 1, If 0.5 is set triangle position will be centered
+ const TextCloud({
+ super.key,
+ required this.text,
+ this.color = Colors.white,
+ this.padding = const EdgeInsets.all(10),
+ this.width = 200,
+ this.height = 100,
+ this.axisDirection = AxisDirection.down,
+ this.locationOfArrow = 0.5,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ Size arrowSize = const Size(12, 12);
+ return Stack(
+ clipBehavior: Clip.none,
+ children: [
+ Container(
+ width: width,
+ height: height,
+ padding: padding,
+ decoration: BoxDecoration(
+ color: color,
+ borderRadius: BorderRadius.circular(10),
+ ),
+ child: Center(
+ child: Text(
+ text,
+ style: TextStyle(color: Colors.white, fontSize: 12),
+ )),
+ ),
+ Builder(builder: (context) {
+ double angle = 0;
+ switch (axisDirection) {
+ case AxisDirection.left:
+ angle = pi * -0.5;
+ break;
+ case AxisDirection.up:
+ angle = pi * -2;
+ break;
+ case AxisDirection.right:
+ angle = pi * 0.5;
+ break;
+ case AxisDirection.down:
+ angle = pi;
+ break;
+ default:
+ angle = 0;
+ }
+ return Positioned(
+ left: axisDirection == AxisDirection.left
+ ? -arrowSize.width + 5
+ : (axisDirection == AxisDirection.up || axisDirection == AxisDirection.down ? width * locationOfArrow - arrowSize.width / 2 : null),
+ right: axisDirection == AxisDirection.right ? -arrowSize.width + 5 : null,
+ top: axisDirection == AxisDirection.up
+ ? -arrowSize.width + 5
+ : (axisDirection == AxisDirection.right || axisDirection == AxisDirection.left ? height * locationOfArrow - arrowSize.width / 2 : null),
+ bottom: axisDirection == AxisDirection.down ? -arrowSize.width + 5 : null,
+ child: Transform.rotate(
+ angle: angle,
+ child: CustomPaint(
+ size: arrowSize,
+ painter: ArrowPaint(color: color),
+ ),
+ ),
+ );
+ })
+ ],
+ );
+ }
+}
+
+class ArrowPaint extends CustomPainter {
+ final Color color;
+
+ ArrowPaint({required this.color});
+
+ @override
+ void paint(Canvas canvas, Size size) {
+ Path path_0 = Path();
+ path_0.moveTo(size.width * 0.5745375, size.height * 0.06573708);
+ path_0.lineTo(size.width * 0.9813667, size.height * 0.8794000);
+ path_0.cubicTo(size.width * 1.001950, size.height * 0.9205625, size.width * 0.9852625, size.height * 0.9706208, size.width * 0.9441000, size.height * 0.9912000);
+ path_0.cubicTo(size.width * 0.9325250, size.height * 0.9969875, size.width * 0.9197667, size.height, size.width * 0.9068292, size.height);
+ path_0.lineTo(size.width * 0.09316958, size.height);
+ path_0.cubicTo(size.width * 0.04714583, size.height, size.width * 0.009836208, size.height * 0.9626917, size.width * 0.009836208, size.height * 0.9166667);
+ path_0.cubicTo(size.width * 0.009836208, size.height * 0.9037292, size.width * 0.01284829, size.height * 0.8909708, size.width * 0.01863392, size.height * 0.8794000);
+ path_0.lineTo(size.width * 0.4254625, size.height * 0.06573708);
+ path_0.cubicTo(size.width * 0.4460458, size.height * 0.02457225, size.width * 0.4961042, size.height * 0.007886875, size.width * 0.5372667, size.height * 0.02846929);
+ path_0.cubicTo(size.width * 0.5533958, size.height * 0.03653296, size.width * 0.5664708, size.height * 0.04961000, size.width * 0.5745375, size.height * 0.06573708);
+ path_0.close();
+
+ Paint paint_0_fill = Paint()..style = PaintingStyle.fill;
+ paint_0_fill.color = color;
+ canvas.drawPath(path_0, paint_0_fill);
+ }
+
+ @override
+ bool shouldRepaint(covariant CustomPainter oldDelegate) {
+ return true;
+ }
+}
+
+class ItemResultCardWidgetWithParamsVitalSign extends StatelessWidget {
+ final String title;
+ final String subTitle;
+ final String note;
+ final String source;
+ final String referenceRange;
+ final double percentage;
+ final String buttonText;
+ final ResultTypes type;
+ final bool isArabic;
+ final Function()? onButtonPressed;
+
+ const ItemResultCardWidgetWithParamsVitalSign({
+ Key? key,
+ required this.title,
+ required this.subTitle,
+ required this.referenceRange,
+ required this.percentage,
+ required this.note,
+ required this.source,
+ required this.buttonText,
+ required this.type,
+ this.onButtonPressed,
+ this.isArabic = false,
+ }) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ final fontFamily = isArabic ? 'Cairo' : 'Poppins';
+
+ return Container(
+ // margin: const EdgeInsets.only(left: 0, right: 0, top: 11),
+ // decoration: BoxDecoration(
+ // borderRadius: const BorderRadius.all(Radius.circular(10)),
+ // border: Border(
+ // left: BorderSide(
+ // color: type == ResultTypes.criticalLow || type == ResultTypes.criticalHigh
+ // ? Color(0xFFDE7676)
+ // : type == ResultTypes.low || type == ResultTypes.high
+ // ? Color(0xFFEAB157)
+ // : type == ResultTypes.normal
+ // ? Color(0xFF09AA28)
+ // : Color(0xFF09AA28),
+ // width: MediaQuery.of(context).size.width * 0.015,
+ // ),
+ // ),
+ // color: Colors.white,
+ // boxShadow: [
+ // BoxShadow(
+ // color: Colors.grey.withOpacity(0.2),
+ // spreadRadius: 2,
+ // blurRadius: 5,
+ // offset: const Offset(0, 3),
+ // ),
+ // ],
+ // ),
+ child: Padding(
+ padding: const EdgeInsets.all(0.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ mainAxisSize: MainAxisSize.max,
+ children: [
+ // Title Row
+ // Row(
+ // mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ // children: [
+ // Text(
+ // title,
+ // style: TextStyle(
+ // fontSize: 16,
+ // fontFamily: fontFamily,
+ // fontWeight: FontWeight.w600,
+ // color: const Color(0xff2E303A),
+ // letterSpacing: -0.64,
+ // height: 16 / 25,
+ // ),
+ // ),
+ // GestureDetector(
+ // onTap: onButtonPressed,
+ // child: Utils.tableColumnValueWithUnderLine(TranslationBase.of(context).viewFlowChart, isLast: true, isCapitable: false),
+ // ),
+ // ],
+ // ),
+ // const SizedBox(height: 8),
+ // Row(
+ // crossAxisAlignment: CrossAxisAlignment.start,
+ // children: [
+ // ResultStatusWidget(type: type),
+ // SizedBox(width: 5),
+ // Column(
+ // crossAxisAlignment: CrossAxisAlignment.start,
+ // children: [
+ // Text(
+ // subTitle,
+ // style: TextStyle(fontSize: 14, fontFamily: fontFamily, fontWeight: FontWeight.w600, color: const Color(0xff2E303A), letterSpacing: -0.56),
+ // ),
+ // Text(
+ // "Reference Range \n $referenceRange",
+ // style: TextStyle(
+ // fontSize: 10,
+ // fontFamily: fontFamily,
+ // fontWeight: FontWeight.w600,
+ // color: const Color(0xff2E303A),
+ // letterSpacing: -0.4,
+ // ),
+ // ),
+ // ],
+ // ),
+ // ],
+ // ),
+ // const SizedBox(height: 10),
+ // Progress Bar
+ SizedBox(
+ height: 55,
+ width: 220,
+ child: CustomResultProgressBar(
+ percentage: percentage,
+ value: subTitle,
+ type: type,
+ ),
+ ),
+ // const SizedBox(height: 12),
+ // Note Section
+ // if (note.isNotEmpty)
+ // Column(
+ // crossAxisAlignment: CrossAxisAlignment.start,
+ // children: [
+ // const Divider(color: Color(0xFFEFEFEF), thickness: 1),
+ // const SizedBox(height: 10),
+ // Text(
+ // "Notes:",
+ // style: TextStyle(
+ // fontSize: 12,
+ // color: const Color(0xFF2E303A),
+ // letterSpacing: -0.4,
+ // fontWeight: FontWeight.bold,
+ // ),
+ // ),
+ // Text(
+ // note,
+ // style: TextStyle(
+ // fontSize: 12,
+ // color: const Color(0xFF575757),
+ // letterSpacing: -0.4,
+ // fontWeight: FontWeight.bold,
+ // ),
+ // ),
+ // ],
+ // ),
+ const SizedBox(height: 3),
+ ],
+ ),
+ ),
+ );
+ }
+}
+
+class ResultStatusWidget extends StatelessWidget {
+ final ResultTypes type;
+
+ const ResultStatusWidget({
+ Key? key,
+ required this.type,
+ }) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ Color? color;
+ IconData? icon;
+
+ switch (type) {
+ case ResultTypes.criticalLow:
+ color = const Color(0xFFDE7676);
+ icon = Icons.arrow_circle_down;
+ break;
+ case ResultTypes.low:
+ color = const Color(0xFFEAB157);
+ icon = Icons.arrow_circle_down;
+ break;
+ case ResultTypes.criticalHigh:
+ color = const Color(0xFFDE7676);
+ icon = Icons.arrow_circle_up;
+ break;
+ case ResultTypes.high:
+ color = const Color(0xFFEAB157);
+ icon = Icons.arrow_circle_up;
+ break;
+ case ResultTypes.normal:
+ color = const Color(0xFF09AA28);
+ icon = Icons.check_circle;
+ break;
+ }
+
+ // Return the icon if defined, otherwise a placeholder widget
+ return icon != null
+ ? Icon(
+ icon,
+ color: color,
+ )
+ : const SizedBox(); // Use SizedBox to keep the layout consistent
+ }
+}
\ No newline at end of file
diff --git a/lib/vital_signs/components/vital_sign_widget.dart b/lib/vital_signs/components/vital_sign_widget.dart
index 4630ae26..3c007fe5 100644
--- a/lib/vital_signs/components/vital_sign_widget.dart
+++ b/lib/vital_signs/components/vital_sign_widget.dart
@@ -1,6 +1,7 @@
import 'package:diplomaticquarterapp/theme/colors.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/uitl/utils_new.dart';
+import 'package:diplomaticquarterapp/vital_signs/components/barWidget.dart';
import 'package:diplomaticquarterapp/vital_signs/data/vitals_benchmark.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
@@ -13,11 +14,13 @@ class VitalSignWidget extends StatelessWidget {
final Map? lookupValues;
final Map? bloodPressureValues;
final Color? textColor;
+ final String vitalName;
const VitalSignWidget({
Key? key,
required this.vitalSignName,
required this.vitalSignValue,
+ required this.vitalName,
this.textColor,
required this.condition,
required this.vectorUrl,
@@ -27,268 +30,345 @@ class VitalSignWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
- return Card(
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(8),
- ),
- color: Colors.white,
- elevation: 2,
- shadowColor: CustomColors.lightGreyColor,
- child: Padding(
- padding: const EdgeInsets.all(12.0),
- child: Column(crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [
- Row(
- children: [
- SvgPicture.asset(vectorUrl, width: 36.0, height: 36.0),
- SizedBox(
- width: 16,
+ return Container(
+ child: Card(
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(8),
+ ),
+ color: Colors.white,
+ elevation: 2,
+ shadowColor: CustomColors.lightGreyColor,
+ child: Container(
+ decoration: BoxDecoration(
+ borderRadius: const BorderRadius.all(Radius.circular(8)),
+ border: Border(
+ left: BorderSide(
+ color: condition is RangeConditionWithTitle ? getColor(condition.current.interpretation) : getColor(condition.systolic?.systolic.interpretation),
+ // type == ResultTypes.criticalLow || type == ResultTypes.criticalHigh
+ // ?
+ // Color(0xFFDE7676),
+ // : type == ResultTypes.low || type == ResultTypes.high
+ // ? Color(0xFFEAB157)
+ // : type == ResultTypes.normal
+ // ? Color(0xFF09AA28)
+ // : Color(0xFF09AA28),
+ width: MediaQuery.of(context).size.width * 0.015,
),
- Text(
- vitalSignName,
- textAlign: TextAlign.start,
- style: TextStyle(
- fontSize: 18,
- fontWeight: FontWeight.w600,
- color: textColor ?? Colors.white,
- ),
+ ),
+ color: Colors.white,
+ boxShadow: [
+ BoxShadow(
+ color: Colors.grey.withOpacity(0.2),
+ spreadRadius: 2,
+ blurRadius: 5,
+ offset: const Offset(0, 3),
),
],
),
- SizedBox(
- height: 8,
- ),
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Text(
- "$vitalSignValue ${condition.unit}",
- style: TextStyle(
- fontSize: 14,
- color: textColor ?? Colors.white,
- fontWeight: FontWeight.w500,
+ child: Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 8),
+ child: Column(crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [
+ Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: Text(
+ vitalSignName,
+ textAlign: TextAlign.start,
+ style: TextStyle(
+ fontSize: 18,
+ fontWeight: FontWeight.w600,
+ color: textColor ?? Colors.white,
+ ),
),
),
- SizedBox(
- width: 8,
- ),
- if (condition is RangeConditionWithTitle)
- Status(
- status: "${TranslationBase.of(context).getValue(condition.current?.interpretation ?? '')}",
- originalData: condition.current?.interpretation ?? '',
- )
- else if (condition is RangeConditionForBloodPressure)
- Status(
- status: "${TranslationBase.of(context).getValue(condition.systolic?.systolic.interpretation ?? '')}",
- originalData: condition.systolic?.systolic.interpretation ?? '',
- )
- // Text(
- // "${TranslationBase.of(context).getValue(condition.current?.quantitativeInterpretation ?? '')}",
- // style: TextStyle(
- // fontSize: 14,
- // color: textColor ?? Colors.white,
- // fontWeight: FontWeight.w500,
- // ),
+ // SizedBox(
+ // height: 8,
// ),
- ],
- ),
- SizedBox(
- height: 8,
- ),
- // SizedBox(
- // height: 30,
- // child: Row(mainAxisSize: MainAxisSize.max, children: [
- if (condition is RangeConditionWithTitle)
- SizedBox(
- height: 30,
- child: Row(mainAxisSize: MainAxisSize.max, children: [
- Expanded(
- flex: 1,
- child: ListView.separated(
- separatorBuilder: (_, __) => SizedBox(
- width: 8,
- ),
- scrollDirection: Axis.horizontal,
- shrinkWrap: true,
- itemCount: condition.condition?.length ?? 0,
- itemBuilder: (_, index) => RangeWidget(
- title: condition.condition?[index].title ?? 'test',
- isSelected: condition.condition?[index].isInRange(vitalSignValue) == true,
- originalData: condition.current?.interpretation ?? '',
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ Container(
+ padding: const EdgeInsets.symmetric(horizontal: 8.0),
+ transform: Matrix4.translationValues(0.0, -8.0, 0.0),
+ width: 80,
+ child: Text(
+ "$vitalSignValue ${condition.unit}",
+ textAlign: TextAlign.start,
+ style: TextStyle(
+ fontSize: 14,
+ color: CustomColors.grey,
+ fontWeight: FontWeight.bold,
+ ),
),
),
- ),
- ]),
- ),
- // Flexible(
- // flex: 1,
- // child: ListView.separated(
- // physics: NeverScrollableScrollPhysics(),
- // separatorBuilder: (_, __) => SizedBox(
- // width: 8,
- // ),
- // shrinkWrap: true,
- // itemCount: lookupValues?.length ?? 0,
- // itemBuilder: (_, index) {
- // var key = lookupValues?.keys.elementAt(index);
- // return RangeWidget(
- // title: key ?? '',
- // values: lookupValues?[key] ?? [],
- // isSelected: false,
- // );
- // }),
- // ),
+ // if (condition is RangeConditionWithTitle)
+ ItemResultCardWidgetWithParamsVitalSign(
+ title: "Creatinine",
+ subTitle: vitalSignValue,
+ referenceRange: "64-104",
+ // percentage: 4,
+ percentage: getPercentage(vitalName, vitalSignValue, condition is RangeConditionWithTitle ? condition.current.interpretation : condition.systolic?.systolic.interpretation),
+ note: "Mayoclinic is the source of pediatrics value",
+ source: "source",
+ buttonText: "Click",
+ type: ResultTypes.criticalLow)
+ // else if (condition is RangeConditionForBloodPressure)
+ // Status(
+ // status: "${TranslationBase.of(context).getValue(condition.systolic?.systolic.interpretation ?? '')}",
+ // originalData: condition.systolic?.systolic.interpretation ?? '',
+ // )
+ // Text(
+ // "${TranslationBase.of(context).getValue(condition.current?.quantitativeInterpretation ?? '')}",
+ // style: TextStyle(
+ // fontSize: 14,
+ // color: textColor ?? Colors.white,
+ // fontWeight: FontWeight.w500,
+ // ),
+ // ),
+ ],
+ ),
+ // SizedBox(
+ // height: 8,
+ // ),
+ // SizedBox(
+ // height: 30,
+ // child: Row(mainAxisSize: MainAxisSize.max, children: [
- if (condition is RangeConditionForBloodPressure)
- SizedBox(
- height: 30,
- child: Row(mainAxisSize: MainAxisSize.max, children: [
- Expanded(
- flex: 1,
- child: ListView.separated(
- separatorBuilder: (_, __) => SizedBox(
- width: 8,
- ),
- scrollDirection: Axis.horizontal,
- shrinkWrap: true,
- itemCount: condition.condition?.length ?? 0,
- itemBuilder: (_, currentIndex) {
- var title = condition.condition?[currentIndex].quotient ?? '';
- return RangeWidget(
- title: title,
- isSelected: condition.condition?[currentIndex]?.getValue("systolic-lng")?.isSelected == true,
- originalData: condition.systolic?.systolic.interpretation ?? '',
- );
- }),
- ),
- ]),
- ),
- // Flexible(
- // flex: 1,
- // child: ListView.separated(
- // separatorBuilder: (_, __) => SizedBox(
- // width: 8,
- // ),
- // physics: NeverScrollableScrollPhysics(),
- // shrinkWrap: true,
- // itemCount: bloodPressure.length ?? 0,
- // itemBuilder: (_, index) {
- // // return RangeWidget(
- // // title: key??'',
- // // values: lookupValues?[key]??[],isSelected: false,
- // // );
- // return Column(
- // children: [
- // Row(
- // mainAxisAlignment: MainAxisAlignment.spaceBetween,
- // children: [
- // Text(
- // TranslationBase.of(context)
- // .getValue(bloodPressure[index] ?? ''),
- // textAlign: TextAlign.center,
- // style:
- // TextStyle(color: Colors.black, fontSize: 16),
- // ),
- //
- // Status(
- // status:
- // "${TranslationBase.of(context).getValue(condition.getValue(bloodPressure[index])?.quantitativeInterpretation ?? '')}",
- // originalData:condition.getValue(bloodPressure[index])?.quantitativeInterpretation ?? '' ,
- // )
- // ],
- // ),
- // SizedBox(height: 16),
- // SizedBox(
- // height: 30,
- // child: Row(
- // mainAxisSize: MainAxisSize.max,
- // children: [
- // Expanded(
- // flex: 1,
- // child: ListView.separated(
- // separatorBuilder: (_, __) => SizedBox(
- // width: 8,
- // ),
- // scrollDirection: Axis.horizontal,
- // shrinkWrap: true,
- // itemCount:
- // condition.condition?.length ?? 0,
- // itemBuilder: (_, currentIndex) {
- // var title = condition
- // .condition?[currentIndex]
- // .getValue(
- // bloodPressure[index]).title ??
- // '';
- // return RangeWidget(
- // title: title,
- // isSelected: condition
- // .condition?[currentIndex]
- // ?.getValue(
- // bloodPressure[index])
- // ?.isSelected ==
- // true,
- // );
- // }),
- // ),
- // ]),
- // ),
- // SizedBox(height: 16),
- // // SizedBox(
- // // height:220,
- // // child: ListView.separated(
- // // separatorBuilder: (_, __) => SizedBox(
- // // width: 8,
- // // ),
- // // physics: NeverScrollableScrollPhysics(),
- // // shrinkWrap: true,
- // // itemCount: bloodPressureValues?[key]?.length ?? 0,
- // // itemBuilder: (_, index) {
- // // var title = bloodPressureValues?[key]?.keys.elementAt(index);
- // //
- // // return RangeWidget(
- // // title: title ?? '',
- // // values: bloodPressureValues?[key]?[title] ?? [],
- // // isSelected: false,
- // // );
- // // }))
- // ],
- // );
- // }),
- // ),
- // ]),
- // ),
- SizedBox(
- height: 8,
+ if (condition is RangeConditionWithTitle)
+ // SizedBox(
+ // height: 30,
+ // child: Row(mainAxisSize: MainAxisSize.max, children: [
+ // Expanded(
+ // flex: 1,
+ // child: ListView.separated(
+ // separatorBuilder: (_, __) => SizedBox(
+ // width: 8,
+ // ),
+ // scrollDirection: Axis.horizontal,
+ // shrinkWrap: true,
+ // itemCount: condition.condition?.length ?? 0,
+ // itemBuilder: (_, index) => RangeWidget(
+ // title: condition.condition?[index].title ?? 'test',
+ // isSelected: condition.condition?[index].isInRange(vitalSignValue) == true,
+ // originalData: condition.current?.interpretation ?? '',
+ // ),
+ // ),
+ // ),
+ // ]),
+ // ),
+
+ // ItemResultCardWidgetWithParamsVitalSign(
+ // title: "Creatinine",
+ // subTitle: vitalSignValue,
+ // referenceRange: "64-104",
+ // // percentage: 4,
+ // percentage: getPercentage(vitalName, vitalSignValue),
+ // note: "Mayoclinic is the source of pediatrics value",
+ // source: "source",
+ // buttonText: "Click",
+ // type: ResultTypes.criticalLow),
+
+ // Flexible(
+ // flex: 1,
+ // child: ListView.separated(
+ // physics: NeverScrollableScrollPhysics(),
+ // separatorBuilder: (_, __) => SizedBox(
+ // width: 8,
+ // ),
+ // shrinkWrap: true,
+ // itemCount: lookupValues?.length ?? 0,
+ // itemBuilder: (_, index) {
+ // var key = lookupValues?.keys.elementAt(index);
+ // return RangeWidget(
+ // title: key ?? '',
+ // values: lookupValues?[key] ?? [],
+ // isSelected: false,
+ // );
+ // }),
+ // ),
+
+ if (condition is RangeConditionForBloodPressure)
+ SizedBox(
+ height: 30,
+ child: Row(mainAxisSize: MainAxisSize.max, children: [
+ Expanded(
+ flex: 1,
+ child: ListView.separated(
+ separatorBuilder: (_, __) => SizedBox(
+ width: 8,
+ ),
+ scrollDirection: Axis.horizontal,
+ shrinkWrap: true,
+ itemCount: condition.condition?.length ?? 0,
+ itemBuilder: (_, currentIndex) {
+ var title = condition.condition?[currentIndex].quotient ?? '';
+ return RangeWidget(
+ title: title,
+ isSelected: condition.condition?[currentIndex]?.getValue("systolic-lng")?.isSelected == true,
+ originalData: condition.systolic?.systolic.interpretation ?? '',
+ );
+ }),
+ ),
+ ]),
+ ),
+ // Flexible(
+ // flex: 1,
+ // child: ListView.separated(
+ // separatorBuilder: (_, __) => SizedBox(
+ // width: 8,
+ // ),
+ // physics: NeverScrollableScrollPhysics(),
+ // shrinkWrap: true,
+ // itemCount: bloodPressure.length ?? 0,
+ // itemBuilder: (_, index) {
+ // // return RangeWidget(
+ // // title: key??'',
+ // // values: lookupValues?[key]??[],isSelected: false,
+ // // );
+ // return Column(
+ // children: [
+ // Row(
+ // mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ // children: [
+ // Text(
+ // TranslationBase.of(context)
+ // .getValue(bloodPressure[index] ?? ''),
+ // textAlign: TextAlign.center,
+ // style:
+ // TextStyle(color: Colors.black, fontSize: 16),
+ // ),
+ //
+ // Status(
+ // status:
+ // "${TranslationBase.of(context).getValue(condition.getValue(bloodPressure[index])?.quantitativeInterpretation ?? '')}",
+ // originalData:condition.getValue(bloodPressure[index])?.quantitativeInterpretation ?? '' ,
+ // )
+ // ],
+ // ),
+ // SizedBox(height: 16),
+ // SizedBox(
+ // height: 30,
+ // child: Row(
+ // mainAxisSize: MainAxisSize.max,
+ // children: [
+ // Expanded(
+ // flex: 1,
+ // child: ListView.separated(
+ // separatorBuilder: (_, __) => SizedBox(
+ // width: 8,
+ // ),
+ // scrollDirection: Axis.horizontal,
+ // shrinkWrap: true,
+ // itemCount:
+ // condition.condition?.length ?? 0,
+ // itemBuilder: (_, currentIndex) {
+ // var title = condition
+ // .condition?[currentIndex]
+ // .getValue(
+ // bloodPressure[index]).title ??
+ // '';
+ // return RangeWidget(
+ // title: title,
+ // isSelected: condition
+ // .condition?[currentIndex]
+ // ?.getValue(
+ // bloodPressure[index])
+ // ?.isSelected ==
+ // true,
+ // );
+ // }),
+ // ),
+ // ]),
+ // ),
+ // SizedBox(height: 16),
+ // // SizedBox(
+ // // height:220,
+ // // child: ListView.separated(
+ // // separatorBuilder: (_, __) => SizedBox(
+ // // width: 8,
+ // // ),
+ // // physics: NeverScrollableScrollPhysics(),
+ // // shrinkWrap: true,
+ // // itemCount: bloodPressureValues?[key]?.length ?? 0,
+ // // itemBuilder: (_, index) {
+ // // var title = bloodPressureValues?[key]?.keys.elementAt(index);
+ // //
+ // // return RangeWidget(
+ // // title: title ?? '',
+ // // values: bloodPressureValues?[key]?[title] ?? [],
+ // // isSelected: false,
+ // // );
+ // // }))
+ // ],
+ // );
+ // }),
+ // ),
+ // ]),
+ // ),
+ // SizedBox(
+ // height: 8,
+ // ),
+ // Row(
+ // mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ // children: [
+ // Text(
+ // TranslationBase.of(context).getValue(
+ // condition.condition?.first.interpretation ?? ''),
+ // style: TextStyle(
+ // fontSize: 14,
+ // color: textColor ?? Colors.white,
+ // fontWeight: FontWeight.w500,
+ // ),
+ // ),
+ // Text(
+ // TranslationBase.of(context).getValue(
+ // condition.condition?.last.interpretation ?? ''),
+ // style: TextStyle(
+ // fontSize: 14,
+ // color: textColor ?? Colors.white,
+ // fontWeight: FontWeight.w500,
+ // ),
+ // ),
+ // ],
+ // ),
+ // SizedBox(
+ // height: 8,
+ // ),
+ ]),
),
- // Row(
- // mainAxisAlignment: MainAxisAlignment.spaceBetween,
- // children: [
- // Text(
- // TranslationBase.of(context).getValue(
- // condition.condition?.first.interpretation ?? ''),
- // style: TextStyle(
- // fontSize: 14,
- // color: textColor ?? Colors.white,
- // fontWeight: FontWeight.w500,
- // ),
- // ),
- // Text(
- // TranslationBase.of(context).getValue(
- // condition.condition?.last.interpretation ?? ''),
- // style: TextStyle(
- // fontSize: 14,
- // color: textColor ?? Colors.white,
- // fontWeight: FontWeight.w500,
- // ),
- // ),
- // ],
- // ),
- // SizedBox(
- // height: 8,
- // ),
- ]),
+ ),
),
);
}
+
+ double getPercentage(String vitalName, String value, String interpretationValue) {
+ double percent = 0;
+
+ switch (interpretationValue) {
+ case "poor":
+ percent = 4;
+ case "good":
+ percent = 40;
+ case "excellent":
+ percent = 75;
+ }
+
+ return percent;
+ }
+
+ getColor(title) {
+ switch (title) {
+ case "excellent":
+ return Color(0xFF14a45f);
+ case "good":
+ return Color(0xff84d368);
+ case "poor":
+ return Color(0xFFDE7676);
+ case "atRisk":
+ return Color(0xFFa2494b);
+ }
+ }
+
}
class RangeWidget extends StatelessWidget {
@@ -325,11 +405,11 @@ class RangeWidget extends StatelessWidget {
getColor(title) {
switch (title) {
case "excellent":
- return Color(0xFF275b45);
+ return Color(0xFF14a45f);
case "good":
- return Color(0xFF507a3d);
+ return Color(0xff84d368);
case "poor":
- return Color(0xFFa86452);
+ return Color(0xFFDE7676);
case "atRisk":
return Color(0xFFa2494b);
}
diff --git a/lib/vital_signs/result_screen.dart b/lib/vital_signs/result_screen.dart
index b5b17979..6178f233 100644
--- a/lib/vital_signs/result_screen.dart
+++ b/lib/vital_signs/result_screen.dart
@@ -64,6 +64,7 @@ class ResultScreen extends StatelessWidget {
condition: RangeConditionWithTitle.fromJson(vital['generalWellness']!, formatValueToTwoDp(healthResult?.holisticHealth?.generalWellness)),
vitalSignValue: formatValueToTwoDp(healthResult?.holisticHealth?.generalWellness),
vectorUrl: 'assets/images/svg/wellness.svg',
+ vitalName: "generalWellness",
), //wellness
if (_vitalSign?.stress != null)
VitalSignWidget(
@@ -73,6 +74,7 @@ class ResultScreen extends StatelessWidget {
lookupValues: vitalValues['stressLevel']!,
vitalSignValue: formatValueToTwoDp(healthResult?.vitalSigns.stress),
vectorUrl: 'assets/images/svg/stress.svg',
+ vitalName: "stressLevel",
),
VitalSignWidget(
textColor: textColor,
@@ -81,6 +83,7 @@ class ResultScreen extends StatelessWidget {
lookupValues: vitalValues['HR']!,
vitalSignValue: formatValueToTwoDp(healthResult?.vitalSigns.heartRate),
vectorUrl: 'assets/images/svg/heartrate.svg',
+ vitalName: "HR",
),
//heart rate
if (_vitalSign?.bloodPressure != null)
@@ -91,6 +94,7 @@ class ResultScreen extends StatelessWidget {
bloodPressureValues: vitalValues['blood_pressure']!,
vitalSignValue: healthResult?.vitalSigns.bloodPressure ?? "",
vectorUrl: 'assets/images/svg/bloodpressure.svg',
+ vitalName: "blood_pressure",
),
if (_vitalSign?.hrvSdnn != null)
VitalSignWidget(
@@ -99,12 +103,14 @@ class ResultScreen extends StatelessWidget {
vitalSignName: "HRV SDNN",
lookupValues: vitalValues['hrvv']!,
condition: RangeConditionWithTitle.fromJson(vital['hrvv']!, formatValueToTwoDp(healthResult?.vitalSigns.hrvSdnn)),
+ vitalName: "hrvv",
vitalSignValue: formatValueToTwoDp(healthResult?.vitalSigns.hrvSdnn)),
//oxygen
VitalSignWidget(
textColor: textColor,
lookupValues: vitalValues['Sp02']!,
+ vitalName: "Sp02",
vitalSignName: TranslationBase.of(context).oxygenSaturation,
condition: RangeConditionWithTitle.fromJson(vital['Sp02']!, formatValueToTwoDp(healthResult?.vitalSigns.spo2)),
vitalSignValue: formatValueToTwoDp(healthResult?.vitalSigns.spo2),
@@ -114,6 +120,7 @@ class ResultScreen extends StatelessWidget {
VitalSignWidget(
textColor: textColor,
lookupValues: vitalValues['respiratoryRate']!,
+ vitalName: "respiratoryRate",
vitalSignName: TranslationBase.of(context).respiratoryRate,
condition: RangeConditionWithTitle.fromJson(vital['respiratoryRate']!, formatValueToTwoDp(healthResult?.vitalSigns.respiratoryRate)),
vitalSignValue: formatValueToTwoDp(healthResult?.vitalSigns.respiratoryRate),
@@ -123,6 +130,7 @@ class ResultScreen extends StatelessWidget {
VitalSignWidget(
textColor: textColor,
lookupValues: vitalValues['bmi']!,
+ vitalName: "bmi",
vitalSignName: TranslationBase.of(context).BMI,
condition: RangeConditionWithTitle.fromJson(vital['bmi']!, formatValueToTwoDp(healthResult?.holisticHealth?.bmi)),
vitalSignValue: formatValueToTwoDp(healthResult?.holisticHealth?.bmi),
diff --git a/lib/vital_signs/vital_sign.dart b/lib/vital_signs/vital_sign.dart
index 201c4506..da71ab15 100644
--- a/lib/vital_signs/vital_sign.dart
+++ b/lib/vital_signs/vital_sign.dart
@@ -12,7 +12,7 @@ import 'components/scan_condition_checklist.dart';
import 'components/scan_status.dart';
import 'components/start_button.dart';
import 'result_screen.dart';
-import 'package:lottie/lottie.dart';
+// import 'package:lottie/lottie.dart';
final UserInfo userInfo = UserInfo(
age: 30,
diff --git a/lib/widgets/data_display/medical/LabResult/newUI/labWidgets.dart b/lib/widgets/data_display/medical/LabResult/newUI/labWidgets.dart
new file mode 100644
index 00000000..91023357
--- /dev/null
+++ b/lib/widgets/data_display/medical/LabResult/newUI/labWidgets.dart
@@ -0,0 +1,455 @@
+import 'dart:math';
+
+import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
+import 'package:diplomaticquarterapp/uitl/utils.dart';
+import 'package:flutter/material.dart';
+
+enum ResultTypes { criticalLow, low, normal, high, criticalHigh }
+
+class ItemResultCardWidget extends StatelessWidget {
+ final Widget child;
+
+ const ItemResultCardWidget({
+ Key? key,
+ required this.child,
+ }) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ return Row(
+ children: [
+ Expanded(
+ child: Padding(
+ padding: const EdgeInsets.only(left: 12, right: 12, bottom: 12),
+ child: child,
+ ),
+ ),
+ ],
+ );
+ }
+}
+
+class CustomResultProgressBar extends StatelessWidget {
+ final double percentage;
+ final String value;
+ final ResultTypes type;
+
+ const CustomResultProgressBar({Key? key, required this.percentage, required this.value, required this.type}) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ return LayoutBuilder(builder: (context, constraints) {
+ final double totalWidth = constraints.maxWidth;
+ final double spacing = 2;
+ final double tooltipPosition = (totalWidth * (percentage / 100)).clamp(0, totalWidth - 50);
+ return Stack(
+ children: [
+ Row(
+ children: [
+ _buildResultBar(
+ flex: 3,
+ color: Color(0xFFDE7676),
+ title: "Critical Low",
+ ),
+ SizedBox(
+ width: spacing,
+ ),
+ _buildResultBar(
+ flex: 2,
+ color: Color(0xFFEAB157),
+ title: "Low",
+ ),
+ SizedBox(
+ width: spacing,
+ ),
+ _buildResultBar(
+ flex: 5,
+ color: Color(0xFF09AA28),
+ title: "Normal",
+ ),
+ SizedBox(
+ width: spacing,
+ ),
+ _buildResultBar(
+ flex: 2,
+ color: Color(0xFFEAB157),
+ title: "High",
+ ),
+ SizedBox(
+ width: spacing,
+ ),
+ _buildResultBar(
+ flex: 3,
+ color: Color(0xFFDE7676),
+ title: "Critical High",
+ ),
+ ],
+ ),
+ Positioned(
+ left: tooltipPosition,
+ top: 33,
+ child: Column(
+ children: [
+ TextCloud(
+ text: "${value}",
+ color: type == ResultTypes.criticalLow || type == ResultTypes.criticalHigh
+ ? Color(0xFFDE7676)
+ : type == ResultTypes.low || type == ResultTypes.high
+ ? Color(0xFFEAB157)
+ : type == ResultTypes.normal
+ ? Color(0xFF09AA28)
+ : Color(0xFF09AA28),
+ width: 60,
+ height: 20,
+ padding: EdgeInsets.zero,
+ axisDirection: AxisDirection.up,
+ ),
+ ],
+ ),
+ ),
+ ],
+ );
+ });
+ }
+
+ Widget _buildResultBar({
+ required int flex,
+ required Color color,
+ required String title,
+ }) {
+ return Expanded(
+ flex: flex,
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ Text(
+ title,
+ style: const TextStyle(fontSize: 10, fontFamily: 'Poppins', letterSpacing: -0.24, fontWeight: FontWeight.w500),
+ textAlign: TextAlign.center,
+ ),
+ const SizedBox(height: 5),
+ Container(
+ height: 5,
+ decoration: BoxDecoration(
+ color: color,
+ borderRadius: BorderRadius.all(Radius.circular(10)),
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+}
+
+class TextCloud extends StatelessWidget {
+ final String text; // write here box content
+ final Color color; // Set box Color
+ final EdgeInsets padding; // Set content padding
+ final double width; // Box width
+ final double height; // Box Height
+ final AxisDirection axisDirection; // Set triangle location up,left,right,down
+ final double locationOfArrow; // set between 0 and 1, If 0.5 is set triangle position will be centered
+ const TextCloud({
+ super.key,
+ required this.text,
+ this.color = Colors.white,
+ this.padding = const EdgeInsets.all(10),
+ this.width = 200,
+ this.height = 100,
+ this.axisDirection = AxisDirection.down,
+ this.locationOfArrow = 0.5,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ Size arrowSize = const Size(12, 12);
+ return Stack(
+ clipBehavior: Clip.none,
+ children: [
+ Container(
+ width: width,
+ height: height,
+ padding: padding,
+ decoration: BoxDecoration(
+ color: color,
+ borderRadius: BorderRadius.circular(10),
+ ),
+ child: Center(
+ child: Text(
+ text,
+ style: TextStyle(color: Colors.white),
+ )),
+ ),
+ Builder(builder: (context) {
+ double angle = 0;
+ switch (axisDirection) {
+ case AxisDirection.left:
+ angle = pi * -0.5;
+ break;
+ case AxisDirection.up:
+ angle = pi * -2;
+ break;
+ case AxisDirection.right:
+ angle = pi * 0.5;
+ break;
+ case AxisDirection.down:
+ angle = pi;
+ break;
+ default:
+ angle = 0;
+ }
+ return Positioned(
+ left: axisDirection == AxisDirection.left
+ ? -arrowSize.width + 5
+ : (axisDirection == AxisDirection.up || axisDirection == AxisDirection.down ? width * locationOfArrow - arrowSize.width / 2 : null),
+ right: axisDirection == AxisDirection.right ? -arrowSize.width + 5 : null,
+ top: axisDirection == AxisDirection.up
+ ? -arrowSize.width + 5
+ : (axisDirection == AxisDirection.right || axisDirection == AxisDirection.left ? height * locationOfArrow - arrowSize.width / 2 : null),
+ bottom: axisDirection == AxisDirection.down ? -arrowSize.width + 5 : null,
+ child: Transform.rotate(
+ angle: angle,
+ child: CustomPaint(
+ size: arrowSize,
+ painter: ArrowPaint(color: color),
+ ),
+ ),
+ );
+ })
+ ],
+ );
+ }
+}
+
+class ArrowPaint extends CustomPainter {
+ final Color color;
+
+ ArrowPaint({required this.color});
+
+ @override
+ void paint(Canvas canvas, Size size) {
+ Path path_0 = Path();
+ path_0.moveTo(size.width * 0.5745375, size.height * 0.06573708);
+ path_0.lineTo(size.width * 0.9813667, size.height * 0.8794000);
+ path_0.cubicTo(size.width * 1.001950, size.height * 0.9205625, size.width * 0.9852625, size.height * 0.9706208, size.width * 0.9441000, size.height * 0.9912000);
+ path_0.cubicTo(size.width * 0.9325250, size.height * 0.9969875, size.width * 0.9197667, size.height, size.width * 0.9068292, size.height);
+ path_0.lineTo(size.width * 0.09316958, size.height);
+ path_0.cubicTo(size.width * 0.04714583, size.height, size.width * 0.009836208, size.height * 0.9626917, size.width * 0.009836208, size.height * 0.9166667);
+ path_0.cubicTo(size.width * 0.009836208, size.height * 0.9037292, size.width * 0.01284829, size.height * 0.8909708, size.width * 0.01863392, size.height * 0.8794000);
+ path_0.lineTo(size.width * 0.4254625, size.height * 0.06573708);
+ path_0.cubicTo(size.width * 0.4460458, size.height * 0.02457225, size.width * 0.4961042, size.height * 0.007886875, size.width * 0.5372667, size.height * 0.02846929);
+ path_0.cubicTo(size.width * 0.5533958, size.height * 0.03653296, size.width * 0.5664708, size.height * 0.04961000, size.width * 0.5745375, size.height * 0.06573708);
+ path_0.close();
+
+ Paint paint_0_fill = Paint()..style = PaintingStyle.fill;
+ paint_0_fill.color = color;
+ canvas.drawPath(path_0, paint_0_fill);
+ }
+
+ @override
+ bool shouldRepaint(covariant CustomPainter oldDelegate) {
+ return true;
+ }
+}
+
+class ItemResultCardWidgetWithParams extends StatelessWidget {
+ final String title;
+ final String subTitle;
+ final String note;
+ final String source;
+ final String referenceRange;
+ final double percentage;
+ final String buttonText;
+ final ResultTypes type;
+ final bool isArabic;
+ final Function()? onButtonPressed;
+
+ const ItemResultCardWidgetWithParams({
+ Key? key,
+ required this.title,
+ required this.subTitle,
+ required this.referenceRange,
+ required this.percentage,
+ required this.note,
+ required this.source,
+ required this.buttonText,
+ required this.type,
+ this.onButtonPressed,
+ this.isArabic = false,
+ }) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ final fontFamily = isArabic ? 'Cairo' : 'Poppins';
+
+ return Container(
+ margin: const EdgeInsets.only(left: 21, right: 21, top: 21),
+ decoration: BoxDecoration(
+ borderRadius: const BorderRadius.all(Radius.circular(10)),
+ border: Border(
+ left: BorderSide(
+ color: type == ResultTypes.criticalLow || type == ResultTypes.criticalHigh
+ ? Color(0xFFDE7676)
+ : type == ResultTypes.low || type == ResultTypes.high
+ ? Color(0xFFEAB157)
+ : type == ResultTypes.normal
+ ? Color(0xFF09AA28)
+ : Color(0xFF09AA28),
+ width: MediaQuery.of(context).size.width * 0.015,
+ ),
+ ),
+ color: Colors.white,
+ boxShadow: [
+ BoxShadow(
+ color: Colors.grey.withOpacity(0.2),
+ spreadRadius: 2,
+ blurRadius: 5,
+ offset: const Offset(0, 3),
+ ),
+ ],
+ ),
+ child: Padding(
+ padding: const EdgeInsets.all(12.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ mainAxisSize: MainAxisSize.max,
+ children: [
+ // Title Row
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text(
+ title,
+ style: TextStyle(
+ fontSize: 16,
+ fontFamily: fontFamily,
+ fontWeight: FontWeight.w600,
+ color: const Color(0xff2E303A),
+ letterSpacing: -0.64,
+ height: 16 / 25,
+ ),
+ ),
+ GestureDetector(
+ onTap: onButtonPressed,
+ child: Utils.tableColumnValueWithUnderLine(TranslationBase.of(context).viewFlowChart, isLast: true, isCapitable: false),
+ ),
+ ],
+ ),
+ const SizedBox(height: 8),
+ Row(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ ResultStatusWidget(type: type),
+ SizedBox(width: 5),
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ subTitle,
+ style: TextStyle(fontSize: 14, fontFamily: fontFamily, fontWeight: FontWeight.w600, color: const Color(0xff2E303A), letterSpacing: -0.56),
+ ),
+ Text(
+ "Reference Range \n $referenceRange",
+ style: TextStyle(
+ fontSize: 10,
+ fontFamily: fontFamily,
+ fontWeight: FontWeight.w600,
+ color: const Color(0xff2E303A),
+ letterSpacing: -0.4,
+ ),
+ ),
+ ],
+ ),
+ ],
+ ),
+ const SizedBox(height: 10),
+ // Progress Bar
+ SizedBox(
+ height: 55,
+ child: CustomResultProgressBar(
+ percentage: percentage,
+ value: subTitle,
+ type: type,
+ ),
+ ),
+ const SizedBox(height: 12),
+ // Note Section
+ if (note.isNotEmpty)
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ const Divider(color: Color(0xFFEFEFEF), thickness: 1),
+ const SizedBox(height: 10),
+ Text(
+ "Notes:",
+ style: TextStyle(
+ fontSize: 12,
+ color: const Color(0xFF2E303A),
+ letterSpacing: -0.4,
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ Text(
+ note,
+ style: TextStyle(
+ fontSize: 12,
+ color: const Color(0xFF575757),
+ letterSpacing: -0.4,
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ ],
+ ),
+ const SizedBox(height: 3),
+ ],
+ ),
+ ),
+ );
+ }
+}
+
+class ResultStatusWidget extends StatelessWidget {
+ final ResultTypes type;
+
+ const ResultStatusWidget({
+ Key? key,
+ required this.type,
+ }) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ Color? color;
+ IconData? icon;
+
+ switch (type) {
+ case ResultTypes.criticalLow:
+ color = const Color(0xFFDE7676);
+ icon = Icons.arrow_circle_down;
+ break;
+ case ResultTypes.low:
+ color = const Color(0xFFEAB157);
+ icon = Icons.arrow_circle_down;
+ break;
+ case ResultTypes.criticalHigh:
+ color = const Color(0xFFDE7676);
+ icon = Icons.arrow_circle_up;
+ break;
+ case ResultTypes.high:
+ color = const Color(0xFFEAB157);
+ icon = Icons.arrow_circle_up;
+ break;
+ case ResultTypes.normal:
+ color = const Color(0xFF09AA28);
+ icon = Icons.check_circle;
+ break;
+ }
+
+ // Return the icon if defined, otherwise a placeholder widget
+ return icon != null
+ ? Icon(
+ icon,
+ color: color,
+ )
+ : const SizedBox(); // Use SizedBox to keep the layout consistent
+ }
+}
\ No newline at end of file
diff --git a/pubspec.yaml b/pubspec.yaml
index ff78e2fb..ce02a498 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -226,6 +226,7 @@ flutter:
- assets/payment_options/
- assets/images/new/
+ - assets/images/new/HealthSnap/
- assets/images/new/zoom/
- assets/images/new/inpatient/
- assets/images/new/mass/