Implemented AqiSubValueWidget.

This commit is contained in:
Faris Armoush
2025-05-27 15:12:11 +03:00
parent 3746c36a71
commit 95eca869c9
3 changed files with 185 additions and 2 deletions

View File

@ -40,7 +40,7 @@ class AirQualityView extends StatelessWidget {
spacing: 32,
children: [
Expanded(
flex: 2,
flex: 5,
child: Column(
spacing: 20,
children: [
@ -49,7 +49,10 @@ class AirQualityView extends StatelessWidget {
],
),
),
Expanded(child: AirQualityEndSideWidget()),
Expanded(
flex: 3,
child: AirQualityEndSideWidget(),
),
],
),
),

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/analytics/modules/air_quality/widgets/aqi_sub_value_widget.dart';
import 'package:syncrow_web/pages/analytics/modules/analytics/blocs/analytics_devices/analytics_devices_bloc.dart';
import 'package:syncrow_web/pages/analytics/modules/energy_management/helpers/fetch_energy_management_data_helper.dart';
import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/analytics_device_dropdown.dart';
@ -39,6 +40,46 @@ class AirQualityEndSideWidget extends StatelessWidget {
fontSize: 12,
),
),
const Divider(),
Container(
decoration: secondarySection.copyWith(boxShadow: const []),
padding: const EdgeInsetsDirectional.all(20),
child: const Column(
spacing: 6,
children: [
AqiSubValueWidget(
label: 'PM2.5',
value: 19,
unit: 'µg/m³',
),
AqiSubValueWidget(
label: 'PM10',
value: 42,
unit: 'µg/m³',
),
AqiSubValueWidget(
label: 'CO2',
value: 610,
unit: 'ppm',
),
AqiSubValueWidget(
label: 'VOC',
value: 1,
unit: 'mg/m³',
),
AqiSubValueWidget(
label: 'O3',
value: 55,
unit: 'µg/m³',
),
AqiSubValueWidget(
label: 'NO2',
value: 18,
unit: 'µg/m³',
),
],
),
),
],
),
);

View File

@ -0,0 +1,139 @@
import 'package:flutter/material.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/extension/build_context_x.dart';
final class _AqiRange {
const _AqiRange({
required this.max,
required this.color,
});
final int max;
final Color color;
}
class AqiSubValueWidget extends StatelessWidget {
final String label;
final int value;
final String unit;
const AqiSubValueWidget({
super.key,
required this.label,
required this.value,
required this.unit,
});
static const List<_AqiRange> _ranges = [
_AqiRange(max: 12, color: ColorsManager.green),
_AqiRange(max: 35, color: Color(0xFFFFF176)),
_AqiRange(max: 55, color: Color(0xFFFFD54F)),
_AqiRange(max: 150, color: Color(0xFFE57373)),
_AqiRange(max: 250, color: Color(0xFFBA68C8)),
_AqiRange(max: 500, color: Color(0xFFB39DDB)),
];
int _getActiveSegment(int value) {
for (int i = 0; i < _ranges.length; i++) {
if (value <= _ranges[i].max) return i;
}
return _ranges.length - 1;
}
@override
Widget build(BuildContext context) {
final activeSegment = _getActiveSegment(value);
return Container(
padding: const EdgeInsetsDirectional.all(10),
decoration: BoxDecoration(
color: ColorsManager.whiteColors,
borderRadius: BorderRadius.circular(12),
),
child: Row(
spacing: MediaQuery.sizeOf(context).width * 0.0075,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
_buildLabel(context),
_buildSegmentedBar(activeSegment),
_buildValueAndUnit(context),
],
),
);
}
Widget _buildValueAndUnit(BuildContext context) {
return Expanded(
child: FittedBox(
fit: BoxFit.scaleDown,
alignment: AlignmentDirectional.centerEnd,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
value.toString(),
style: context.textTheme.titleMedium?.copyWith(
color: ColorsManager.blackColor,
fontWeight: FontWeight.w400,
fontSize: 14,
),
),
Text(
unit,
style: context.textTheme.bodySmall?.copyWith(
color: ColorsManager.blackColor,
fontWeight: FontWeight.w400,
fontSize: 10,
),
),
],
),
),
);
}
Widget _buildSegmentedBar(int activeSegment) {
return Expanded(
flex: 4,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12),
child: Row(
spacing: 4,
mainAxisAlignment: MainAxisAlignment.center,
children: List.generate(_ranges.length, (index) {
final isActive = index == activeSegment;
final color = _ranges[index].color.withValues(
alpha: isActive ? 1.0 : 0.25,
);
return Expanded(
child: Container(
height: 5,
decoration: BoxDecoration(
color: color,
borderRadius: BorderRadius.circular(4),
),
),
);
}),
),
),
);
}
Widget _buildLabel(BuildContext context) {
return Expanded(
child: FittedBox(
fit: BoxFit.scaleDown,
alignment: AlignmentDirectional.centerStart,
child: Text(
label,
style: context.textTheme.bodySmall?.copyWith(
color: ColorsManager.blackColor,
fontWeight: FontWeight.w400,
fontSize: 14,
),
),
),
);
}
}