vital sign finalized.

pull/151/head
Sultan khan 4 days ago
parent 34e8386ca1
commit ac0d72b3ff

@ -305,55 +305,64 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Row( Padding(
mainAxisAlignment: MainAxisAlignment.spaceBetween, padding: EdgeInsets.symmetric(horizontal: 24.w),
children: [ child: Row(
"Vital Signs".needTranslation.toText16(weight: FontWeight.w500, letterSpacing: -0.2), mainAxisAlignment: MainAxisAlignment.spaceBetween,
Row( children: [
children: [ "Vital Signs".needTranslation.toText16(weight: FontWeight.w500, letterSpacing: -0.2),
LocaleKeys.viewAll.tr().toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500), Row(
SizedBox(width: 2.h), children: [
Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h), LocaleKeys.viewAll.tr().toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500),
], SizedBox(width: 2.h),
), Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h),
], ],
).paddingSymmetrical(0.w, 0.h).onPress(() { ),
Navigator.of(context).push( ],
CustomPageRoute( ).paddingSymmetrical(0.w, 0.h).onPress(() {
page: VitalSignPage(), Navigator.of(context).push(
), CustomPageRoute(
); page: VitalSignPage(),
}), ),
);
}),
),
SizedBox(height: 16.h), SizedBox(height: 16.h),
// Make this section dynamic-height (no fixed 160.h) // Make this section dynamic-height (no fixed 160.h)
LayoutBuilder( LayoutBuilder(
builder: (context, constraints) { builder: (context, constraints) {
if (hmgServicesVM.isVitalSignLoading) { if (hmgServicesVM.isVitalSignLoading) {
return _buildVitalSignShimmer(); return Padding(
padding: EdgeInsets.symmetric(horizontal: 24.w),
child: _buildVitalSignShimmer(),
);
} }
if (hmgServicesVM.vitalSignList.isEmpty) { if (hmgServicesVM.vitalSignList.isEmpty) {
return Container( return Padding(
padding: EdgeInsets.all(16.w), padding: EdgeInsets.symmetric(horizontal: 24.w),
width: MediaQuery.of(context).size.width, child: Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration( padding: EdgeInsets.all(16.w),
color: AppColors.whiteColor, width: MediaQuery.of(context).size.width,
borderRadius: 12.r, decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
hasShadow: false, color: AppColors.whiteColor,
), borderRadius: 12.r,
child: Column( hasShadow: false,
mainAxisAlignment: MainAxisAlignment.center, ),
children: [ child: Column(
Utils.buildSvgWithAssets(icon: AppAssets.call_for_vitals, width: 32.h, height: 32.h), mainAxisAlignment: MainAxisAlignment.center,
SizedBox(height: 12.h), children: [
"No vital signs recorded yet".needTranslation.toText12(isCenter: true), Utils.buildSvgWithAssets(icon: AppAssets.call_for_vitals, width: 32.h, height: 32.h),
], SizedBox(height: 12.h),
"No vital signs recorded yet".needTranslation.toText12(isCenter: true),
],
),
), ),
); );
} }
// The cards define their own height; measure the first rendered page once // The cards define their own height; measure the first rendered page once
_scheduleVitalSignMeasure(); _scheduleVitalSignMeasure();
final double hostHeight = _vitalSignMeasuredHeight ?? (160.h); final double hostHeight = _vitalSignMeasuredHeight ?? (135.h);
return SizedBox( return SizedBox(
height: hostHeight, height: hostHeight,
@ -400,7 +409,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
), ),
], ],
], ],
).paddingSymmetrical(24.w, 0.0); );
}), }),
SizedBox(height: 16.h), SizedBox(height: 16.h),
@ -1394,23 +1403,23 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
).toShimmer(), ).toShimmer(),
SizedBox(height: 16.h), SizedBox(height: 16.h),
// Label shimmer // Label shimmer
Container( // Container(
width: 70.w, // width: 70.w,
height: 12.h, // height: 12.h,
decoration: BoxDecoration( // decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4.r), // borderRadius: BorderRadius.circular(4.r),
), // ),
).toShimmer(), // ).toShimmer(),
SizedBox(height: 8.h), // SizedBox(height: 8.h),
// Value shimmer (larger) // Value shimmer (larger)
Container( // Container(
width: 60.w, // width: 60.w,
height: 32.h, // height: 32.h,
decoration: BoxDecoration( // decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4.r), // borderRadius: BorderRadius.circular(4.r),
), // ),
).toShimmer(), // ).toShimmer(),
SizedBox(height: 12.h), // SizedBox(height: 12.h),
// Bottom row with chip and arrow // Bottom row with chip and arrow
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -1446,62 +1455,66 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
}) { }) {
return [ return [
// Page 1: BMI + Height // Page 1: BMI + Height
Row( Padding(
children: [ padding: EdgeInsets.only(left: 24.w),
Expanded( child: Row(
child: _buildVitalSignCard( children: [
icon: AppAssets.bmiVital, Expanded(
label: "BMI", child: _buildVitalSignCard(
value: vitalSign.bodyMassIndex?.toString() ?? '--', icon: AppAssets.bmiVital,
unit: '', label: "BMI",
status: vitalSign.bodyMassIndex != null ? _getBMIStatus(vitalSign.bodyMassIndex) : null, value: vitalSign.bodyMassIndex?.toString() ?? '--',
onTap: onTap, unit: '',
status: vitalSign.bodyMassIndex != null ? _getBMIStatus(vitalSign.bodyMassIndex) : null,
onTap: onTap,
),
), ),
), SizedBox(width: 12.w),
SizedBox(width: 12.w), Expanded(
Expanded( child: _buildVitalSignCard(
child: _buildVitalSignCard( icon: AppAssets.heightVital,
icon: AppAssets.heightVital, label: "Height",
label: "Height", value: vitalSign.heightCm?.toString() ?? '--',
value: vitalSign.heightCm?.toString() ?? '--', unit: 'cm',
unit: 'cm', status: null,
status: null, onTap: onTap,
onTap: onTap, ),
), ),
), ],
], ),
), ),
// Page 2: Weight + Blood Pressure // Page 2: Weight + Blood Pressure
Row( Padding(padding: EdgeInsets.symmetric(horizontal: 12.w),child: Row(
children: [ children: [
Expanded( Expanded(
child: _buildVitalSignCard( child: _buildVitalSignCard(
icon: AppAssets.weightVital, icon: AppAssets.weightVital,
label: "Weight", label: "Weight",
value: vitalSign.weightKg?.toString() ?? '--', value: vitalSign.weightKg?.toString() ?? '--',
unit: 'kg', unit: 'kg',
status: vitalSign.weightKg != null ? "Normal" : null, status: vitalSign.weightKg != null ? "Normal" : null,
onTap: onTap, onTap: onTap,
),
), ),
), SizedBox(width: 12.w),
SizedBox(width: 12.w), Expanded(
Expanded( child: _buildVitalSignCard(
child: _buildVitalSignCard( icon: AppAssets.bloodPressure,
icon: AppAssets.bloodPressure, label: "Blood Pressure",
label: "Blood Pressure", value: vitalSign.bloodPressureLower != null && vitalSign.bloodPressureHigher != null
value: vitalSign.bloodPressureLower != null && vitalSign.bloodPressureHigher != null ? "${vitalSign.bloodPressureHigher}/${vitalSign.bloodPressureLower}"
? "${vitalSign.bloodPressureHigher}/${vitalSign.bloodPressureLower}" : '--',
: '--', unit: '',
unit: '', status: _getBloodPressureStatus(
status: _getBloodPressureStatus( systolic: vitalSign.bloodPressureHigher,
systolic: vitalSign.bloodPressureHigher, diastolic: vitalSign.bloodPressureLower,
diastolic: vitalSign.bloodPressureLower, ),
onTap: onTap,
), ),
onTap: onTap,
), ),
), ],
], )),
),
]; ];
} }
@ -1526,7 +1539,6 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
return GestureDetector( return GestureDetector(
onTap: onTap, onTap: onTap,
child: Container( child: Container(
// Same styling used originally for vitals in MedicalFilePage
decoration: RoundedRectangleBorder().toSmoothCornerDecoration( decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor, color: AppColors.whiteColor,
borderRadius: 16.r, borderRadius: 16.r,
@ -1540,15 +1552,15 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
Row( Row(
children: [ children: [
Container( Container(
padding: EdgeInsets.all(10.h), padding: EdgeInsets.all(8.h),
decoration: BoxDecoration( decoration: BoxDecoration(
color: scheme.iconBg, color: scheme.iconBg,
borderRadius: BorderRadius.circular(12.r), borderRadius: BorderRadius.circular(12.r),
), ),
child: Utils.buildSvgWithAssets( child: Utils.buildSvgWithAssets(
icon: icon, icon: icon,
width: 20.w, width: 22.w,
height: 20.h, height: 22.h,
iconColor: scheme.iconFg, iconColor: scheme.iconFg,
fit: BoxFit.contain, fit: BoxFit.contain,
), ),
@ -1563,55 +1575,56 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
], ],
), ),
SizedBox(height: 14.h), SizedBox(height: 14.h),
Container( Container(
padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 6.h), padding: EdgeInsets.symmetric(horizontal: 6.w, vertical: 6.h),
decoration: BoxDecoration( decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.bgScaffoldColor, color: AppColors.bgScaffoldColor,
borderRadius: BorderRadius.circular(10.r), borderRadius: 10.r,
hasShadow: false,
), ),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Row( Flexible(
crossAxisAlignment: CrossAxisAlignment.end, child: Row(
children: [ crossAxisAlignment: CrossAxisAlignment.end,
value.toText17( mainAxisSize: MainAxisSize.min,
isBold: true, children: [
color: AppColors.textColor, Flexible(
), child: value.toText17(
if (unit.isNotEmpty) ...[ isBold: true,
SizedBox(width: 3.w), color: AppColors.textColor,
unit.toText12( ),
color: AppColors.textColor,
fontWeight: FontWeight.w500,
), ),
if (unit.isNotEmpty) ...[
SizedBox(width: 3.w),
unit.toText12(
color: AppColors.textColor,
fontWeight: FontWeight.w500,
),
],
], ],
], ),
), ),
if (status != null) if (status != null) ...[
SizedBox(width: 4.w),
AppCustomChipWidget( AppCustomChipWidget(
labelText: status, labelText: status,
backgroundColor: scheme.chipBg, backgroundColor: scheme.chipBg,
textColor: scheme.chipFg, textColor: scheme.chipFg,
) ),
]
else else
const SizedBox.shrink(), AppCustomChipWidget(
labelText: "",
backgroundColor: AppColors.bgScaffoldColor,
textColor:null,
)
], ],
), ),
), ),
SizedBox(height: 8.h),
Align(
alignment: AlignmentDirectional.centerEnd,
child: Utils.buildSvgWithAssets(
icon: AppAssets.arrow_forward,
width: 18.w,
height: 18.h,
iconColor: AppColors.textColorLight,
fit: BoxFit.contain,
),
),
], ],
), ),
), ),

