90 lines
2.9 KiB
Dart
90 lines
2.9 KiB
Dart
/// Transactions that share a given label.
|
|
library;
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:provider/provider.dart';
|
|
|
|
import '../models/transaction_meta.dart';
|
|
import '../providers/bank_provider.dart';
|
|
import '../providers/tx_meta_provider.dart';
|
|
import '../utils/helpers.dart';
|
|
import '../widgets/responsive_body.dart';
|
|
import 'transaction_detail_screen.dart';
|
|
|
|
class LabelTransactionsScreen extends StatelessWidget {
|
|
const LabelTransactionsScreen({super.key, required this.label});
|
|
|
|
final TxLabel label;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final bank = context.watch<BankController>();
|
|
final meta = context.watch<TxMetaController>();
|
|
final txs = [
|
|
for (final tx in bank.transactions)
|
|
if (meta.metaFor(tx).labelIds.contains(label.id)) tx,
|
|
];
|
|
final theme = Theme.of(context);
|
|
final colors = theme.colorScheme;
|
|
final currency = bank.balance?.currency ??
|
|
(txs.isNotEmpty ? txs.first.currency : 'EUR');
|
|
var totalOut = 0.0;
|
|
for (final tx in txs) {
|
|
if (tx.amount < 0) totalOut += tx.amount.abs();
|
|
}
|
|
|
|
return Scaffold(
|
|
appBar: AppBar(
|
|
title: Text(label.name),
|
|
),
|
|
body: ResponsiveBody(
|
|
child: ListView(
|
|
padding: const EdgeInsets.only(top: 8, bottom: 32),
|
|
children: [
|
|
ListTile(
|
|
contentPadding: EdgeInsets.zero,
|
|
leading: Icon(label.icon, color: label.color),
|
|
title: Text('${txs.length} transactions'),
|
|
subtitle: Text('Money out ${formatMoney(totalOut, currency)}'),
|
|
),
|
|
const Divider(),
|
|
if (txs.isEmpty)
|
|
Padding(
|
|
padding: const EdgeInsets.symmetric(vertical: 32),
|
|
child: Text(
|
|
'No transactions with this label.',
|
|
textAlign: TextAlign.center,
|
|
style: theme.textTheme.bodyMedium,
|
|
),
|
|
)
|
|
else
|
|
for (final tx in txs)
|
|
ListTile(
|
|
contentPadding: EdgeInsets.zero,
|
|
title: Text(
|
|
tx.description,
|
|
maxLines: 2,
|
|
overflow: TextOverflow.ellipsis,
|
|
),
|
|
subtitle: Text(formatIsoDate(tx.date)),
|
|
trailing: Text(
|
|
formatMoney(tx.amount, tx.currency),
|
|
style: theme.textTheme.titleSmall?.copyWith(
|
|
color: tx.amount >= 0 ? colors.primary : colors.error,
|
|
),
|
|
),
|
|
onTap: () {
|
|
Navigator.of(context).push(
|
|
MaterialPageRoute<void>(
|
|
builder: (_) => TransactionDetailScreen(tx: tx),
|
|
),
|
|
);
|
|
},
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|