import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../../providers/reports_provider.dart'; import 'report_card_wrapper.dart'; /// KPI card showing ticket-to-task conversion rate, with a visual gauge arc. class ConversionRateCard extends ConsumerWidget { const ConversionRateCard({super.key, this.repaintKey}); final GlobalKey? repaintKey; @override Widget build(BuildContext context, WidgetRef ref) { final asyncData = ref.watch(ticketToTaskRateReportProvider); return asyncData.when( loading: () => ReportCardWrapper( title: 'Ticket-to-Task Conversion', isLoading: true, height: 160, repaintBoundaryKey: repaintKey, child: const SizedBox.shrink(), ), error: (e, _) => ReportCardWrapper( title: 'Ticket-to-Task Conversion', error: e.toString(), repaintBoundaryKey: repaintKey, child: const SizedBox.shrink(), ), data: (data) => _build(context, data), ); } Widget _build(BuildContext context, ConversionRate data) { final colors = Theme.of(context).colorScheme; final text = Theme.of(context).textTheme; return ReportCardWrapper( title: 'Ticket-to-Task Conversion', repaintBoundaryKey: repaintKey, child: Row( children: [ // Gauge SizedBox( width: 100, height: 100, child: Stack( alignment: Alignment.center, children: [ SizedBox( width: 90, height: 90, child: CircularProgressIndicator( value: data.conversionRate / 100, strokeWidth: 8, backgroundColor: colors.surfaceContainerHighest, color: colors.primary, strokeCap: StrokeCap.round, ), ), Text( '${data.conversionRate.toStringAsFixed(1)}%', style: text.titleMedium?.copyWith( fontWeight: FontWeight.w700, color: colors.primary, ), ), ], ), ), const SizedBox(width: 24), // Details Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ _MetricRow( label: 'Total Tickets', value: data.totalTickets.toString(), text: text, ), const SizedBox(height: 8), _MetricRow( label: 'Promoted to Task', value: data.promotedTickets.toString(), text: text, ), const SizedBox(height: 8), _MetricRow( label: 'Not Promoted', value: (data.totalTickets - data.promotedTickets).toString(), text: text, ), ], ), ), ], ), ); } } class _MetricRow extends StatelessWidget { const _MetricRow({ required this.label, required this.value, required this.text, }); final String label; final String value; final TextTheme text; @override Widget build(BuildContext context) { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Flexible(child: Text(label, style: text.bodySmall)), Text( value, style: text.titleSmall?.copyWith(fontWeight: FontWeight.w600), ), ], ); } }