This commit is contained in:
2026-03-20 16:56:24 +03:00
parent 9835206a78
commit 582e21a7e2
3 changed files with 100 additions and 14 deletions
+6
View File
@@ -42,6 +42,12 @@ class TransactionsNotifier extends StateNotifier<List<Transaction>> {
state = [...state, transaction]; state = [...state, transaction];
_storage.addTransaction(transaction); _storage.addTransaction(transaction);
} }
void clearAll() {
state = [];
// also clear from SharedPreferences:
SharedPreferences.getInstance().then((prefs) => prefs.remove('transactions'));
}
} }
// Search and filter state // Search and filter state
+14 -14
View File
@@ -10,22 +10,22 @@ import '../settings/provider.dart';
import 'provider.dart'; import 'provider.dart';
// Helper for balance card only - hides .00 decimals // Helper for balance card only - hides .00 decimals
String _formatBalanceAmount(String symbol, double amount, AmountFormat fmt) { String _smartBalance(double amount, AmountFormat fmt, String symbol) {
const spaceAfter = {'Br', ''}; const spaceAfter = {'Br', ''};
final sep = spaceAfter.contains(symbol) ? ' ' : ''; final sep = spaceAfter.contains(symbol) ? ' ' : '';
final isWhole = amount == amount.floorToDouble();
// Check if decimal part is zero String formatted;
final hasDecimals = (amount - amount.truncate()) != 0; if (isWhole) {
// format the integer, then manually remove .00
if (!hasDecimals) { formatted = fmt.format(amount);
// Format integer part only using the selected format style if (formatted.endsWith('.00')) {
final intAmount = amount.truncate().toDouble(); formatted = formatted.substring(0, formatted.length - 3);
// Use fmt.format but strip the .00 }
final full = fmt.format(intAmount); } else {
final withoutDecimals = full.endsWith('.00') ? full.substring(0, full.length - 3) : full; formatted = fmt.format(amount);
return '$symbol$sep$withoutDecimals';
} }
return formatAmount(symbol, amount, fmt); // existing helper return '$symbol$sep$formatted';
} }
class DashboardScreen extends ConsumerStatefulWidget { class DashboardScreen extends ConsumerStatefulWidget {
@@ -407,7 +407,7 @@ class _BalanceCard extends ConsumerWidget {
fit: BoxFit.scaleDown, fit: BoxFit.scaleDown,
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: Text( child: Text(
_formatBalanceAmount(currencyInfo.symbol, balance, fmt), _smartBalance(balance, fmt, currencyInfo.symbol),
style: TextStyle( style: TextStyle(
fontSize: 36, // max font size fontSize: 36, // max font size
fontWeight: FontWeight.w700, fontWeight: FontWeight.w700,
@@ -444,7 +444,7 @@ class _BalanceCard extends ConsumerWidget {
fit: BoxFit.scaleDown, fit: BoxFit.scaleDown,
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: Text( child: Text(
_formatBalanceAmount(c.$2, converted, fmt), _smartBalance(converted, fmt, c.$2),
style: TextStyle( style: TextStyle(
fontSize: 13, fontSize: 13,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
+80
View File
@@ -6,6 +6,7 @@ import 'package:intl/intl.dart';
import '../../core/constants.dart'; import '../../core/constants.dart';
import '../../shared/utils/currency_utils.dart'; import '../../shared/utils/currency_utils.dart';
import '../../shared/providers/amount_format_provider.dart'; import '../../shared/providers/amount_format_provider.dart';
import '../dashboard/provider.dart';
import 'provider.dart'; import 'provider.dart';
class SettingsScreen extends ConsumerStatefulWidget { class SettingsScreen extends ConsumerStatefulWidget {
@@ -50,6 +51,55 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
setState(() => _isEditing = false); setState(() => _isEditing = false);
} }
void _confirmClearData(BuildContext context, WidgetRef ref) {
// First confirmation
showDialog(
context: context,
builder: (ctx) => AlertDialog(
title: const Text('Clear all transactions?'),
content: const Text('This will permanently delete all your transaction history. This cannot be undone.'),
actions: [
TextButton(
onPressed: () => Navigator.pop(ctx),
child: const Text('Cancel'),
),
TextButton(
onPressed: () {
Navigator.pop(ctx);
// Second confirmation
showDialog(
context: context,
builder: (ctx2) => AlertDialog(
title: const Text('Are you absolutely sure?'),
content: const Text('All transactions will be deleted forever. There is no way to recover them.'),
actions: [
TextButton(
onPressed: () => Navigator.pop(ctx2),
child: const Text('No, keep them'),
),
TextButton(
onPressed: () {
ref.read(transactionsProvider.notifier).clearAll();
Navigator.pop(ctx2);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('All transactions deleted')),
);
},
style: TextButton.styleFrom(foregroundColor: const Color(0xFFE05C6B)),
child: const Text('Yes, delete everything'),
),
],
),
);
},
style: TextButton.styleFrom(foregroundColor: const Color(0xFFE05C6B)),
child: const Text('Delete'),
),
],
),
);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final budget = ref.watch(budgetProvider); final budget = ref.watch(budgetProvider);
@@ -434,6 +484,36 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
], ],
), ),
), ),
const SizedBox(height: 24),
// Danger Zone
Text(
'Danger Zone',
style: TextStyle(
fontSize: 12,
letterSpacing: 1.2,
color: const Color(0xFFE05C6B).withOpacity(0.8),
fontWeight: FontWeight.w600,
),
),
const SizedBox(height: 8),
SizedBox(
width: double.infinity,
child: OutlinedButton.icon(
onPressed: () => _confirmClearData(context, ref),
icon: const Icon(Icons.delete_forever, color: Color(0xFFE05C6B)),
label: const Text(
'Clear All Transactions',
style: TextStyle(color: Color(0xFFE05C6B)),
),
style: OutlinedButton.styleFrom(
side: BorderSide(color: const Color(0xFFE05C6B).withOpacity(0.5)),
padding: const EdgeInsets.symmetric(vertical: 14),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
),
),
),
const SizedBox(height: 32),
], ],
), ),
), ),