mirror of
https://github.com/koloideal/Casha.git
synced 2026-06-10 18:35:28 +03:00
update
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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);
|
|
||||||
final withoutDecimals = full.endsWith('.00') ? full.substring(0, full.length - 3) : full;
|
|
||||||
return '$symbol$sep$withoutDecimals';
|
|
||||||
}
|
}
|
||||||
return formatAmount(symbol, amount, fmt); // existing helper
|
} else {
|
||||||
|
formatted = fmt.format(amount);
|
||||||
|
}
|
||||||
|
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,
|
||||||
|
|||||||
@@ -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),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user