mirror of
https://github.com/koloideal/Casha.git
synced 2026-06-10 02:15:29 +03:00
stableee
This commit is contained in:
@@ -190,5 +190,18 @@ class AppStrings {
|
|||||||
String get showConversionsOnCard =>
|
String get showConversionsOnCard =>
|
||||||
_ru ? 'Показывать на карточке' : 'Show on balance card';
|
_ru ? 'Показывать на карточке' : 'Show on balance card';
|
||||||
|
|
||||||
|
String get selectSourceAccount =>
|
||||||
|
_ru ? 'Выберите счёт отправителя' : 'Select source account';
|
||||||
|
String get selectDestAccount =>
|
||||||
|
_ru ? 'Выберите счёт получателя' : 'Select destination account';
|
||||||
|
String get accountsMustDiffer =>
|
||||||
|
_ru ? 'Счета должны отличаться' : 'Accounts must differ';
|
||||||
|
String get transferLabel => _ru ? 'Перевод' : 'Transfer';
|
||||||
|
String get transferTo => _ru ? 'на' : 'to';
|
||||||
|
String get transferFrom => _ru ? 'с' : 'from';
|
||||||
|
String get selectAccount => _ru ? 'Выберите счёт' : 'Select account';
|
||||||
|
String get accountPlaceholder => _ru ? 'Счёт' : 'Account';
|
||||||
|
String get saveError => _ru ? 'Ошибка сохранения' : 'Save error';
|
||||||
|
|
||||||
String get dateLocale => _ru ? 'ru_RU' : 'en_US';
|
String get dateLocale => _ru ? 'ru_RU' : 'en_US';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,13 +80,11 @@ class _AddTransactionScreenState extends ConsumerState<AddTransactionScreen>
|
|||||||
_amountController.text = widget.initial!.amount.toString();
|
_amountController.text = widget.initial!.amount.toString();
|
||||||
_noteController.text = widget.initial!.note ?? '';
|
_noteController.text = widget.initial!.note ?? '';
|
||||||
|
|
||||||
// Pre-populate toAccountId when opening Transfer for edit
|
|
||||||
if (widget.initial!.category == 'Transfer') {
|
if (widget.initial!.category == 'Transfer') {
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
final allTxs = ref.read(transactionsProvider).valueOrNull ?? [];
|
final allTxs = ref.read(transactionsProvider).valueOrNull ?? [];
|
||||||
|
|
||||||
if (widget.initial!.type == TransactionType.expense) {
|
if (widget.initial!.type == TransactionType.expense) {
|
||||||
// widget.initial IS the expense side — find income counterpart for To
|
|
||||||
final counterpart = allTxs.firstWhereOrNull(
|
final counterpart = allTxs.firstWhereOrNull(
|
||||||
(t) =>
|
(t) =>
|
||||||
t.id != widget.initial!.id &&
|
t.id != widget.initial!.id &&
|
||||||
@@ -110,7 +108,6 @@ class _AddTransactionScreenState extends ConsumerState<AddTransactionScreen>
|
|||||||
_transferIncomeRecordId = counterpart?.id;
|
_transferIncomeRecordId = counterpart?.id;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// widget.initial IS the income side — find expense counterpart
|
|
||||||
final expenseRecord = allTxs.firstWhereOrNull(
|
final expenseRecord = allTxs.firstWhereOrNull(
|
||||||
(t) =>
|
(t) =>
|
||||||
t.id != widget.initial!.id &&
|
t.id != widget.initial!.id &&
|
||||||
@@ -125,7 +122,6 @@ class _AddTransactionScreenState extends ConsumerState<AddTransactionScreen>
|
|||||||
t.note == widget.initial!.note,
|
t.note == widget.initial!.note,
|
||||||
);
|
);
|
||||||
if (expenseRecord != null) {
|
if (expenseRecord != null) {
|
||||||
// Swap: From = expense account, To = this income account
|
|
||||||
ref
|
ref
|
||||||
.read(addTransactionProvider(widget.initial).notifier)
|
.read(addTransactionProvider(widget.initial).notifier)
|
||||||
.setAccountId(expenseRecord.accountId);
|
.setAccountId(expenseRecord.accountId);
|
||||||
@@ -145,7 +141,6 @@ class _AddTransactionScreenState extends ConsumerState<AddTransactionScreen>
|
|||||||
final activeAccount = ref.read(activeAccountProvider);
|
final activeAccount = ref.read(activeAccountProvider);
|
||||||
final curr = ref.read(currencyProvider);
|
final curr = ref.read(currencyProvider);
|
||||||
|
|
||||||
// Use active account's currency if available, otherwise use global currency
|
|
||||||
final currencyCode = activeAccount?.currency ?? curr.code;
|
final currencyCode = activeAccount?.currency ?? curr.code;
|
||||||
final currencySymbol = currencyMap[currencyCode]?.symbol ?? curr.symbol;
|
final currencySymbol = currencyMap[currencyCode]?.symbol ?? curr.symbol;
|
||||||
|
|
||||||
@@ -153,7 +148,6 @@ class _AddTransactionScreenState extends ConsumerState<AddTransactionScreen>
|
|||||||
.read(addTransactionProvider(null).notifier)
|
.read(addTransactionProvider(null).notifier)
|
||||||
.setCurrency(currencySymbol, currencyCode);
|
.setCurrency(currencySymbol, currencyCode);
|
||||||
|
|
||||||
// Set the selected account if there's an active account
|
|
||||||
if (activeAccount != null) {
|
if (activeAccount != null) {
|
||||||
ref
|
ref
|
||||||
.read(addTransactionProvider(null).notifier)
|
.read(addTransactionProvider(null).notifier)
|
||||||
@@ -191,7 +185,7 @@ class _AddTransactionScreenState extends ConsumerState<AddTransactionScreen>
|
|||||||
final parts = normalized.split('.');
|
final parts = normalized.split('.');
|
||||||
if (parts.length == 2 && parts[1].length > 2) return null;
|
if (parts.length == 2 && parts[1].length > 2) return null;
|
||||||
|
|
||||||
return normalized; // valid, return normalized string
|
return normalized;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _triggerError() {
|
void _triggerError() {
|
||||||
@@ -200,6 +194,7 @@ class _AddTransactionScreenState extends ConsumerState<AddTransactionScreen>
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _submit() async {
|
Future<void> _submit() async {
|
||||||
|
final s = ref.read(stringsProvider);
|
||||||
final raw = _amountController.text;
|
final raw = _amountController.text;
|
||||||
final parsed = _validateAndParseAmount(raw);
|
final parsed = _validateAndParseAmount(raw);
|
||||||
|
|
||||||
@@ -216,17 +211,17 @@ class _AddTransactionScreenState extends ConsumerState<AddTransactionScreen>
|
|||||||
bool hasError = false;
|
bool hasError = false;
|
||||||
|
|
||||||
if (state.selectedAccountId == null) {
|
if (state.selectedAccountId == null) {
|
||||||
setState(() => _fromAccountError = 'Please select a source account');
|
setState(() => _fromAccountError = s.selectSourceAccount);
|
||||||
hasError = true;
|
hasError = true;
|
||||||
} else {
|
} else {
|
||||||
setState(() => _fromAccountError = null);
|
setState(() => _fromAccountError = null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.toAccountId == null) {
|
if (state.toAccountId == null) {
|
||||||
setState(() => _toAccountError = 'Please select a destination account');
|
setState(() => _toAccountError = s.selectDestAccount);
|
||||||
hasError = true;
|
hasError = true;
|
||||||
} else if (state.toAccountId == state.selectedAccountId) {
|
} else if (state.toAccountId == state.selectedAccountId) {
|
||||||
setState(() => _toAccountError = 'Source and destination must differ');
|
setState(() => _toAccountError = s.accountsMustDiffer);
|
||||||
hasError = true;
|
hasError = true;
|
||||||
} else {
|
} else {
|
||||||
setState(() => _toAccountError = null);
|
setState(() => _toAccountError = null);
|
||||||
@@ -256,14 +251,7 @@ class _AddTransactionScreenState extends ConsumerState<AddTransactionScreen>
|
|||||||
: _noteController.text.trim();
|
: _noteController.text.trim();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
print('--- SUBMIT CLICKED ---');
|
|
||||||
print(
|
|
||||||
'Amount: $amount, Category: ${state.category}, Type: ${state.type.name}',
|
|
||||||
);
|
|
||||||
|
|
||||||
if (state.type == TransactionType.transfer) {
|
if (state.type == TransactionType.transfer) {
|
||||||
// Handle transfer: create two transactions
|
|
||||||
// Get currency with fallback to global currency
|
|
||||||
final curr = ref.read(currencyProvider);
|
final curr = ref.read(currencyProvider);
|
||||||
final currency = state.overrideCurrency.isNotEmpty
|
final currency = state.overrideCurrency.isNotEmpty
|
||||||
? state.overrideCurrency
|
? state.overrideCurrency
|
||||||
@@ -273,8 +261,6 @@ class _AddTransactionScreenState extends ConsumerState<AddTransactionScreen>
|
|||||||
: curr.code;
|
: curr.code;
|
||||||
|
|
||||||
if (state.isEditing) {
|
if (state.isEditing) {
|
||||||
// Update both sides of the transfer pair
|
|
||||||
// Update the expense side
|
|
||||||
final updatedExpense = Transaction(
|
final updatedExpense = Transaction(
|
||||||
id: _transferExpenseRecordId ?? widget.initial!.id,
|
id: _transferExpenseRecordId ?? widget.initial!.id,
|
||||||
amount: amount,
|
amount: amount,
|
||||||
@@ -284,22 +270,21 @@ class _AddTransactionScreenState extends ConsumerState<AddTransactionScreen>
|
|||||||
note: note,
|
note: note,
|
||||||
currency: currency,
|
currency: currency,
|
||||||
currencyCode: currencyCode,
|
currencyCode: currencyCode,
|
||||||
accountId: state.selectedAccountId!, // from initState
|
accountId: state.selectedAccountId!,
|
||||||
);
|
);
|
||||||
await ref.read(transactionsProvider.notifier).update(updatedExpense);
|
await ref.read(transactionsProvider.notifier).update(updatedExpense);
|
||||||
|
|
||||||
// Update the income side
|
|
||||||
if (_transferIncomeRecordId != null) {
|
if (_transferIncomeRecordId != null) {
|
||||||
final updatedIncome = Transaction(
|
final updatedIncome = Transaction(
|
||||||
id: _transferIncomeRecordId!,
|
id: _transferIncomeRecordId!,
|
||||||
amount: amount, // updated amount
|
amount: amount,
|
||||||
category: 'Transfer',
|
category: 'Transfer',
|
||||||
type: TransactionType.income,
|
type: TransactionType.income,
|
||||||
date: finalDateTime,
|
date: finalDateTime,
|
||||||
note: note,
|
note: note,
|
||||||
currency: currency, // updated currency
|
currency: currency,
|
||||||
currencyCode: currencyCode,
|
currencyCode: currencyCode,
|
||||||
accountId: state.toAccountId!, // from initState
|
accountId: state.toAccountId!,
|
||||||
);
|
);
|
||||||
await ref.read(transactionsProvider.notifier).update(updatedIncome);
|
await ref.read(transactionsProvider.notifier).update(updatedIncome);
|
||||||
}
|
}
|
||||||
@@ -332,12 +317,9 @@ class _AddTransactionScreenState extends ConsumerState<AddTransactionScreen>
|
|||||||
accountId: state.toAccountId!,
|
accountId: state.toAccountId!,
|
||||||
);
|
);
|
||||||
|
|
||||||
print('Creating transfer transactions...');
|
|
||||||
await ref.read(transactionsProvider.notifier).add(expense);
|
await ref.read(transactionsProvider.notifier).add(expense);
|
||||||
await ref.read(transactionsProvider.notifier).add(income);
|
await ref.read(transactionsProvider.notifier).add(income);
|
||||||
print('Transfer completed');
|
|
||||||
} else {
|
} else {
|
||||||
// Handle regular income/expense
|
|
||||||
final activeAccount = ref.read(activeAccountProvider);
|
final activeAccount = ref.read(activeAccountProvider);
|
||||||
final selectedId = ref
|
final selectedId = ref
|
||||||
.read(addTransactionProvider(widget.initial))
|
.read(addTransactionProvider(widget.initial))
|
||||||
@@ -345,21 +327,13 @@ class _AddTransactionScreenState extends ConsumerState<AddTransactionScreen>
|
|||||||
int accountId;
|
int accountId;
|
||||||
|
|
||||||
if (selectedId != null && selectedId != 0) {
|
if (selectedId != null && selectedId != 0) {
|
||||||
print('Using selected account ID: $selectedId');
|
|
||||||
accountId = selectedId;
|
accountId = selectedId;
|
||||||
} else if (activeAccount != null) {
|
} else if (activeAccount != null) {
|
||||||
print(
|
|
||||||
'Using active account ID: ${activeAccount.id}, Name: ${activeAccount.name}',
|
|
||||||
);
|
|
||||||
accountId = activeAccount.id;
|
accountId = activeAccount.id;
|
||||||
} else {
|
} else {
|
||||||
print('No active account. Fetching main account...');
|
|
||||||
final mainAccount = await ref
|
final mainAccount = await ref
|
||||||
.read(accountRepositoryProvider)
|
.read(accountRepositoryProvider)
|
||||||
.getMain();
|
.getMain();
|
||||||
print(
|
|
||||||
'Main account fetched: ID=${mainAccount.id}, Name: ${mainAccount.name}',
|
|
||||||
);
|
|
||||||
accountId = mainAccount.id;
|
accountId = mainAccount.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -375,42 +349,27 @@ class _AddTransactionScreenState extends ConsumerState<AddTransactionScreen>
|
|||||||
accountId: accountId,
|
accountId: accountId,
|
||||||
);
|
);
|
||||||
|
|
||||||
print('Transaction object created: ID=${tx.id}, AccId=${tx.accountId}');
|
|
||||||
print('Calling provider to save...');
|
|
||||||
|
|
||||||
if (state.isEditing) {
|
if (state.isEditing) {
|
||||||
await ref.read(transactionsProvider.notifier).update(tx);
|
await ref.read(transactionsProvider.notifier).update(tx);
|
||||||
print('Update completed');
|
|
||||||
} else {
|
} else {
|
||||||
final res = await ref.read(transactionsProvider.notifier).add(tx);
|
final res = await ref.read(transactionsProvider.notifier).add(tx);
|
||||||
print(
|
|
||||||
'Add completed. Result: ${res.isSuccess ? "SUCCESS" : "FAILURE"}',
|
|
||||||
);
|
|
||||||
|
|
||||||
if (res.isFailure) {
|
if (res.isFailure) {
|
||||||
print('!!! Provider returned failure: ${res.errorOrNull}');
|
|
||||||
throw Exception(res.errorOrNull);
|
throw Exception(res.errorOrNull);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
print('Provider save completed successfully');
|
|
||||||
HapticService.medium();
|
HapticService.medium();
|
||||||
|
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
print('Popping screen...');
|
|
||||||
context.pop();
|
context.pop();
|
||||||
}
|
}
|
||||||
} catch (e, stack) {
|
} catch (e) {
|
||||||
print('!!! SAVE CRASHED !!!');
|
|
||||||
print('Error: $e');
|
|
||||||
print('Stack trace:');
|
|
||||||
print(stack);
|
|
||||||
|
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
content: Text('Save error: $e'),
|
content: Text('${s.saveError}: $e'),
|
||||||
backgroundColor: Colors.red,
|
backgroundColor: Colors.red,
|
||||||
duration: const Duration(seconds: 5),
|
duration: const Duration(seconds: 5),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import '../../../core/l10n/locale_provider.dart';
|
||||||
import '../../../shared/models/account.dart';
|
import '../../../shared/models/account.dart';
|
||||||
import '../../../shared/models/transaction.dart';
|
import '../../../shared/models/transaction.dart';
|
||||||
import '../../dashboard/provider.dart';
|
import '../../dashboard/provider.dart';
|
||||||
@@ -37,12 +38,12 @@ class AccountRow extends ConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final s = ref.watch(stringsProvider);
|
||||||
final state = ref.watch(addTransactionProvider(initial));
|
final state = ref.watch(addTransactionProvider(initial));
|
||||||
final accountsAsync = ref.watch(accountsProvider);
|
final accountsAsync = ref.watch(accountsProvider);
|
||||||
final accounts = accountsAsync.valueOrNull ?? [];
|
final accounts = accountsAsync.valueOrNull ?? [];
|
||||||
final isTransfer = state.type == TransactionType.transfer;
|
final isTransfer = state.type == TransactionType.transfer;
|
||||||
|
|
||||||
// Auto-select toAccount when only 2 accounts exist
|
|
||||||
if (isTransfer && accounts.length == 2 && state.selectedAccountId != null) {
|
if (isTransfer && accounts.length == 2 && state.selectedAccountId != null) {
|
||||||
final otherId = accounts
|
final otherId = accounts
|
||||||
.firstWhere(
|
.firstWhere(
|
||||||
@@ -63,7 +64,7 @@ class AccountRow extends ConsumerWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Account',
|
s.accountPlaceholder,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.6),
|
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.6),
|
||||||
@@ -95,6 +96,7 @@ class AccountRow extends ConsumerWidget {
|
|||||||
indicatorKey: fromIndicatorKey,
|
indicatorKey: fromIndicatorKey,
|
||||||
error: fromAccountError,
|
error: fromAccountError,
|
||||||
isDark: isDark,
|
isDark: isDark,
|
||||||
|
selectAccountText: s.selectAccount,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@@ -109,6 +111,7 @@ class _SingleAccountSelector extends ConsumerWidget {
|
|||||||
final GlobalKey indicatorKey;
|
final GlobalKey indicatorKey;
|
||||||
final String? error;
|
final String? error;
|
||||||
final bool isDark;
|
final bool isDark;
|
||||||
|
final String selectAccountText;
|
||||||
|
|
||||||
const _SingleAccountSelector({
|
const _SingleAccountSelector({
|
||||||
required this.initial,
|
required this.initial,
|
||||||
@@ -118,6 +121,7 @@ class _SingleAccountSelector extends ConsumerWidget {
|
|||||||
required this.indicatorKey,
|
required this.indicatorKey,
|
||||||
this.error,
|
this.error,
|
||||||
required this.isDark,
|
required this.isDark,
|
||||||
|
required this.selectAccountText,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -184,7 +188,7 @@ class _SingleAccountSelector extends ConsumerWidget {
|
|||||||
const SizedBox(width: 10),
|
const SizedBox(width: 10),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
displayAccount?.name ?? 'Select account',
|
displayAccount?.name ?? selectAccountText,
|
||||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||||
color: displayAccount != null
|
color: displayAccount != null
|
||||||
? Theme.of(context).colorScheme.onSurface
|
? Theme.of(context).colorScheme.onSurface
|
||||||
@@ -253,6 +257,7 @@ class _TransferAccountRow extends ConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final s = ref.watch(stringsProvider);
|
||||||
final state = ref.watch(addTransactionProvider(initial));
|
final state = ref.watch(addTransactionProvider(initial));
|
||||||
final activeAccount = ref.watch(activeAccountProvider);
|
final activeAccount = ref.watch(activeAccountProvider);
|
||||||
|
|
||||||
@@ -275,8 +280,6 @@ class _TransferAccountRow extends ConsumerWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// If no account is explicitly selected and we're on Total Balance
|
|
||||||
// creating a new transfer — show empty, force user to choose
|
|
||||||
if (activeAccount == null && initial == null) {
|
if (activeAccount == null && initial == null) {
|
||||||
fromAccount = null;
|
fromAccount = null;
|
||||||
} else {
|
} else {
|
||||||
@@ -306,6 +309,7 @@ class _TransferAccountRow extends ConsumerWidget {
|
|||||||
error: fromAccountError,
|
error: fromAccountError,
|
||||||
isDark: isDark,
|
isDark: isDark,
|
||||||
disabled: isFromAccountLocked,
|
disabled: isFromAccountLocked,
|
||||||
|
selectText: s.selectAccount,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
@@ -328,6 +332,7 @@ class _TransferAccountRow extends ConsumerWidget {
|
|||||||
error: toAccountError,
|
error: toAccountError,
|
||||||
isDark: isDark,
|
isDark: isDark,
|
||||||
disabled: autoSelectEnabled || isToAccountLocked,
|
disabled: autoSelectEnabled || isToAccountLocked,
|
||||||
|
selectText: s.selectAccount,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -344,6 +349,7 @@ class _AccountHalf extends StatelessWidget {
|
|||||||
final String? error;
|
final String? error;
|
||||||
final bool isDark;
|
final bool isDark;
|
||||||
final bool disabled;
|
final bool disabled;
|
||||||
|
final String selectText;
|
||||||
|
|
||||||
const _AccountHalf({
|
const _AccountHalf({
|
||||||
required this.account,
|
required this.account,
|
||||||
@@ -354,6 +360,7 @@ class _AccountHalf extends StatelessWidget {
|
|||||||
this.error,
|
this.error,
|
||||||
required this.isDark,
|
required this.isDark,
|
||||||
this.disabled = false,
|
this.disabled = false,
|
||||||
|
required this.selectText,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -413,7 +420,7 @@ class _AccountHalf extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 2),
|
const SizedBox(height: 2),
|
||||||
Text(
|
Text(
|
||||||
account?.name ?? 'Select',
|
account?.name ?? selectText,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
|
|||||||
@@ -274,10 +274,10 @@ class TransactionTile extends ConsumerWidget {
|
|||||||
List<Account> accounts,
|
List<Account> accounts,
|
||||||
Account? activeAccount,
|
Account? activeAccount,
|
||||||
) {
|
) {
|
||||||
// Fallback if no counterpart
|
final s = ref.watch(stringsProvider);
|
||||||
if (counterpart == null) {
|
if (counterpart == null) {
|
||||||
return Text(
|
return Text(
|
||||||
'Transfer',
|
s.transferLabel,
|
||||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
color: Theme.of(context).colorScheme.onSurface,
|
||||||
@@ -298,13 +298,12 @@ class TransactionTile extends ConsumerWidget {
|
|||||||
final destAccountName = _accountName(accounts, destAccountId);
|
final destAccountName = _accountName(accounts, destAccountId);
|
||||||
final onSurface = Theme.of(context).colorScheme.onSurface;
|
final onSurface = Theme.of(context).colorScheme.onSurface;
|
||||||
|
|
||||||
// Total Balance view (activeAccount == null), showing expense side
|
|
||||||
if (activeAccount == null) {
|
if (activeAccount == null) {
|
||||||
return Row(
|
return Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Transfer',
|
s.transferLabel,
|
||||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
color: onSurface,
|
color: onSurface,
|
||||||
@@ -321,14 +320,12 @@ class TransactionTile extends ConsumerWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Account view
|
|
||||||
if (isExpense) {
|
if (isExpense) {
|
||||||
// Expense side: Transfer to <destAccountName>
|
|
||||||
return Row(
|
return Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Transfer',
|
s.transferLabel,
|
||||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
color: onSurface,
|
color: onSurface,
|
||||||
@@ -336,7 +333,7 @@ class TransactionTile extends ConsumerWidget {
|
|||||||
),
|
),
|
||||||
const SizedBox(width: 6),
|
const SizedBox(width: 6),
|
||||||
Text(
|
Text(
|
||||||
'to',
|
s.transferTo,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 11,
|
fontSize: 11,
|
||||||
color: onSurface.withOpacity(0.45),
|
color: onSurface.withOpacity(0.45),
|
||||||
@@ -348,12 +345,11 @@ class TransactionTile extends ConsumerWidget {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// Income side: Transfer from <sourceAccountName>
|
|
||||||
return Row(
|
return Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Transfer',
|
s.transferLabel,
|
||||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
color: onSurface,
|
color: onSurface,
|
||||||
@@ -361,7 +357,7 @@ class TransactionTile extends ConsumerWidget {
|
|||||||
),
|
),
|
||||||
const SizedBox(width: 6),
|
const SizedBox(width: 6),
|
||||||
Text(
|
Text(
|
||||||
'from',
|
s.transferFrom,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 11,
|
fontSize: 11,
|
||||||
color: onSurface.withOpacity(0.45),
|
color: onSurface.withOpacity(0.45),
|
||||||
|
|||||||
Reference in New Issue
Block a user