✨ Transaction details
This commit is contained in:
@@ -1176,5 +1176,14 @@
|
|||||||
"noRecipientsSelected": "No recipients selected",
|
"noRecipientsSelected": "No recipients selected",
|
||||||
"selectRecipientsToSendFund": "Select recipients to send the fund to",
|
"selectRecipientsToSendFund": "Select recipients to send the fund to",
|
||||||
"addRecipient": "Add Recipient",
|
"addRecipient": "Add Recipient",
|
||||||
"addMoreRecipients": "Add More Recipients"
|
"addMoreRecipients": "Add More Recipients",
|
||||||
|
"transactionDetails": "Transaction Details",
|
||||||
|
"remarks": "Remarks",
|
||||||
|
"payer": "Payer",
|
||||||
|
"payee": "Payee",
|
||||||
|
"transactionType": "Transaction Type",
|
||||||
|
"transfer": "Transfer",
|
||||||
|
"payment": "Payment",
|
||||||
|
"systemWallet": "System Wallet",
|
||||||
|
"date": "Date"
|
||||||
}
|
}
|
||||||
|
@@ -1075,5 +1075,6 @@
|
|||||||
"deleteRecycledFiles": "删除被回收的文件",
|
"deleteRecycledFiles": "删除被回收的文件",
|
||||||
"recycledFilesDeleted": "被回收文件成功删除",
|
"recycledFilesDeleted": "被回收文件成功删除",
|
||||||
"failedToDeleteRecycledFiles": "删除被回收文件失败",
|
"failedToDeleteRecycledFiles": "删除被回收文件失败",
|
||||||
"upload": "上传"
|
"upload": "上传",
|
||||||
|
"systemWallet": "中央统筹"
|
||||||
}
|
}
|
@@ -8,6 +8,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|||||||
import 'package:island/models/account.dart';
|
import 'package:island/models/account.dart';
|
||||||
import 'package:island/models/wallet.dart';
|
import 'package:island/models/wallet.dart';
|
||||||
import 'package:island/pods/network.dart';
|
import 'package:island/pods/network.dart';
|
||||||
|
import 'package:island/widgets/account/account_pfc.dart';
|
||||||
import 'package:island/widgets/account/account_picker.dart';
|
import 'package:island/widgets/account/account_picker.dart';
|
||||||
import 'package:island/widgets/app_scaffold.dart';
|
import 'package:island/widgets/app_scaffold.dart';
|
||||||
import 'package:island/widgets/content/cloud_files.dart';
|
import 'package:island/widgets/content/cloud_files.dart';
|
||||||
@@ -659,6 +660,173 @@ Future<SnWalletFund> walletFund(Ref ref, String fundId) async {
|
|||||||
return SnWalletFund.fromJson(resp.data);
|
return SnWalletFund.fromJson(resp.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TransactionDetailSheet extends StatelessWidget {
|
||||||
|
final SnTransaction transaction;
|
||||||
|
|
||||||
|
const TransactionDetailSheet({super.key, required this.transaction});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final isIncome =
|
||||||
|
transaction.payeeWalletId == null ||
|
||||||
|
transaction.payeeWallet?.accountId == null;
|
||||||
|
|
||||||
|
return SheetScaffold(
|
||||||
|
titleText: 'transactionDetails'.tr(),
|
||||||
|
heightFactor: 0.75,
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// Amount
|
||||||
|
Text(
|
||||||
|
'amount'.tr(),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Gap(4),
|
||||||
|
Text(
|
||||||
|
'${transaction.amount.toStringAsFixed(2)} ${transaction.currency}',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: isIncome ? Colors.green : Colors.red,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Gap(16),
|
||||||
|
|
||||||
|
// Remarks
|
||||||
|
if (transaction.remarks != null &&
|
||||||
|
transaction.remarks!.isNotEmpty) ...[
|
||||||
|
Text(
|
||||||
|
'remarks'.tr(),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Gap(4),
|
||||||
|
Text(
|
||||||
|
transaction.remarks!,
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
|
),
|
||||||
|
const Gap(16),
|
||||||
|
],
|
||||||
|
|
||||||
|
// Date
|
||||||
|
Text(
|
||||||
|
'date'.tr(),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Gap(4),
|
||||||
|
Text(
|
||||||
|
DateFormat.yMd().add_Hm().format(transaction.createdAt),
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
|
),
|
||||||
|
const Gap(16),
|
||||||
|
|
||||||
|
// Payer
|
||||||
|
Text(
|
||||||
|
'payer'.tr(),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Gap(4),
|
||||||
|
AccountPfcGestureDetector(
|
||||||
|
uname: transaction.payerWallet?.account?.name,
|
||||||
|
child: Row(
|
||||||
|
spacing: 8,
|
||||||
|
children: [
|
||||||
|
if (transaction.payerWallet?.account != null)
|
||||||
|
ProfilePictureWidget(
|
||||||
|
file: transaction.payerWallet!.account!.profile.picture,
|
||||||
|
radius: 12,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
transaction.payerWallet?.account?.nick ??
|
||||||
|
'systemWallet'.tr(),
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Gap(16),
|
||||||
|
|
||||||
|
// Payee
|
||||||
|
Text(
|
||||||
|
'payee'.tr(),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Gap(4),
|
||||||
|
AccountPfcGestureDetector(
|
||||||
|
uname: transaction.payeeWallet?.account?.name,
|
||||||
|
child: Row(
|
||||||
|
spacing: 8,
|
||||||
|
children: [
|
||||||
|
if (transaction.payeeWallet?.account != null)
|
||||||
|
ProfilePictureWidget(
|
||||||
|
file: transaction.payeeWallet!.account!.profile.picture,
|
||||||
|
radius: 12,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
transaction.payeeWallet?.account?.nick ??
|
||||||
|
'systemWallet'.tr(),
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Gap(16),
|
||||||
|
|
||||||
|
// Transaction Type
|
||||||
|
Text(
|
||||||
|
'transactionType'.tr(),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Gap(4),
|
||||||
|
Text(
|
||||||
|
_getTransactionTypeText(transaction.type),
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String _getTransactionTypeText(int type) {
|
||||||
|
// Assuming types: 0: transfer, 1: payment, etc. Adjust based on actual types
|
||||||
|
switch (type) {
|
||||||
|
case 0:
|
||||||
|
return 'transfer'.tr();
|
||||||
|
case 1:
|
||||||
|
return 'payment'.tr();
|
||||||
|
default:
|
||||||
|
return 'unknown'.tr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class WalletScreen extends HookConsumerWidget {
|
class WalletScreen extends HookConsumerWidget {
|
||||||
const WalletScreen({super.key});
|
const WalletScreen({super.key});
|
||||||
|
|
||||||
@@ -802,7 +970,19 @@ class WalletScreen extends HookConsumerWidget {
|
|||||||
final isIncome =
|
final isIncome =
|
||||||
transaction.payeeWalletId == wallet.value?.id;
|
transaction.payeeWalletId == wallet.value?.id;
|
||||||
|
|
||||||
return ListTile(
|
return InkWell(
|
||||||
|
onTap: () {
|
||||||
|
showModalBottomSheet(
|
||||||
|
context: context,
|
||||||
|
useRootNavigator: true,
|
||||||
|
isScrollControlled: true,
|
||||||
|
builder:
|
||||||
|
(context) => TransactionDetailSheet(
|
||||||
|
transaction: transaction,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: ListTile(
|
||||||
key: ValueKey(transaction.id),
|
key: ValueKey(transaction.id),
|
||||||
leading: Icon(
|
leading: Icon(
|
||||||
isIncome
|
isIncome
|
||||||
@@ -822,7 +1002,9 @@ class WalletScreen extends HookConsumerWidget {
|
|||||||
trailing: Text(
|
trailing: Text(
|
||||||
'${isIncome ? '+' : '-'}${transaction.amount.toStringAsFixed(2)} ${transaction.currency}',
|
'${isIncome ? '+' : '-'}${transaction.amount.toStringAsFixed(2)} ${transaction.currency}',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: isIncome ? Colors.green : Colors.red,
|
color:
|
||||||
|
isIncome ? Colors.green : Colors.red,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@@ -189,7 +189,7 @@ class AccountProfileCard extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class AccountPfcGestureDetector extends StatelessWidget {
|
class AccountPfcGestureDetector extends StatelessWidget {
|
||||||
final String uname;
|
final String? uname;
|
||||||
final Widget child;
|
final Widget child;
|
||||||
const AccountPfcGestureDetector({
|
const AccountPfcGestureDetector({
|
||||||
super.key,
|
super.key,
|
||||||
@@ -202,7 +202,13 @@ class AccountPfcGestureDetector extends StatelessWidget {
|
|||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
child: child,
|
child: child,
|
||||||
onTapDown: (details) {
|
onTapDown: (details) {
|
||||||
showAccountProfileCard(context, uname, offset: details.localPosition);
|
if (uname != null) {
|
||||||
|
showAccountProfileCard(
|
||||||
|
context,
|
||||||
|
uname!,
|
||||||
|
offset: details.localPosition,
|
||||||
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user