import 'dart:math'; import 'package:fl_chart/fl_chart.dart'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_export.dart'; import 'package:hmg_patient_app_new/core/common_models/data_points.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; import 'package:hmg_patient_app_new/widgets/custom_tab_bar.dart'; import 'package:hmg_patient_app_new/widgets/graph/CustomBarGraph.dart'; import 'package:intl/intl.dart' show DateFormat; class ActivityDetails extends StatefulWidget { final String selectedActivity; const ActivityDetails({super.key, required this.selectedActivity}); @override State createState() => _ActivityDetailsState(); } class _ActivityDetailsState extends State { int index = 0; @override Widget build(BuildContext context) { return Scaffold( backgroundColor: AppColors.bgScaffoldColor, body: CollapsingListView( title: "All Health Data".needTranslation, child: Column( spacing: 16.h, children: [ periodSelectorView((index) {}), activityDetails(), DecoratedBox( decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 12.h), child: activityGraph().paddingOnly(left: 16.w, right: 16.w, top: 32.h, bottom: 16.h),) ], ).paddingSymmetrical(24.w, 24.h), ), ); } Widget periodSelectorView(Function(int) onItemSelected) { return DecoratedBox( decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 12.h), child: Row( children: [ Expanded( child: CustomTabBar( activeTextColor: Color(0xffED1C2B), activeBackgroundColor: Color(0xffED1C2B).withValues(alpha: .1), tabs: [ CustomTabBarModel(null, "D"), CustomTabBarModel(null, "W"), CustomTabBarModel(null, "M"), CustomTabBarModel(null, "6M"), CustomTabBarModel(null, "Y"), // CustomTabBarModel(null, "Completed".needTranslation), ], shouldTabExpanded: true, onTabChange: (index) { //todo handle the selection from viewmodel setState(() { this.index = index; }); }, ), ), ], ).paddingSymmetrical(4.w, 4.h)); } Widget activityDetails() { return DecoratedBox( decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 12.h, hasShadow: true), child: Column( spacing: 8.h, children: [ Column( children: [widget.selectedActivity.toText32(weight: FontWeight.w600, color: AppColors.textColor), "Average".toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor)], ), Row( children: ["3232".toText24(color: AppColors.textGreenColor, fontWeight: FontWeight.w600), "(20-21)".toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500)], ) ], ).paddingSymmetrical(16.w, 16.h)); } Widget activityGraph() { final _random = Random(); int randomBP() => 100 + _random.nextInt(51); // 100–150 final List data6Months = List.generate(6, (index) { final date = DateTime.now().subtract(Duration(days: 30 * (5 - index))); final value = randomBP(); return DataPoint( value: value.toDouble(), label: value.toString(), actualValue: value.toString(), displayTime: DateFormat('MMM').format(date), unitOfMeasurement: 'mmHg', time: date, ); }); final List data12Months = List.generate(12, (index) { final date = DateTime.now().subtract(Duration(days: 30 * (11 - index))); final value = randomBP(); return DataPoint( value: value.toDouble(), label: value.toString(), actualValue: value.toString(), displayTime: DateFormat('MMM').format(date), unitOfMeasurement: 'mmHg', time: date, ); }); List data =[]; if(index == 0){ data = data6Months; } else if(index == 1){ data = data12Months; } else data = [ DataPoint( value: 128, label: "128", actualValue: '128', displayTime: 'Sun', unitOfMeasurement: 'mmHg', time: DateTime.now().subtract(const Duration(days: 6)), ), DataPoint( value: 135, label: "135", actualValue: '135', displayTime: 'Mon', unitOfMeasurement: 'mmHg', time: DateTime.now().subtract(const Duration(days: 5)), ), DataPoint( value: 122, label: "122", actualValue: '122', displayTime: 'Tue', unitOfMeasurement: 'mmHg', time: DateTime.now().subtract(const Duration(days: 4)), ), DataPoint( value: 140, label: "140", actualValue: '140', displayTime: 'Wed', unitOfMeasurement: 'mmHg', time: DateTime.now().subtract(const Duration(days: 3)), ), DataPoint( value: 118, label: "118", actualValue: '118', displayTime: 'Thu', unitOfMeasurement: 'mmHg', time: DateTime.now().subtract(const Duration(days: 2)), ), DataPoint( value: 125, label: "125", actualValue: '125', displayTime: 'Fri', unitOfMeasurement: 'mmHg', time: DateTime.now().subtract(const Duration(days: 1)), ), DataPoint( value: 130, label: "130", actualValue: '130', displayTime: 'Sat', unitOfMeasurement: 'mmHg', time: DateTime.now(), ), ]; return CustomBarChart( dataPoints: data, height: 300.h, maxY: 150, barColor: AppColors.bgGreenColor, barWidth: 26.w, barRadius: BorderRadius.circular(8), bottomLabelColor: Colors.black, bottomLabelSize: 12, leftLabelInterval: .1, leftLabelReservedSize: 40, // Left axis label formatter (Y-axis) leftLabelFormatter: (value) { var labelValue = double.tryParse(value.toStringAsFixed(0)); if (labelValue == null) return SizedBox.shrink(); if (labelValue == 0 || labelValue == 150 / 2 || labelValue == 150) { return Text( labelValue.toStringAsFixed(0), style: const TextStyle( color: Colors.black26, fontSize: 11, ), ); } return SizedBox.shrink(); }, // Bottom axis label formatter (X-axis - Days) bottomLabelFormatter: (value, dataPoints) { final index = value.toInt(); if (index >= 0 && index < dataPoints.length) { return Text( dataPoints[index].displayTime, style: const TextStyle( color: Colors.grey, fontSize: 11, ), ); } return const Text(''); }, verticalInterval: 1/data.length, getDrawingVerticalLine: (value) { return FlLine( color: AppColors.greyColor, strokeWidth: 1, ); }, showGridLines: true, ); } }