From 449505c4b81882797b86aa5602e11cdde5d4b6ed Mon Sep 17 00:00:00 2001 From: alzalia1 Date: Mon, 18 Aug 2025 22:59:01 +0200 Subject: [PATCH] feat: stats --- .../widget/ended/bal_ended_screen.dart | 23 +- lib/ui/bal_page/widget/ended/stats_tab.dart | 196 ++++++++++++++++++ 2 files changed, 197 insertions(+), 22 deletions(-) create mode 100644 lib/ui/bal_page/widget/ended/stats_tab.dart diff --git a/lib/ui/bal_page/widget/ended/bal_ended_screen.dart b/lib/ui/bal_page/widget/ended/bal_ended_screen.dart index 694b85e..70a9905 100644 --- a/lib/ui/bal_page/widget/ended/bal_ended_screen.dart +++ b/lib/ui/bal_page/widget/ended/bal_ended_screen.dart @@ -3,6 +3,7 @@ import 'package:seshat/domain/models/enums.dart'; import 'package:seshat/domain/models/return_owner.dart'; import 'package:seshat/domain/models/search_result.dart'; import 'package:seshat/ui/bal_page/view_model/bal_view_model.dart'; +import 'package:seshat/ui/bal_page/widget/ended/stats_tab.dart'; import 'package:seshat/ui/core/ui/navigation_bar.dart'; class BalEndedScreen extends StatefulWidget { @@ -195,25 +196,3 @@ class ReturnPopup extends StatelessWidget { ); } } - -class StatsTab extends StatelessWidget { - const StatsTab({super.key, required this.viewModel}); - final BalViewModel viewModel; - - @override - Widget build(BuildContext context) { - return Column( - children: [ - Padding( - padding: const EdgeInsets.all(10.0), - child: Card( - child: ListTile( - title: Text("0€", style: TextStyle(fontSize: 30)), - subtitle: Text("Total d'argent collecté"), - ), - ), - ), - ], - ); - } -} diff --git a/lib/ui/bal_page/widget/ended/stats_tab.dart b/lib/ui/bal_page/widget/ended/stats_tab.dart new file mode 100644 index 0000000..bb303ec --- /dev/null +++ b/lib/ui/bal_page/widget/ended/stats_tab.dart @@ -0,0 +1,196 @@ +import 'package:fl_chart/fl_chart.dart'; +import 'package:flutter/material.dart'; +import 'package:seshat/ui/bal_page/view_model/bal_view_model.dart'; + +Map colors = { + "owners": Color(0xFFB1C086), + "section": Color(0xFFEBCCFF), +}; + +class StatsTab extends StatefulWidget { + const StatsTab({super.key, required this.viewModel}); + final BalViewModel viewModel; + + @override + State createState() => _StatsTabState(); +} + +class _StatsTabState extends State { + @override + Widget build(BuildContext context) { + return SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: const EdgeInsets.all(10.0), + child: Card( + child: Column( + children: [ + Text("Argent Collecté", style: TextStyle(fontSize: 30)), + Text( + "${widget.viewModel.stats?.totalCollectedMoney.toString() ?? "0"}€ total", + style: TextStyle(fontSize: 20), + ), + SizedBox( + height: 300, + child: Padding( + padding: const EdgeInsets.all(15.0), + child: PieChart( + PieChartData( + sections: getMoneySection(), + centerSpaceRadius: double.infinity, + ), + ), + ), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Indicator( + color: colors["owners"]!, + text: "Propriétaires", + ), + Indicator(color: colors["section"]!, text: "Syndicat"), + ], + ), + SizedBox(height: 5), + ], + ), + ), + ), + Padding( + padding: const EdgeInsets.all(10.0), + child: Card( + child: Column( + children: [ + Text("Livres Vendus", style: TextStyle(fontSize: 30)), + Text( + "${widget.viewModel.stats?.totalSoldBooks ?? "0"} livres", + style: TextStyle(fontSize: 20), + ), + SizedBox( + height: 300, + child: Padding( + padding: const EdgeInsets.all(15.0), + child: PieChart( + PieChartData( + sections: getBooksSection(), + centerSpaceRadius: double.infinity, + ), + ), + ), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Indicator( + color: colors["owners"]!, + text: "Propriétaires", + ), + Indicator(color: colors["section"]!, text: "Syndicat"), + ], + ), + SizedBox(height: 5), + ], + ), + ), + ), + Padding( + padding: const EdgeInsets.all(10.0), + child: Card( + child: Column( + children: [ + Text( + "${widget.viewModel.stats?.totalDifferentOwners} propriétaires", + style: TextStyle(fontSize: 30), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Text( + "ont participé·e à cette BAL", + style: TextStyle(fontSize: 20), + ), + ], + ), + ], + ), + ), + ), + ], + ), + ); + } + + List getMoneySection() { + return [ + PieChartSectionData( + value: widget.viewModel.stats?.totalOwnedCollectedMoney ?? 0, + title: + "${(widget.viewModel.stats?.totalOwnedCollectedMoney ?? 0).toString()}€", + titleStyle: TextStyle(color: Colors.black), + color: colors["section"]!, + ), + PieChartSectionData( + value: + (widget.viewModel.stats?.totalCollectedMoney ?? 0) - + (widget.viewModel.stats?.totalOwnedCollectedMoney ?? 0), + title: + "${((widget.viewModel.stats?.totalCollectedMoney ?? 0) - (widget.viewModel.stats?.totalOwnedCollectedMoney ?? 0)).toString()}€", + titleStyle: TextStyle(color: Colors.black), + color: colors["owners"]!, + ), + ]; + } + + List getBooksSection() { + return [ + PieChartSectionData( + value: widget.viewModel.stats?.totalSoldBooks.toDouble() ?? 0, + title: (widget.viewModel.stats?.totalSoldBooks ?? 0).toString(), + titleStyle: TextStyle(color: Colors.black), + color: colors["section"]!, + ), + PieChartSectionData( + value: + ((widget.viewModel.stats?.totalSoldBooks ?? 0) - + (widget.viewModel.stats?.totalOwnedSoldBooks ?? 0)) + .toDouble(), + title: + ((widget.viewModel.stats?.totalSoldBooks ?? 0) - + (widget.viewModel.stats?.totalOwnedSoldBooks ?? 0)) + .toString(), + titleStyle: TextStyle(color: Colors.black), + color: colors["owners"]!, + ), + ]; + } +} + +class Indicator extends StatelessWidget { + const Indicator({ + super.key, + required this.color, + required this.text, + this.size = 16, + }); + final Color color; + final String text; + final double size; + + @override + Widget build(BuildContext context) { + return Row( + children: [ + Container( + width: size, + height: size, + decoration: BoxDecoration(shape: BoxShape.rectangle, color: color), + ), + const SizedBox(width: 4), + Text(text, style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), + ], + ); + } +}