mirror of
https://github.com/koloideal/Casha.git
synced 2026-08-08 17:51:14 +03:00
step
big
This commit is contained in:
@@ -1,187 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import '../../../core/l10n/app_strings.dart';
|
||||
import '../../../shared/providers/amount_format_provider.dart';
|
||||
import '../../../shared/utils/currency_utils.dart';
|
||||
import '../../../shared/widgets/byn_sign.dart';
|
||||
import '../../settings/provider.dart';
|
||||
|
||||
class BudgetProgress extends ConsumerWidget {
|
||||
final double spent;
|
||||
final double budget;
|
||||
final CurrencyInfo currencyInfo;
|
||||
final AppStrings strings;
|
||||
const BudgetProgress({
|
||||
super.key,
|
||||
required this.spent,
|
||||
required this.budget,
|
||||
required this.currencyInfo,
|
||||
required this.strings,
|
||||
});
|
||||
|
||||
Border? _themeBorder(BuildContext context) {
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
return isDark ? null : Border.all(color: const Color(0xFFDDDDEE), width: 1);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final fmt = ref.watch(amountFormatProvider);
|
||||
final progress = budget > 0 ? spent / budget : 0.0;
|
||||
final isOver = progress > 1.0;
|
||||
final displayPercent = (progress * 100).toStringAsFixed(0);
|
||||
|
||||
return ClipRRect(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
border: Border(
|
||||
left: BorderSide(
|
||||
color: isOver ? const Color(0xFFE05C6B) : const Color(0xFF7C6DED),
|
||||
width: 3,
|
||||
),
|
||||
top: _themeBorder(context)?.top ?? BorderSide.none,
|
||||
right: _themeBorder(context)?.right ?? BorderSide.none,
|
||||
bottom: _themeBorder(context)?.bottom ?? BorderSide.none,
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
strings.monthlyBudget,
|
||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||
color: Theme.of(
|
||||
context,
|
||||
).colorScheme.onSurface.withOpacity(0.6),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'$displayPercent%',
|
||||
style: TextStyle(
|
||||
color: isOver
|
||||
? const Color(0xFFE05C6B)
|
||||
: Theme.of(
|
||||
context,
|
||||
).colorScheme.onSurface.withOpacity(0.7),
|
||||
fontWeight: isOver ? FontWeight.w700 : FontWeight.normal,
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
child: LinearProgressIndicator(
|
||||
value: isOver ? 1.0 : progress,
|
||||
backgroundColor: Theme.of(
|
||||
context,
|
||||
).colorScheme.onSurface.withOpacity(0.1),
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
isOver
|
||||
? const Color(0xFFE05C6B)
|
||||
: (progress > 0.8
|
||||
? Colors.orange
|
||||
: const Color(0xFF4CAF8C)),
|
||||
),
|
||||
minHeight: 8,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
currencyInfo.code == 'BYN'
|
||||
? Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
'${strings.spent}: ',
|
||||
style: Theme.of(context).textTheme.bodySmall
|
||||
?.copyWith(
|
||||
color: Theme.of(
|
||||
context,
|
||||
).colorScheme.onSurface.withOpacity(0.6),
|
||||
),
|
||||
),
|
||||
BynSign(
|
||||
fontSize: 12,
|
||||
color: Theme.of(
|
||||
context,
|
||||
).colorScheme.onSurface.withOpacity(0.6),
|
||||
),
|
||||
const SizedBox(width: 2),
|
||||
Text(
|
||||
formatAmount('', spent, fmt),
|
||||
style: Theme.of(context).textTheme.bodySmall
|
||||
?.copyWith(
|
||||
color: Theme.of(
|
||||
context,
|
||||
).colorScheme.onSurface.withOpacity(0.6),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: Text(
|
||||
'${strings.spent}: ${formatAmount(currencyInfo.symbol, spent, fmt)}',
|
||||
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||
color: Theme.of(
|
||||
context,
|
||||
).colorScheme.onSurface.withOpacity(0.6),
|
||||
),
|
||||
),
|
||||
currencyInfo.code == 'BYN'
|
||||
? Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
'${strings.limit}: ',
|
||||
style: Theme.of(context).textTheme.bodySmall
|
||||
?.copyWith(
|
||||
color: Theme.of(
|
||||
context,
|
||||
).colorScheme.onSurface.withOpacity(0.6),
|
||||
),
|
||||
),
|
||||
BynSign(
|
||||
fontSize: 12,
|
||||
color: Theme.of(
|
||||
context,
|
||||
).colorScheme.onSurface.withOpacity(0.6),
|
||||
),
|
||||
const SizedBox(width: 2),
|
||||
Text(
|
||||
formatAmount('', budget, fmt),
|
||||
style: Theme.of(context).textTheme.bodySmall
|
||||
?.copyWith(
|
||||
color: Theme.of(
|
||||
context,
|
||||
).colorScheme.onSurface.withOpacity(0.6),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: Text(
|
||||
'${strings.limit}: ${formatAmount(currencyInfo.symbol, budget, fmt)}',
|
||||
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||
color: Theme.of(
|
||||
context,
|
||||
).colorScheme.onSurface.withOpacity(0.6),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import '../../../core/l10n/locale_provider.dart';
|
||||
import '../../../shared/models/transaction.dart';
|
||||
import '../../../shared/models/account.dart';
|
||||
import '../../../shared/providers/amount_format_provider.dart';
|
||||
import '../../../shared/providers/category_provider.dart';
|
||||
import '../../../shared/utils/currency_utils.dart';
|
||||
import '../../../shared/widgets/byn_sign.dart';
|
||||
import '../../settings/provider.dart';
|
||||
@@ -29,7 +30,9 @@ class TransactionTile extends ConsumerWidget {
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final s = ref.watch(stringsProvider);
|
||||
final isRu = s.locale == AppLocale.ru;
|
||||
final fmt = ref.watch(amountFormatProvider);
|
||||
final catalog = ref.watch(categoryCatalogProvider);
|
||||
final isTransfer = transaction.category == 'Transfer';
|
||||
final isIncome = transaction.type == TransactionType.income;
|
||||
final color = isTransfer
|
||||
@@ -37,10 +40,11 @@ class TransactionTile extends ConsumerWidget {
|
||||
: (isIncome ? AppColors.income : AppColors.expense);
|
||||
final catColor = isTransfer
|
||||
? const Color(0xFF7C6DED)
|
||||
: (AppCategories.colors[transaction.category] ?? AppColors.accent);
|
||||
: catalog.colorFor(transaction.category);
|
||||
final catIcon = isTransfer
|
||||
? Icons.swap_horiz_rounded
|
||||
: (AppCategories.icons[transaction.category] ?? Icons.category_rounded);
|
||||
: catalog.iconFor(transaction.category);
|
||||
final catLabel = catalog.labelFor(transaction.category, isRu);
|
||||
|
||||
final activeAccount = ref.watch(activeAccountProvider);
|
||||
final displayCurrency =
|
||||
@@ -105,7 +109,7 @@ class TransactionTile extends ConsumerWidget {
|
||||
activeAccount,
|
||||
)
|
||||
: Text(
|
||||
s.categoryLabel(transaction.category),
|
||||
catLabel,
|
||||
style: Theme.of(context).textTheme.bodyMedium
|
||||
?.copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
|
||||
Reference in New Issue
Block a user