diff --git a/lib/screens/reports/widgets/report_card_wrapper.dart b/lib/screens/reports/widgets/report_card_wrapper.dart index 98f840e9..e0593122 100644 --- a/lib/screens/reports/widgets/report_card_wrapper.dart +++ b/lib/screens/reports/widgets/report_card_wrapper.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; import 'package:skeletonizer/skeletonizer.dart'; +import '../../../theme/app_surfaces.dart'; + /// Wraps each report chart widget in a themed Card with a title, loading /// skeleton and error state handling. Exposes a [GlobalKey] on the inner /// [RepaintBoundary] so the PDF exporter can capture the rendered chart @@ -74,15 +76,25 @@ class ReportCardWrapper extends StatelessWidget { body = child; } + final radius = AppSurfaces.of(context).cardRadius; + final isDark = colors.brightness == Brightness.dark; + final cardContent = Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Padding( - padding: const EdgeInsets.fromLTRB(16, 14, 16, 4), - child: Text(title, style: text.titleSmall), + padding: const EdgeInsets.fromLTRB(16, 12, 16, 10), + child: Text( + title.toUpperCase(), + style: text.labelMedium?.copyWith( + fontWeight: FontWeight.w700, + letterSpacing: 0.6, + color: colors.onSurfaceVariant, + ), + ), ), - const Divider(height: 1), + Divider(height: 1, color: colors.outlineVariant), Padding( padding: const EdgeInsets.all(16), child: height != null ? SizedBox(height: height, child: body) : body, @@ -93,8 +105,12 @@ class ReportCardWrapper extends StatelessWidget { final card = Card( elevation: 0, shadowColor: Colors.transparent, - color: colors.surfaceContainerLow, - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), + surfaceTintColor: Colors.transparent, + color: isDark ? colors.surfaceContainer : colors.surfaceContainerLowest, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(radius), + side: BorderSide(color: colors.outlineVariant), + ), child: cardContent, ); diff --git a/lib/screens/reports/widgets/request_distribution_charts.dart b/lib/screens/reports/widgets/request_distribution_charts.dart index 33fb5269..61bf72e3 100644 --- a/lib/screens/reports/widgets/request_distribution_charts.dart +++ b/lib/screens/reports/widgets/request_distribution_charts.dart @@ -77,10 +77,11 @@ class _RequestTypeChartState extends ConsumerState { return ReportCardWrapper( title: 'Request Type Distribution', repaintBoundaryKey: widget.repaintKey, - height: 220, + height: 180, child: Row( children: [ - Expanded( + SizedBox( + width: 150, child: PieChart( PieChartData( pieTouchData: PieTouchData( @@ -116,22 +117,24 @@ class _RequestTypeChartState extends ConsumerState { ), ), ), - const SizedBox(width: 12), - Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: data.asMap().entries.map((entry) { - final i = entry.key; - final e = entry.value; - final isTouched = i == _touchedIndex; - return _HoverLegendItem( - color: colorFor(i, e.name), - label: e.name, - value: - '${e.count} (${(e.count / total * 100).toStringAsFixed(0)}%)', - isTouched: isTouched, - ); - }).toList(), + const SizedBox(width: 16), + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: data.asMap().entries.map((entry) { + final i = entry.key; + final e = entry.value; + final isTouched = i == _touchedIndex; + return _HoverLegendItem( + color: colorFor(i, e.name), + label: e.name, + value: + '${e.count} (${(e.count / total * 100).toStringAsFixed(0)}%)', + isTouched: isTouched, + ); + }).toList(), + ), ), ], ), @@ -208,10 +211,11 @@ class _RequestCategoryChartState extends ConsumerState { return ReportCardWrapper( title: 'Request Category Distribution', repaintBoundaryKey: widget.repaintKey, - height: 220, + height: 180, child: Row( children: [ - Expanded( + SizedBox( + width: 150, child: PieChart( PieChartData( pieTouchData: PieTouchData( @@ -247,22 +251,24 @@ class _RequestCategoryChartState extends ConsumerState { ), ), ), - const SizedBox(width: 12), - Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: data.asMap().entries.map((entry) { - final i = entry.key; - final e = entry.value; - final isTouched = i == _touchedIndex; - return _HoverLegendItem( - color: colorFor(i, e.name), - label: e.name, - value: - '${e.count} (${(e.count / total * 100).toStringAsFixed(0)}%)', - isTouched: isTouched, - ); - }).toList(), + const SizedBox(width: 16), + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: data.asMap().entries.map((entry) { + final i = entry.key; + final e = entry.value; + final isTouched = i == _touchedIndex; + return _HoverLegendItem( + color: colorFor(i, e.name), + label: e.name, + value: + '${e.count} (${(e.count / total * 100).toStringAsFixed(0)}%)', + isTouched: isTouched, + ); + }).toList(), + ), ), ], ), diff --git a/lib/screens/reports/widgets/status_charts.dart b/lib/screens/reports/widgets/status_charts.dart index 422cd249..25fba45a 100644 --- a/lib/screens/reports/widgets/status_charts.dart +++ b/lib/screens/reports/widgets/status_charts.dart @@ -52,10 +52,11 @@ class _TicketsByStatusChartState extends ConsumerState { return ReportCardWrapper( title: 'Tickets by Status', repaintBoundaryKey: widget.repaintKey, - height: 220, + height: 180, child: Row( children: [ - Expanded( + SizedBox( + width: 150, child: PieChart( PieChartData( pieTouchData: PieTouchData( @@ -92,22 +93,24 @@ class _TicketsByStatusChartState extends ConsumerState { ), ), ), - const SizedBox(width: 12), - Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: data.asMap().entries.map((entry) { - final i = entry.key; - final e = entry.value; - final isTouched = i == _touchedIndex; - return _LegendItem( - color: _ticketStatusColor(context, e.status), - label: _capitalize(e.status), - value: - '${e.count} (${(e.count / total * 100).toStringAsFixed(0)}%)', - isTouched: isTouched, - ); - }).toList(), + const SizedBox(width: 16), + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: data.asMap().entries.map((entry) { + final i = entry.key; + final e = entry.value; + final isTouched = i == _touchedIndex; + return _LegendItem( + color: _ticketStatusColor(context, e.status), + label: _capitalize(e.status), + value: + '${e.count} (${(e.count / total * 100).toStringAsFixed(0)}%)', + isTouched: isTouched, + ); + }).toList(), + ), ), ], ), @@ -178,10 +181,11 @@ class _TasksByStatusChartState extends ConsumerState { return ReportCardWrapper( title: 'Tasks by Status', repaintBoundaryKey: widget.repaintKey, - height: 220, + height: 180, child: Row( children: [ - Expanded( + SizedBox( + width: 150, child: PieChart( PieChartData( pieTouchData: PieTouchData( @@ -218,22 +222,24 @@ class _TasksByStatusChartState extends ConsumerState { ), ), ), - const SizedBox(width: 12), - Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: data.asMap().entries.map((entry) { - final i = entry.key; - final e = entry.value; - final isTouched = i == _touchedIndex; - return _LegendItem( - color: _taskStatusColor(context, e.status), - label: _formatTaskStatus(e.status), - value: - '${e.count} (${(e.count / total * 100).toStringAsFixed(0)}%)', - isTouched: isTouched, - ); - }).toList(), + const SizedBox(width: 16), + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: data.asMap().entries.map((entry) { + final i = entry.key; + final e = entry.value; + final isTouched = i == _touchedIndex; + return _LegendItem( + color: _taskStatusColor(context, e.status), + label: _formatTaskStatus(e.status), + value: + '${e.count} (${(e.count / total * 100).toStringAsFixed(0)}%)', + isTouched: isTouched, + ); + }).toList(), + ), ), ], ),