import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:prasule/api/category.dart'; import 'package:prasule/api/wallet.dart'; import 'package:prasule/api/walletmanager.dart'; import 'package:prasule/main.dart'; import 'package:prasule/pw/platformbutton.dart'; import 'package:prasule/pw/platformroute.dart'; import 'package:prasule/util/drawer.dart'; import 'package:prasule/util/graphs.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:prasule/views/settings/settings.dart'; import 'package:prasule/views/setup.dart'; import 'package:shared_preferences/shared_preferences.dart'; class GraphView extends StatefulWidget { const GraphView({super.key}); @override State createState() => _GraphViewState(); } class _GraphViewState extends State { var _selectedDate = DateTime.now(); Wallet? selectedWallet; List wallets = []; String? locale; var yearlyBtnSet = {"monthly"}; var graphTypeSet = {"expense", "income"}; bool get yearly => yearlyBtnSet.contains("yearly"); @override void didChangeDependencies() { super.didChangeDependencies(); locale ??= Localizations.localeOf(context).languageCode; } List generateChartData(EntryType type) { var data = List.filled( (yearly) ? 12 : DateTime(_selectedDate.year, _selectedDate.month, 0).day, 0.0); if (selectedWallet == null) return []; for (var i = 0; i < data.length; i++) { var entriesForRange = selectedWallet!.entries.where((element) => ((!yearly) ? element.date.month == _selectedDate.month && element.date.year == _selectedDate.year && element.date.day == i + 1 : element.date.month == i + 1 && element.date.year == _selectedDate.year) && element.type == type); var sum = 0.0; for (var e in entriesForRange) { sum += e.data.amount; } data[i] = sum; } return data; } void loadWallet() async { wallets = await WalletManager.listWallets(); if (wallets.isEmpty && mounted) { Navigator.of(context).pushReplacement( MaterialPageRoute(builder: (c) => const SetupView())); return; } selectedWallet = wallets.first; setState(() {}); } int? chartType; @override void initState() { super.initState(); loadWallet(); SharedPreferences.getInstance().then((s) { chartType = s.getInt("monthlygraph") ?? 2; setState(() {}); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: DropdownButton( value: (selectedWallet == null) ? -1 : wallets.indexOf(selectedWallet!), items: [ ...wallets.map( (e) => DropdownMenuItem( value: wallets.indexOf( e, ), child: Text(e.name), ), ), DropdownMenuItem( value: -1, child: Text(AppLocalizations.of(context).newWallet), ) ], onChanged: (v) async { if (v == null || v == -1) { await Navigator.of(context).push( platformRoute( (c) => const SetupView( newWallet: true, ), ), ); wallets = await WalletManager.listWallets(); logger.i(wallets.length); selectedWallet = wallets.last; setState(() {}); return; } selectedWallet = wallets[v]; setState(() {}); }, ), actions: [ PopupMenuButton( itemBuilder: (context) => [ AppLocalizations.of(context).settings, AppLocalizations.of(context).about ].map((e) => PopupMenuItem(value: e, child: Text(e))).toList(), onSelected: (value) { if (value == AppLocalizations.of(context).settings) { Navigator.of(context).push( MaterialPageRoute( builder: (context) => const SettingsView(), ), ); } else if (value == AppLocalizations.of(context).about) { showAboutDialog( context: context, applicationLegalese: AppLocalizations.of(context).license, applicationName: "PraĊĦule"); } }, ) ], ), drawer: makeDrawer(context, 2), body: SingleChildScrollView( child: Center( child: (selectedWallet == null) ? const CircularProgressIndicator( strokeWidth: 5, ) : SizedBox( width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.height, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ SegmentedButton( segments: [ ButtonSegment( value: "expense", label: Text(AppLocalizations.of(context).expenses), ), ButtonSegment( value: "income", label: Text(AppLocalizations.of(context).income), ), ], selected: graphTypeSet, multiSelectionEnabled: true, onSelectionChanged: (selection) { graphTypeSet = selection; setState(() {}); }, ), const SizedBox( height: 5, ), SegmentedButton( segments: [ ButtonSegment( value: "yearly", label: Text(AppLocalizations.of(context).yearly), ), ButtonSegment( value: "monthly", label: Text(AppLocalizations.of(context).monthly), ), ], selected: yearlyBtnSet, onSelectionChanged: (selection) async { yearlyBtnSet = selection; var s = await SharedPreferences.getInstance(); chartType = (yearly) ? (s.getInt("yearlygraph") ?? 1) : (s.getInt("monthlygraph") ?? 2); setState(() {}); }, ), const SizedBox(height: 5), Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), color: Theme.of(context) .colorScheme .secondaryContainer), child: Padding( padding: const EdgeInsets.all(8.0), child: Column( children: [ PlatformButton( style: ButtonStyle( backgroundColor: MaterialStateProperty.all( Theme.of(context).colorScheme.primary), foregroundColor: MaterialStateProperty.all( Theme.of(context) .colorScheme .onPrimary)), text: (yearly) ? DateFormat.y(locale).format(_selectedDate) : DateFormat.yMMMM(locale) .format(_selectedDate), onPressed: () async { var firstDate = (selectedWallet!.entries ..sort( (a, b) => a.date.compareTo(b.date))) .first .date; var lastDate = (selectedWallet!.entries ..sort( (a, b) => b.date.compareTo(a.date))) .first .date; logger.i(firstDate); logger.i(lastDate); var newDate = await showDatePicker( context: context, initialDate: DateTime(_selectedDate.year, _selectedDate.month, 1), firstDate: firstDate, lastDate: lastDate, initialEntryMode: (yearly) ? DatePickerEntryMode.input : DatePickerEntryMode.calendar, initialDatePickerMode: (yearly) ? DatePickerMode.year : DatePickerMode.day); if (newDate == null) return; _selectedDate = newDate; setState(() {}); }, ), const SizedBox( height: 5, ), SizedBox( width: MediaQuery.of(context).size.width * 0.9, height: 300, child: (chartType == null) ? const CircularProgressIndicator() : (chartType == 1) ? ExpensesBarChart( currency: selectedWallet!.currency, date: _selectedDate, locale: locale ?? "en", yearly: yearly, expenseData: (graphTypeSet .contains("expense")) ? generateChartData( EntryType.expense) : [], incomeData: (graphTypeSet .contains("income")) ? generateChartData( EntryType.income) : [], ) : ExpensesLineChart( currency: selectedWallet!.currency, date: _selectedDate, locale: locale ?? "en", yearly: yearly, expenseData: (graphTypeSet .contains("expense")) ? generateChartData( EntryType.expense) : [], incomeData: (graphTypeSet .contains("income")) ? generateChartData( EntryType.income) : [], ), ) ], ), ), ) ], ), ), ), ), ); } }