cr 7211 lab report new ui changes

merge-update-with-lab-changes
Aamir 1 year ago
parent 0f0b541563
commit b74a433798

@ -1,3 +1,5 @@
import 'dart:convert';
import 'package:diplomaticquarterapp/core/model/labs/patient_lab_orders.dart';
import 'package:diplomaticquarterapp/core/viewModels/medical/labs_view_model.dart';
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
@ -11,6 +13,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_html/flutter_html.dart';
import 'package:provider/provider.dart';
import 'package:diplomaticquarterapp/widgets/data_display/medical/LabResult/newUI/labWidgets.dart';
import 'LabResultWidget.dart';
@ -69,10 +72,11 @@ class _LaboratoryResultWidgetState extends State<LaboratoryResultWidget> {
),
SizedBox(height: 10),
if (model.labResultLists.isNotEmpty)
Container(
child: Column(
children: [
InkWell(
Column(
children: [
Padding(
padding: EdgeInsets.only(left: 21, right: 21),
child: GestureDetector(
onTap: () {
setState(
() {
@ -80,59 +84,84 @@ class _LaboratoryResultWidgetState extends State<LaboratoryResultWidget> {
},
);
},
child: Container(
padding: EdgeInsets.only(left: 17, top: 12, right: 13, bottom: 12),
margin: EdgeInsets.only(left: 21, right: 21, top: 12),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(10.0),
),
boxShadow: [
BoxShadow(
color: Color(0xff000000).withOpacity(.05),
//spreadRadius: 5,
blurRadius: 27,
offset: Offset(0, -3),
child: Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: Text(
TranslationBase.of(context).generalResult,
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64, height: 25 / 16),
),
],
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: Text(
TranslationBase.of(context).generalResult,
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64, height: 25 / 16),
),
),
Icon(
_isShowMoreGeneral ? Icons.keyboard_arrow_up : Icons.keyboard_arrow_down,
color: Color(0xff575757),
size: 22,
)
],
),
if (_isShowMoreGeneral)
...List.generate(
model.labResultLists.length,
(index) => LabResultWidget(
patientLabOrder: widget.patientLabOrder,
filterName: model.labResultLists[index].filterName,
patientLabResultList: model.labResultLists[index].patientLabResultList,
),
)
],
),
),
Icon(
_isShowMoreGeneral ? Icons.keyboard_arrow_up : Icons.keyboard_arrow_down,
color: Color(0xff575757),
size: 22,
)
],
),
),
],
),
),
ItemResultCardWidgetWithParams(
title: "LYMPHOCYTES", subTitle: "0.4", referenceRange: "0.6-4", percentage: 5, note: "", source: "source", buttonText: "Click", type: ResultTypes.criticalLow),
ItemResultCardWidgetWithParams(
title: "Creatinine",
subTitle: "60",
referenceRange: "64-104",
percentage: 20,
note: "Mayoclinic is the source of pediatrics value",
source: "source",
buttonText: "Click",
type: ResultTypes.low),
ItemResultCardWidgetWithParams(
title: "WBC",
subTitle: "5.96",
referenceRange: "4-11",
percentage: 45,
note: "Mayoclinic is the source of pediatrics value",
source: "source",
buttonText: "Click",
type: ResultTypes.normal),
ItemResultCardWidgetWithParams(title: "NEUT%", subTitle: "55", referenceRange: "10-50", percentage: 65, note: "", source: "source", buttonText: "Click", type: ResultTypes.high),
_isShowMoreGeneral
? Container(
padding: EdgeInsets.only(left: 17, top: 12, right: 13, bottom: 12),
margin: EdgeInsets.only(left: 21, right: 21, top: 12),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(10.0),
),
boxShadow: [
BoxShadow(
color: Color(0xff000000).withOpacity(.05),
//spreadRadius: 5,
blurRadius: 27,
offset: Offset(0, -3),
),
],
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
if (_isShowMoreGeneral)
...List.generate(model.labResultLists.length, (index) {
print(widget.patientLabOrder);
print(model.labResultLists[index].filterName);
print(jsonEncode(model.labResultLists[0].patientLabResultList));
return LabResultWidget(
patientLabOrder: widget.patientLabOrder,
filterName: model.labResultLists[index].filterName,
patientLabResultList: model.labResultLists[index].patientLabResultList,
);
})
],
),
)
: SizedBox(),
],
),
InkWell(
onTap: () {

@ -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
}
}
Loading…
Cancel
Save