import 'dart:math' as math show max; import 'package:flutter/material.dart'; import 'package:syncrow_web/pages/analytics/modules/occupancy/widgets/interactive_heat_map.dart'; import 'package:syncrow_web/pages/analytics/modules/occupancy/widgets/occupancy_heat_map_days.dart'; import 'package:syncrow_web/pages/analytics/modules/occupancy/widgets/occupancy_heat_map_gradient.dart'; import 'package:syncrow_web/pages/analytics/modules/occupancy/widgets/occupancy_heat_map_months.dart'; import 'package:syncrow_web/pages/analytics/modules/occupancy/widgets/occupancy_painter.dart'; import 'package:syncrow_web/utils/color_manager.dart'; class OccupancyHeatMap extends StatelessWidget { const OccupancyHeatMap({ required this.heatMapData, required this.selectedDate, super.key, }); final Map heatMapData; final DateTime selectedDate; static const _cellSize = 16.0; static const _totalWeeks = 53; int get _maxValue => heatMapData.isNotEmpty ? heatMapData.keys.map((key) => heatMapData[key] ?? 0).reduce(math.max) : 0; DateTime _getStartingDate() { final jan1 = DateTime.utc(selectedDate.year, 1, 1); final startOfWeek = jan1.subtract(Duration(days: jan1.weekday - 1)); return startOfWeek; } List _generatePaintItems(DateTime startDate) { return List.generate(_totalWeeks * 7, (index) { final date = startDate.add(Duration(days: index)); final value = heatMapData[date] ?? 0; return OccupancyPaintItem(index: index, value: value, date: date); }); } @override Widget build(BuildContext context) { final startDate = _getStartingDate(); final paintItems = _generatePaintItems(startDate); return Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: [ OccupancyHeatMapMonths(startDate: startDate, cellSize: _cellSize), Container( decoration: const BoxDecoration( border: Border( bottom: BorderSide(color: ColorsManager.grayBorder), top: BorderSide(color: ColorsManager.grayBorder), ), ), width: double.infinity, child: Row( children: [ Expanded( child: FittedBox( fit: BoxFit.fill, child: Row( children: [ const OccupancyHeatMapDays(cellSize: _cellSize), SizedBox( width: _totalWeeks * _cellSize, height: 7 * _cellSize, child: InteractiveHeatMap( items: paintItems, maxValue: _maxValue, cellSize: _cellSize, ), ), ], ), ), ), ], ), ), const SizedBox(height: 20), OccupancyHeatMapGradient(maxValue: _maxValue), ], ); } }