no message
parent
0895d94df2
commit
f7021f685a
Binary file not shown.
|
After Width: | Height: | Size: 2.4 MiB |
@ -0,0 +1,102 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hmg_patient_app_new/theme/colors.dart';
|
||||
|
||||
/// UI-only helper model for Vital Sign cards.
|
||||
///
|
||||
/// Keeps presentation logic (chip colors, icon colors, simple status rules)
|
||||
/// in one place so it can be reused across multiple pages.
|
||||
class VitalSignUiModel {
|
||||
final Color iconBg;
|
||||
final Color iconFg;
|
||||
final Color chipBg;
|
||||
final Color chipFg;
|
||||
|
||||
const VitalSignUiModel({
|
||||
required this.iconBg,
|
||||
required this.iconFg,
|
||||
required this.chipBg,
|
||||
required this.chipFg,
|
||||
});
|
||||
|
||||
/// Returns a color scheme for a card based on its [status] and [label].
|
||||
///
|
||||
/// Rules (mirrors existing behavior in Medical File page):
|
||||
/// - Height is always blue.
|
||||
/// - High => red scheme.
|
||||
/// - Low => yellow scheme.
|
||||
/// - Otherwise => green scheme (Normal).
|
||||
static VitalSignUiModel scheme({required String? status, required String label}) {
|
||||
final s = (status ?? '').toLowerCase();
|
||||
final l = label.toLowerCase();
|
||||
|
||||
// Height should always be blue.
|
||||
if (l.contains('height')) {
|
||||
return VitalSignUiModel(
|
||||
iconBg: AppColors.infoColor.withValues(alpha: 0.12),
|
||||
iconFg: AppColors.infoColor,
|
||||
chipBg: AppColors.infoColor.withValues(alpha: 0.12),
|
||||
chipFg: AppColors.infoColor,
|
||||
);
|
||||
}
|
||||
|
||||
if (s.contains('high')) {
|
||||
return const VitalSignUiModel(
|
||||
iconBg: AppColors.chipSecondaryLightRedColor,
|
||||
iconFg: AppColors.primaryRedColor,
|
||||
chipBg: AppColors.chipSecondaryLightRedColor,
|
||||
chipFg: AppColors.primaryRedColor,
|
||||
);
|
||||
}
|
||||
|
||||
if (s.contains('low')) {
|
||||
final Color yellowBg = AppColors.warningColor.withValues(alpha: 0.12);
|
||||
return VitalSignUiModel(
|
||||
iconBg: yellowBg,
|
||||
iconFg: AppColors.warningColor,
|
||||
chipBg: yellowBg,
|
||||
chipFg: AppColors.warningColor,
|
||||
);
|
||||
}
|
||||
|
||||
// Normal (green)
|
||||
final Color greenBg = AppColors.lightGreenColor;
|
||||
return VitalSignUiModel(
|
||||
iconBg: greenBg,
|
||||
iconFg: AppColors.bgGreenColor,
|
||||
chipBg: greenBg,
|
||||
chipFg: AppColors.bgGreenColor,
|
||||
);
|
||||
}
|
||||
|
||||
/// Simple, user-friendly classification:
|
||||
/// - Low: systolic < 90 OR diastolic < 60
|
||||
/// - High: systolic >= 140 OR diastolic >= 90
|
||||
/// - Normal: otherwise
|
||||
/// Returns null if values are missing/unparseable.
|
||||
static String? bloodPressureStatus({dynamic systolic, dynamic diastolic}) {
|
||||
final int? s = toIntOrNull(systolic);
|
||||
final int? d = toIntOrNull(diastolic);
|
||||
if (s == null || d == null) return null;
|
||||
|
||||
if (s < 90 || d < 60) return 'Low';
|
||||
if (s >= 140 || d >= 90) return 'High';
|
||||
return 'Normal';
|
||||
}
|
||||
|
||||
static int? toIntOrNull(dynamic v) {
|
||||
if (v == null) return null;
|
||||
if (v is int) return v;
|
||||
if (v is double) return v.round();
|
||||
return int.tryParse(v.toString());
|
||||
}
|
||||
|
||||
static String bmiStatus(dynamic bmi) {
|
||||
if (bmi == null) return 'N/A';
|
||||
final double bmiValue = double.tryParse(bmi.toString()) ?? 0;
|
||||
if (bmiValue < 18.5) return 'Underweight';
|
||||
if (bmiValue < 25) return 'Normal';
|
||||
if (bmiValue < 30) return 'Overweight';
|
||||
return 'High';
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,93 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
|
||||
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
|
||||
import 'package:hmg_patient_app_new/theme/colors.dart';
|
||||
|
||||
class VitalSignShimmerWidget extends StatelessWidget {
|
||||
const VitalSignShimmerWidget({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
children: [
|
||||
// BMI Card Shimmer
|
||||
Expanded(child: _buildShimmerCard()),
|
||||
SizedBox(width: 8.w),
|
||||
// Height Card Shimmer
|
||||
Expanded(child: _buildShimmerCard()),
|
||||
SizedBox(width: 8.w),
|
||||
// Weight Card Shimmer
|
||||
Expanded(child: _buildShimmerCard()),
|
||||
SizedBox(width: 8.w),
|
||||
// Blood Pressure Card Shimmer
|
||||
Expanded(child: _buildShimmerCard()),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildShimmerCard() {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.whiteColor,
|
||||
borderRadius: BorderRadius.circular(12.r),
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(12.w),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
// Icon shimmer
|
||||
Container(
|
||||
width: 32.w,
|
||||
height: 32.h,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(8.r),
|
||||
),
|
||||
).toShimmer(),
|
||||
SizedBox(height: 8.h),
|
||||
// Label shimmer
|
||||
Container(
|
||||
width: 50.w,
|
||||
height: 10.h,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(4.r),
|
||||
),
|
||||
).toShimmer(),
|
||||
SizedBox(height: 4.h),
|
||||
// Value shimmer
|
||||
Container(
|
||||
width: 40.w,
|
||||
height: 16.h,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(4.r),
|
||||
),
|
||||
).toShimmer(),
|
||||
SizedBox(height: 4.h),
|
||||
// Chip shimmer
|
||||
Container(
|
||||
width: 45.w,
|
||||
height: 18.h,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12.r),
|
||||
),
|
||||
).toShimmer(),
|
||||
SizedBox(height: 4.h),
|
||||
// Arrow shimmer
|
||||
Align(
|
||||
alignment: AlignmentDirectional.centerEnd,
|
||||
child: Container(
|
||||
width: 10.w,
|
||||
height: 10.h,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(2.r),
|
||||
),
|
||||
).toShimmer(),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue