Files
actual-importer/web/src/pages/PrepareTransactionsPage/TransactionsTable.tsx

74 lines
2.3 KiB
TypeScript

import { useCallback, useMemo } from "react";
import type { Transaction } from "../../types/api";
import styles from "./TransactionsTable.module.css";
import classNames from "classnames";
export type TransactionsTableProps = {
transactions: Transaction[];
deselected: number[];
deselect: (index: number) => void;
select: (index: number) => void;
readonly?: boolean;
}
const transactionEmoji = (transaction: Transaction): string => {
if (transaction.kind === 'transfer') {
return '➡️'
};
return transaction.amount > 0 ? '⬇️' : '⬆️';
};
const transactionType = (transaction: Transaction): string => {
if (transaction.kind === 'transfer') {
return 'Transfer'
};
return transaction.amount > 0 ? 'Inflow' : 'Outflow';
};
export default function TransactionsTable({ transactions, deselected, deselect, select, readonly }: TransactionsTableProps) {
const changeSelection = useCallback((index: number) => {
if (readonly) {
return;
}
if(deselected.includes(index)) {
select(index);
}
else {
deselect(index);
}
}, [deselected, deselect, select]);
const reversedTransactions = useMemo(() => transactions.slice().reverse(), [transactions]);
const renderRow = useCallback((transaction: Transaction, index: number) => (
<div
key={index}
onClick={() => changeSelection(index)}
className={classNames('notification', styles.transaction, {
'is-success': transaction.kind === 'regular' && transaction.amount > 0,
'is-danger': transaction.kind === 'regular' && transaction.amount < 0,
'is-info': transaction.kind === 'transfer',
'is-light': deselected.includes(index)
})}>
<h6 className="title is-6" title={transactionType(transaction)}>
{transactionEmoji(transaction)} {transaction.date}
</h6>
{transaction.id && (<><strong>ID:</strong> {transaction.id}<br /></>)}
<strong>From:</strong> {transaction.from}<br />
<strong>To:</strong> {transaction.to}<br />
<strong>Title:</strong> {transaction.title}<br />
<strong>Amount:</strong> <span className={styles.amount}>{transaction.amount}</span>
</div>
), [changeSelection]);
return (
<div className={styles.transactionsTable}>
{reversedTransactions.map(renderRow)}
</div>
);
}