/*
This file is part of GNU Taler
(C) 2022 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
import {
AbsoluteTime,
Amounts,
NotificationType,
ScopeType,
Transaction,
WalletBalance
} from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { useTranslationContext } from "@gnu-taler/web-util/browser";
import { startOfDay } from "date-fns";
import { Fragment, VNode, h } from "preact";
import { useEffect, useState } from "preact/hooks";
import { ErrorAlertView } from "../components/CurrentAlerts.js";
import { HistoryItem } from "../components/HistoryItem.js";
import { Loading } from "../components/Loading.js";
import { Time } from "../components/Time.js";
import {
CenteredBoldText,
CenteredText,
DateSeparator,
NiceSelect,
} from "../components/styled/index.js";
import { alertFromError, useAlertContext } from "../context/alert.js";
import { useBackendContext } from "../context/backend.js";
import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
import { useSettings } from "../hooks/useSettings.js";
import { Button } from "../mui/Button.js";
import { NoBalanceHelp } from "../popup/NoBalanceHelp.js";
import DownloadIcon from "../svg/download_24px.inline.svg";
import UploadIcon from "../svg/upload_24px.inline.svg";
interface Props {
currency?: string;
goToWalletDeposit: (currency: string) => Promise;
goToWalletManualWithdraw: (currency?: string) => Promise;
}
export function HistoryPage({
currency,
goToWalletManualWithdraw,
goToWalletDeposit,
}: Props): VNode {
const { i18n } = useTranslationContext();
const api = useBackendContext();
const [balanceIndex, setBalanceIndex] = useState(0);
const [settings] = useSettings();
const state = useAsyncAsHook(async () => {
const b = await api.wallet.call(WalletApiOperation.GetBalances, {})
const balance = b.balances.length > 0 ? b.balances[balanceIndex] : undefined
const tx = await api.wallet.call(WalletApiOperation.GetTransactions, {
scopeInfo: balance?.scopeInfo,
sort: "descending",
includeRefreshes: settings.showRefeshTransactions,
})
return { b, tx }
}, [balanceIndex]);
useEffect(() => {
return api.listener.onUpdateNotification(
[NotificationType.TransactionStateTransition],
state?.retry,
);
});
const { pushAlertOnError } = useAlertContext();
if (!state) {
return ;
}
if (state.hasError) {
return (
);
}
if (!state.response.b.balances.length) {
return (
);
}
return (
setBalanceIndex(b)}
balances={state.response.b.balances}
goToWalletManualWithdraw={goToWalletManualWithdraw}
goToWalletDeposit={goToWalletDeposit}
transactions={state.response.tx.transactions}
/>
);
}
export function HistoryView({
balances,
balanceIndex,
changeBalanceIndex,
transactions,
goToWalletManualWithdraw,
goToWalletDeposit,
}: {
balanceIndex: number,
changeBalanceIndex: (s: number) => void;
goToWalletDeposit: (currency: string) => Promise;
goToWalletManualWithdraw: (currency?: string) => Promise;
transactions: Transaction[];
balances: WalletBalance[];
}): VNode {
const { i18n } = useTranslationContext();
const balance = balances[balanceIndex];
const available = balance
? Amounts.jsonifyAmount(balance.available)
: undefined;
const datesWithTransaction: string[] = [];
const byDate = transactions.reduce((rv, x) => {
const startDay =
x.timestamp.t_s === "never" ? 0 : startOfDay(x.timestamp.t_s * 1000).getTime();
if (startDay) {
if (!rv[startDay]) {
rv[startDay] = [];
datesWithTransaction.push(String(startDay));
}
rv[startDay].push(x);
}
return rv;
}, {} as { [x: string]: Transaction[] });
return (