uaestats_fe/lib/presentation/components/indicators/graph_holder_card.dart
2026-05-16 11:31:32 +05:30

157 lines
4.6 KiB
Dart
Executable File

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:share_plus/share_plus.dart';
import 'package:uae_stat/config/old_theme.dart';
import 'package:uae_stat/domain/use_cases/language.dart';
import 'package:uae_stat/infrastructure/services/packages/widget_to_img.dart';
import 'package:uae_stat/presentation/components/charts/themed_distribution_chart.dart';
import 'package:uae_stat/presentation/components/charts/themed_pie_chart.dart';
import 'package:uae_stat/presentation/components/space.dart';
class GraphHolderCard extends ConsumerWidget {
const GraphHolderCard(
this.graph, {
super.key,
required this.titleText,
this.subtitleText,
this.graphHeightDelta,
this.overrideHorizontalPadding,
});
final Widget graph;
final String titleText;
final String? subtitleText;
final double? graphHeightDelta;
final double? overrideHorizontalPadding;
@override
Widget build(BuildContext context, ref) {
final graphHeight = (graph is ThemedPieChartSingular ? 220 : 280) +
(graphHeightDelta != null ? graphHeightDelta! : 0);
final horizontalPadding = graph is ThemedDistributionChart ? 4 : 32;
final subtitle = subtitleText == null
? null
: Text(
subtitleText!,
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: context.translate(
'Roboto',
'NotoKufi',
),
fontWeight: FontWeight.w400,
fontSize: 11,
color: const Color(0xff898C81),
),
);
final title = Text(
titleText,
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: context.translate(
'Roboto',
'NotoKufi',
),
fontSize: 18,
fontWeight: FontWeight.w400,
),
);
final content = Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
title,
if (subtitle != null) ...[
4.verticalSpace,
subtitle,
],
(graph is ThemedPieChartSingular ? 30 : 20).verticalSpace,
SizedBox(
height: graphHeight.toDouble(),
child: graph,
),
],
);
final cardBg = Screenshottable(
child: DecoratedBox(
decoration: OldTheme.cardDecoration,
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
overrideHorizontalPadding ?? horizontalPadding.toDouble(),
20,
overrideHorizontalPadding ?? horizontalPadding.toDouble(),
graph is ThemedPieChartSingular ? 24 : 12,
),
child: content,
),
),
);
final button = InkWell(
onTap: () => showDialog(
context: context,
useRootNavigator: false,
barrierDismissible: false,
builder: (dialogContext) {
final shareBtn = ElevatedButton.icon(
onPressed: () async {
final imgBytes = await cardBg.generateScreenshot();
final xFile = XFile.fromData(
imgBytes,
mimeType: 'image/png',
name: '$titleText.png',
);
Share.shareXFiles(
[xFile],
subject: titleText,
);
},
label: Text(
context.translate(
'Share',
'يشارك',
),
),
icon: const Icon(Icons.share),
);
final interactiveViewer = InteractiveViewer(
boundaryMargin: const EdgeInsets.all(double.infinity),
alignment: Alignment.center,
constrained: false,
minScale: 0.5,
child: SizedBox(
width: context.width,
height: graphHeight + 111,
child: FractionallySizedBox(
widthFactor: 0.9,
alignment: Alignment.center,
child: cardBg,
),
),
);
return InkWell(
onTap: dialogContext.pop,
child: Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(
vertical: 12,
horizontal: 24,
),
child: Row(
children: [shareBtn],
),
),
Expanded(
child: interactiveViewer,
),
],
),
);
},
),
child: cardBg,
);
return button;
}
}