@ -74,7 +74,7 @@ class _VitalSignDetailsPageState extends State<VitalSignDetailsPage> {
return SingleChildScrollView( return SingleChildScrollView(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, spacing: 16.h,
children: [ children: [
_headerCard( _headerCard(
context, context,
@ -85,16 +85,8 @@ class _VitalSignDetailsPageState extends State<VitalSignDetailsPage> {
scheme: scheme, scheme: scheme,
latestDate: latest?.vitalSignDate, latestDate: latest?.vitalSignDate,
), ),
SizedBox(height: 16.h),
_whatIsThisResultCard(context), _whatIsThisResultCard(context),
SizedBox(height: 16.h),
_historyCard(context, history: history), _historyCard(context, history: history),
SizedBox(height: 16.h),
_nextStepsCard(context),
SizedBox(height: 32.h),
], ],
).paddingAll(24.h), ).paddingAll(24.h),
); );
@ -121,65 +113,71 @@ class _VitalSignDetailsPageState extends State<VitalSignDetailsPage> {
padding: EdgeInsets.all(16.h), padding: EdgeInsets.all(16.h),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
spacing: 8.h,
children: [ children: [
Row( Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Container( title.toText28(isBold: true, color: AppColors.textColor, letterSpacing: -1),
padding: EdgeInsets.all(10.h),
decoration: BoxDecoration(
color: scheme.iconBg,
borderRadius: BorderRadius.circular(12.r),
),
child: Utils.buildSvgWithAssets(
icon: icon,
width: 20.w,
height: 20.h,
iconColor: scheme.iconFg,
fit: BoxFit.contain,
),
),
SizedBox(width: 10.w),
title.toText18(isBold: true, weight: FontWeight.w600),
], ],
), ),
if (status != null) SizedBox(height: 8.h),
Container( (latestDate != null
padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 6.h), ? ('Result of ${latestDate.toString().split(' ').first}'.needTranslation)
decoration: BoxDecoration( : ('Result of --'.needTranslation))
color: scheme.chipBg, .toText11(weight: FontWeight.w500, color: AppColors.greyTextColor),
borderRadius: BorderRadius.circular(100.r), ],
), ),
child: status.toText11( Row(
color: scheme.chipFg, crossAxisAlignment: CrossAxisAlignment.center,
weight: FontWeight.w500, children: [
), Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.min,
children: [
Flexible(
child: valueText.toText28(
isBold: true,
color: scheme.iconFg,
letterSpacing: -2,
),
),
SizedBox(width: 4.h),
if (status != null)
Column(
spacing: 6.h,
children: [
status.toText10(weight: FontWeight.w500, color: AppColors.greyTextColor),
Utils.buildSvgWithAssets(
icon: AppAssets.lab_result_indicator,
width: 21,
height: 23,
iconColor: scheme.iconFg,
),
],
),
],
), ),
),
], ],
), ),
SizedBox(height: 10.h), if (args.low != null || args.high != null)
(
latestDate != null
? ('Result of ${latestDate.toString().split(' ').first}'.needTranslation)
: ('Result of --'.needTranslation)
).toText11(weight: FontWeight.w500, color: AppColors.greyTextColor),
SizedBox(height: 12.h),
valueText.toText28(isBold: true, color: AppColors.textColor, letterSpacing: -2),
if (args.low != null || args.high != null) ...[
SizedBox(height: 8.h),
Text( Text(
_referenceText(context), _referenceText(context),
style: TextStyle( style: TextStyle(
fontSize: 12.f, fontSize: 12.f,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
fontFamily: 'Poppins',
color: AppColors.greyTextColor, color: AppColors.greyTextColor,
), ),
) softWrap: true,
] ),
], ],
), ),
); );
@ -208,21 +206,10 @@ class _VitalSignDetailsPageState extends State<VitalSignDetailsPage> {
padding: EdgeInsets.all(16.h), padding: EdgeInsets.all(16.h),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
spacing: 8.h,
children: [ children: [
'What is this result?'.needTranslation.toText16(weight: FontWeight.w600), 'What is this result?'.needTranslation.toText16(weight: FontWeight.w600, color: AppColors.textColor),
SizedBox(height: 8.h), _descriptionText(context).toText12(fontWeight: FontWeight.w500, color: AppColors.textColorLight),
_descriptionText(context).toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500, maxLine: 10),
SizedBox(height: 12.h),
Row(
children: [
Utils.buildSvgWithAssets(icon: AppAssets.bulb, width: 16.w, height: 16.h, iconColor: AppColors.greyTextColor),
SizedBox(width: 6.w),
Expanded(
child: 'This information is for monitoring and not a diagnosis.'.needTranslation
.toText11(color: AppColors.greyTextColor, weight: FontWeight.w500, maxLine: 3),
),
],
)
], ],
), ),
); );
@ -235,34 +222,63 @@ class _VitalSignDetailsPageState extends State<VitalSignDetailsPage> {
borderRadius: 24.h, borderRadius: 24.h,
hasShadow: true, hasShadow: true,
), ),
padding: EdgeInsets.all(16.h), height: _isGraphVisible
? 260.h
: (history.length < 3)
? (history.length * 64) + 80.h
: 260.h,
padding: EdgeInsets.all(15.h),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [ children: [
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
'History flowchart'.needTranslation.toText16(weight: FontWeight.w600), Text(
_isGraphVisible ? 'History flowchart'.needTranslation : 'History'.needTranslation,
style: TextStyle(
fontSize: 16,
fontFamily: 'Poppins',
fontWeight: FontWeight.w600,
color: AppColors.textColor,
),
),
Row( Row(
mainAxisSize: MainAxisSize.min,
children: [ children: [
// toggle graph/list similar to lab result details Container(
Utils.buildSvgWithAssets( width: 24.h,
icon: _isGraphVisible ? AppAssets.graphIcon : AppAssets.listIcon, height: 24.h,
width: 18.w, alignment: Alignment.center,
height: 18.h, child: InkWell(
iconColor: AppColors.greyTextColor, onTap: () {
).onPress(() { setState(() {
setState(() { _isGraphVisible = !_isGraphVisible;
_isGraphVisible = !_isGraphVisible; });
}); },
}), child: Utils.buildSvgWithAssets(
SizedBox(width: 10.w), icon: _isGraphVisible ? AppAssets.ic_list : AppAssets.ic_graph,
Utils.buildSvgWithAssets(icon: AppAssets.calendarGrey, width: 18.w, height: 18.h, iconColor: AppColors.greyTextColor), width: 24.h,
height: 24.h,
),
),
),
// SizedBox(width: 16.h),
// Container(
// width: 24.h,
// height: 24.h,
// alignment: Alignment.center,
// child: Utils.buildSvgWithAssets(
// icon: AppAssets.ic_date_filter,
// width: 24.h,
// height: 24.h,
// ),
// ),
], ],
), ),
], ],
), ).paddingOnly(bottom: _isGraphVisible ? 16.h : 24.h),
SizedBox(height: 12.h),
if (history.isEmpty) if (history.isEmpty)
Utils.getNoDataWidget(context, noDataText: 'No history available'.needTranslation, isSmallWidget: true) Utils.getNoDataWidget(context, noDataText: 'No history available'.needTranslation, isSmallWidget: true)
else if (_isGraphVisible) else if (_isGraphVisible)
@ -277,47 +293,63 @@ class _VitalSignDetailsPageState extends State<VitalSignDetailsPage> {
Widget _buildHistoryGraph(List<DataPoint> history) { Widget _buildHistoryGraph(List<DataPoint> history) {
final minY = _minY(history); final minY = _minY(history);
final maxY = _maxY(history); final maxY = _maxY(history);
final scheme = VitalSignUiModel.scheme(status: _statusForLatest(null), label: args.title);
return CustomGraph( return CustomGraph(
dataPoints: history, dataPoints: history,
makeGraphBasedOnActualValue: true, makeGraphBasedOnActualValue: true,
leftLabelReservedSize: 40, leftLabelReservedSize: 40,
showGridLines: true, showGridLines: true,
showShadow: true,
leftLabelInterval: _leftInterval(history), leftLabelInterval: _leftInterval(history),
maxY: maxY, maxY: maxY,
minY: minY, minY: minY,
maxX: history.length.toDouble() - .75, maxX: history.length.toDouble() - .75,
horizontalInterval: .1, horizontalInterval: _leftInterval(history),
leftLabelFormatter: (value) { leftLabelFormatter: (value) {
// Match the lab screen behavior: only show High/Low labels. // Show labels at interval points
final v = double.parse(value.toStringAsFixed(1)); if (args.high != null && (value - args.high!).abs() < 0.1) {
if (args.high != null && v == args.high) { return _axisLabel('High');
return _axisLabel('High'.needTranslation);
} }
if (args.low != null && v == args.low) { if (args.low != null && (value - args.low!).abs() < 0.1) {
return _axisLabel('Low'.needTranslation); return _axisLabel('Low');
} }
return const SizedBox.shrink(); // Show numeric labels at regular intervals
return _axisLabel(value.toStringAsFixed(0));
}, },
getDrawingHorizontalLine: (value) { getDrawingHorizontalLine: (value) {
value = double.parse(value.toStringAsFixed(1)); // Draw reference lines for high/low bounds
if ((args.high != null && value == args.high) || (args.low != null && value == args.low)) { if (args.high != null && (value - args.high!).abs() < 0.1) {
return FlLine( return FlLine(
color: AppColors.bgGreenColor.withValues(alpha: 0.6), color: AppColors.bgGreenColor.withOpacity(0.2),
strokeWidth: 1, strokeWidth: 1,
dashArray: [5, 5],
); );
} }
return const FlLine(color: Colors.transparent, strokeWidth: 1); if (args.low != null && (value - args.low!).abs() < 0.1) {
}, return FlLine(
graphColor: AppColors.blackColor, color: AppColors.bgGreenColor.withOpacity(0.2),
graphShadowColor: Colors.transparent, strokeWidth: 1,
graphGridColor: AppColors.graphGridColor.withValues(alpha: .4), dashArray: [5, 5],
bottomLabelFormatter: (value, data) { );
if (data.isEmpty) return const SizedBox.shrink(); }
if (value == 0) return _bottomLabel(data[value.toInt()].label); // Draw grid lines at intervals
if (value == data.length - 1) return _bottomLabel(data[value.toInt()].label); return FlLine(
if (value == ((data.length - 1) / 2)) return _bottomLabel(data[value.toInt()].label); color: AppColors.bgGreenColor.withOpacity(0.2),
return const SizedBox.shrink(); strokeWidth: 1,
dashArray: [5, 5],
);
}, },
graphColor: AppColors.bgGreenColor,
graphShadowColor: AppColors.lightGreenColor.withOpacity(.4),
graphGridColor: scheme.iconFg,
bottomLabelFormatter: (value, data) {
if (data.isEmpty) return const SizedBox.shrink();
if (value == 0) return _bottomLabel(data[value.toInt()].label);
if (value == data.length - 1) return _bottomLabel(data[value.toInt()].label, isLast: true);
if (value == ((data.length - 1) / 2)) return _bottomLabel(data[value.toInt()].label);
return const SizedBox.shrink();
},
rangeAnnotations: _rangeAnnotations(history), rangeAnnotations: _rangeAnnotations(history),
minX: (history.length == 1) ? null : -.2, minX: (history.length == 1) ? null : -.2,
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
@ -325,6 +357,7 @@ class _VitalSignDetailsPageState extends State<VitalSignDetailsPage> {
); );
} }
Widget _buildHistoryList(BuildContext context, List<DataPoint> history) { Widget _buildHistoryList(BuildContext context, List<DataPoint> history) {
final items = history.reversed.toList(); final items = history.reversed.toList();
final height = items.length < 3 ? items.length * 64.0 : 180.h; final height = items.length < 3 ? items.length * 64.0 : 180.h;
@ -393,7 +426,7 @@ class _VitalSignDetailsPageState extends State<VitalSignDetailsPage> {
HorizontalRangeAnnotation( HorizontalRangeAnnotation(
y1: minY, y1: minY,
y2: args.low!, y2: args.low!,
color: AppColors.highAndLow.withValues(alpha: 0.05), color: AppColors.highAndLow.withOpacity(0.05),
), ),
); );
} }
@ -403,7 +436,7 @@ class _VitalSignDetailsPageState extends State<VitalSignDetailsPage> {
HorizontalRangeAnnotation( HorizontalRangeAnnotation(
y1: args.low!, y1: args.low!,
y2: args.high!, y2: args.high!,
color: AppColors.bgGreenColor.withValues(alpha: 0.05), color: AppColors.bgGreenColor.withOpacity(0.05),
), ),
); );
} }
@ -413,7 +446,7 @@ class _VitalSignDetailsPageState extends State<VitalSignDetailsPage> {
HorizontalRangeAnnotation( HorizontalRangeAnnotation(
y1: args.high!, y1: args.high!,
y2: maxY, y2: maxY,
color: AppColors.criticalLowAndHigh.withValues(alpha: 0.05), color: AppColors.criticalLowAndHigh.withOpacity(0.05),
), ),
); );
} }
@ -447,11 +480,14 @@ class _VitalSignDetailsPageState extends State<VitalSignDetailsPage> {
case VitalSignMetric.respiratoryRate: case VitalSignMetric.respiratoryRate:
return _toDouble(v.respirationBeatPerMinute); return _toDouble(v.respirationBeatPerMinute);
case VitalSignMetric.bloodPressure: case VitalSignMetric.bloodPressure:
// Graph only systolic for now (simple single-series). // Graph only systolic for now (simple single-series).
return _toDouble(v.bloodPressureHigher); return _toDouble(v.bloodPressureHigher);
} }
} }
const monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
double index = 0; double index = 0;
for (final v in sorted) { for (final v in sorted) {
final mv = metricValue(v); final mv = metricValue(v);
@ -459,7 +495,7 @@ class _VitalSignDetailsPageState extends State<VitalSignDetailsPage> {
if (mv == 0) continue; if (mv == 0) continue;
final dt = v.vitalSignDate ?? DateTime.now(); final dt = v.vitalSignDate ?? DateTime.now();
final label = '${dt.day}/${dt.month}'; final label = '${monthNames[dt.month - 1]}, ${dt.year}';
points.add( points.add(
DataPoint( DataPoint(
@ -603,18 +639,14 @@ class _VitalSignDetailsPageState extends State<VitalSignDetailsPage> {
); );
} }
Widget _bottomLabel(String label) { Widget _bottomLabel(String label, {bool isLast = false}) {
return Padding( return Padding(
padding: const EdgeInsets.only(top: 8.0), padding: EdgeInsets.only(
child: Text( top: 8.0,
label, right: isLast ? 16.h : 0,
style: TextStyle(
fontSize: 8.f,
fontFamily: 'Poppins',
fontWeight: FontWeight.w600,
color: AppColors.labelTextColor,
),
), ),
child: label.toText8(fontWeight: FontWeight.w500),
); );
} }
} }

@ -178,7 +178,7 @@ class _VitalSignPageState extends State<VitalSignPage> {
children: [ children: [
// Body anatomy image with Heart Rate card overlaid at bottom // Body anatomy image with Heart Rate card overlaid at bottom
SizedBox( SizedBox(
height: 480.h, height: 420.h,
width: double.infinity, width: double.infinity,
child: Stack( child: Stack(
clipBehavior: Clip.none, clipBehavior: Clip.none,
@ -196,7 +196,7 @@ class _VitalSignPageState extends State<VitalSignPage> {
Align( Align(
alignment: Alignment.bottomCenter, alignment: Alignment.bottomCenter,
child: SizedBox( child: SizedBox(
height: 420.h, height: 480.h,
child: ImageFiltered( child: ImageFiltered(
imageFilter: ImageFilter.blur(sigmaX: 6, sigmaY: 6), imageFilter: ImageFilter.blur(sigmaX: 6, sigmaY: 6),
child: Container( child: Container(
@ -245,7 +245,7 @@ class _VitalSignPageState extends State<VitalSignPage> {
], ],
), ),
), ),
SizedBox(height: 12.h), SizedBox(height: 12.h),
// Respiratory rate Card // Respiratory rate Card
_buildVitalSignCard( _buildVitalSignCard(
@ -308,15 +308,15 @@ class _VitalSignPageState extends State<VitalSignPage> {
Row( Row(
children: [ children: [
Container( Container(
padding: EdgeInsets.all(10.h), padding: EdgeInsets.all(8.h),
decoration: BoxDecoration( decoration: BoxDecoration(
color: scheme.iconBg, color: scheme.iconBg,
borderRadius: BorderRadius.circular(12.r), borderRadius: BorderRadius.circular(12.r),
), ),
child: Utils.buildSvgWithAssets( child: Utils.buildSvgWithAssets(
icon: icon, icon: icon,
width: 20.w, width: 22.w,
height: 20.h, height: 22.h,
iconColor: scheme.iconFg, iconColor: scheme.iconFg,
fit: BoxFit.contain, fit: BoxFit.contain,
), ),
@ -332,10 +332,15 @@ class _VitalSignPageState extends State<VitalSignPage> {
), ),
SizedBox(height: 14.h), SizedBox(height: 14.h),
Container( Container(
padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 6.h), padding: EdgeInsets.symmetric(horizontal: 6.w, vertical: 6.h),
decoration: BoxDecoration( // decoration: BoxDecoration(
// color: AppColors.bgScaffoldColor,
// borderRadius: BorderRadius.circular(10.r),
// ),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.bgScaffoldColor, color: AppColors.bgScaffoldColor,
borderRadius: BorderRadius.circular(10.r), borderRadius: 10.r,
hasShadow: false,
), ),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -361,23 +366,24 @@ class _VitalSignPageState extends State<VitalSignPage> {
labelText: status, labelText: status,
backgroundColor: scheme.chipBg, backgroundColor: scheme.chipBg,
textColor: scheme.chipFg, textColor: scheme.chipFg,
) )
else else
const SizedBox.shrink(), const SizedBox.shrink(),
], ],
), ),
), ),
SizedBox(height: 8.h), // SizedBox(height: 8.h),
Align( // Align(
alignment: AlignmentDirectional.centerEnd, // alignment: AlignmentDirectional.centerEnd,
child: Utils.buildSvgWithAssets( // child: Utils.buildSvgWithAssets(
icon: AppAssets.arrow_forward, // icon: AppAssets.arrow_forward,
width: 18.w, // width: 18.w,
height: 18.h, // height: 18.h,
iconColor: AppColors.textColorLight, // iconColor: AppColors.textColorLight,
fit: BoxFit.contain, // fit: BoxFit.contain,
), // ),
), // ),
], ],
), ),
), ),

Loading…
Cancel
Save