From 2f5ad03431e2a398c091997fbe1f254043ea22d8 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Sun, 29 Jun 2025 10:57:18 +0300 Subject: [PATCH] created empty charts widget. --- .../total_energy_consumption_chart_box.dart | 12 ++- .../analytics_chart_empty_state_widget.dart | 80 +++++++++++++++++++ 2 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 lib/pages/analytics/widgets/analytics_chart_empty_state_widget.dart diff --git a/lib/pages/analytics/modules/energy_management/widgets/total_energy_consumption_chart_box.dart b/lib/pages/analytics/modules/energy_management/widgets/total_energy_consumption_chart_box.dart index 4d88471d..52a0b0ba 100644 --- a/lib/pages/analytics/modules/energy_management/widgets/total_energy_consumption_chart_box.dart +++ b/lib/pages/analytics/modules/energy_management/widgets/total_energy_consumption_chart_box.dart @@ -3,6 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/total_energy_consumption/total_energy_consumption_bloc.dart'; import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/chart_title.dart'; import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/total_energy_consumption_chart.dart'; +import 'package:syncrow_web/pages/analytics/widgets/analytics_chart_empty_state_widget.dart'; import 'package:syncrow_web/pages/analytics/widgets/analytics_error_widget.dart'; import 'package:syncrow_web/pages/analytics/widgets/charts_loading_widget.dart'; import 'package:syncrow_web/utils/style.dart'; @@ -41,7 +42,16 @@ class TotalEnergyConsumptionChartBox extends StatelessWidget { const SizedBox(height: 20), const Divider(), const SizedBox(height: 20), - TotalEnergyConsumptionChart(chartData: state.chartData), + Visibility( + visible: state.chartData.isNotEmpty, + replacement: AnalyticsChartEmptyStateWidget( + isLoading: state.status == TotalEnergyConsumptionStatus.loading, + isError: state.status == TotalEnergyConsumptionStatus.failure, + isInitial: state.status == TotalEnergyConsumptionStatus.initial, + errorMessage: state.errorMessage, + ), + child: TotalEnergyConsumptionChart(chartData: state.chartData), + ), ], ), ), diff --git a/lib/pages/analytics/widgets/analytics_chart_empty_state_widget.dart b/lib/pages/analytics/widgets/analytics_chart_empty_state_widget.dart new file mode 100644 index 00000000..086cf959 --- /dev/null +++ b/lib/pages/analytics/widgets/analytics_chart_empty_state_widget.dart @@ -0,0 +1,80 @@ +import 'package:flutter/material.dart'; +import 'package:syncrow_web/common/widgets/app_loading_indicator.dart'; +import 'package:syncrow_web/utils/color_manager.dart'; +import 'package:syncrow_web/utils/extension/build_context_x.dart'; + +class AnalyticsChartEmptyStateWidget extends StatelessWidget { + const AnalyticsChartEmptyStateWidget({ + this.isLoading = false, + this.isError = false, + this.isInitial = false, + this.errorMessage, + this.noDataMessage = 'No data to display', + this.initialMessage = 'Please select a space to see data', + super.key, + }); + + final bool isLoading; + final bool isError; + final bool isInitial; + final String? errorMessage; + final String noDataMessage; + final String initialMessage; + + @override + Widget build(BuildContext context) { + return Expanded( + child: isLoading + ? const Center( + child: AppLoadingIndicator(), + ) + : isError + ? _buildState( + context, + icon: Icons.error_outline, + message: errorMessage ?? 'Something went wrong', + color: ColorsManager.red, + ) + : isInitial + ? _buildState( + context, + icon: Icons.filter_list, + message: initialMessage, + ) + : _buildState( + context, + icon: Icons.bar_chart, + message: noDataMessage, + ), + ); + } + + Widget _buildState( + BuildContext context, { + required IconData icon, + required String message, + Color? color, + }) { + final disabledColor = context.theme.disabledColor; + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + icon, + size: 48, + color: color ?? disabledColor, + ), + const SizedBox(height: 16), + SelectableText( + message, + style: context.textTheme.bodyMedium?.copyWith( + color: color ?? disabledColor, + ), + textAlign: TextAlign.center, + ), + ], + ), + ); + } +}