2021-06-16 23:21:03 +02:00
|
|
|
/*
|
|
|
|
This file is part of TALER
|
|
|
|
(C) 2016 GNUnet e.V.
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
|
|
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
|
|
|
|
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
|
|
|
*/
|
|
|
|
|
2021-11-15 15:18:58 +01:00
|
|
|
import {
|
2022-03-18 15:32:41 +01:00
|
|
|
AbsoluteTime,
|
2021-11-15 15:18:58 +01:00
|
|
|
Amounts,
|
2021-11-19 18:51:27 +01:00
|
|
|
NotificationType,
|
|
|
|
parsePaytoUri,
|
2022-05-03 05:16:03 +02:00
|
|
|
parsePayUri,
|
2021-11-15 15:18:58 +01:00
|
|
|
Transaction,
|
|
|
|
TransactionType,
|
2021-11-19 18:51:27 +01:00
|
|
|
WithdrawalType,
|
2021-11-15 15:18:58 +01:00
|
|
|
} from "@gnu-taler/taler-util";
|
2021-12-06 14:31:19 +01:00
|
|
|
import { differenceInSeconds } from "date-fns";
|
2021-11-19 18:51:27 +01:00
|
|
|
import { ComponentChildren, Fragment, h, VNode } from "preact";
|
2022-04-26 03:37:41 +02:00
|
|
|
import { useEffect, useState } from "preact/hooks";
|
2021-10-27 20:13:35 +02:00
|
|
|
import emptyImg from "../../static/img/empty.png";
|
2022-04-11 16:33:55 +02:00
|
|
|
import { Amount } from "../components/Amount.js";
|
2022-03-29 04:41:07 +02:00
|
|
|
import { BankDetailsByPaytoType } from "../components/BankDetailsByPaytoType.js";
|
|
|
|
import { ErrorTalerOperation } from "../components/ErrorTalerOperation.js";
|
|
|
|
import { Loading } from "../components/Loading.js";
|
|
|
|
import { LoadingError } from "../components/LoadingError.js";
|
2022-05-03 05:16:03 +02:00
|
|
|
import { Part, PartPayto } from "../components/Part.js";
|
2021-11-15 15:18:58 +01:00
|
|
|
import {
|
2021-11-16 17:59:53 +01:00
|
|
|
Button,
|
|
|
|
ButtonDestructive,
|
2021-11-15 15:18:58 +01:00
|
|
|
ButtonPrimary,
|
2021-11-19 18:51:27 +01:00
|
|
|
CenteredDialog,
|
|
|
|
InfoBox,
|
2021-11-15 15:18:58 +01:00
|
|
|
ListOfProducts,
|
2021-11-19 18:51:27 +01:00
|
|
|
Overlay,
|
2021-11-15 15:18:58 +01:00
|
|
|
RowBorderGray,
|
|
|
|
SmallLightText,
|
2022-03-28 19:03:59 +02:00
|
|
|
SubTitle,
|
2021-11-15 15:18:58 +01:00
|
|
|
WarningBox,
|
2022-03-29 04:41:07 +02:00
|
|
|
} from "../components/styled/index.js";
|
|
|
|
import { Time } from "../components/Time.js";
|
|
|
|
import { useTranslationContext } from "../context/translation.js";
|
2022-04-26 04:07:31 +02:00
|
|
|
import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
|
2022-05-14 23:09:33 +02:00
|
|
|
import { Pages } from "../NavigationBar.js";
|
2022-03-29 04:41:07 +02:00
|
|
|
import * as wxApi from "../wxApi.js";
|
2021-06-16 23:21:03 +02:00
|
|
|
|
2022-01-25 14:29:29 +01:00
|
|
|
interface Props {
|
|
|
|
tid: string;
|
|
|
|
goToWalletHistory: (currency?: string) => void;
|
|
|
|
}
|
2022-04-26 03:37:41 +02:00
|
|
|
|
|
|
|
async function getTransaction(tid: string): Promise<Transaction> {
|
|
|
|
const res = await wxApi.getTransactions();
|
|
|
|
const ts = res.transactions.filter((t) => t.transactionId === tid);
|
|
|
|
if (ts.length > 1) throw Error("more than one transaction with this id");
|
|
|
|
if (ts.length === 1) {
|
|
|
|
return ts[0];
|
|
|
|
}
|
|
|
|
throw Error("no transaction found");
|
|
|
|
}
|
|
|
|
|
2022-01-25 14:29:29 +01:00
|
|
|
export function TransactionPage({ tid, goToWalletHistory }: Props): VNode {
|
2022-03-14 19:20:32 +01:00
|
|
|
const { i18n } = useTranslationContext();
|
2021-11-19 18:51:27 +01:00
|
|
|
|
2022-04-26 04:07:31 +02:00
|
|
|
const state = useAsyncAsHook(() => getTransaction(tid));
|
2022-04-26 03:37:41 +02:00
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
wxApi.onUpdateNotification([NotificationType.WithdrawGroupFinished], () => {
|
|
|
|
state?.retry();
|
|
|
|
});
|
|
|
|
});
|
2021-06-16 23:21:03 +02:00
|
|
|
|
2021-11-19 18:51:27 +01:00
|
|
|
if (!state) {
|
2022-01-25 14:29:29 +01:00
|
|
|
return <Loading />;
|
2021-07-13 20:33:28 +02:00
|
|
|
}
|
2021-11-19 18:51:27 +01:00
|
|
|
|
|
|
|
if (state.hasError) {
|
|
|
|
return (
|
2022-01-25 14:29:29 +01:00
|
|
|
<LoadingError
|
2022-02-23 19:18:37 +01:00
|
|
|
title={
|
2022-02-23 19:44:14 +01:00
|
|
|
<i18n.Translate>
|
|
|
|
Could not load the transaction information
|
|
|
|
</i18n.Translate>
|
2022-02-23 19:18:37 +01:00
|
|
|
}
|
2022-01-25 14:29:29 +01:00
|
|
|
error={state}
|
|
|
|
/>
|
2021-11-19 18:51:27 +01:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-01-25 14:29:29 +01:00
|
|
|
const currency = Amounts.parse(state.response.amountRaw)?.currency;
|
2021-11-19 18:51:27 +01:00
|
|
|
|
2021-11-15 15:18:58 +01:00
|
|
|
return (
|
|
|
|
<TransactionView
|
2021-11-19 18:51:27 +01:00
|
|
|
transaction={state.response}
|
2022-01-25 14:29:29 +01:00
|
|
|
onDelete={() =>
|
|
|
|
wxApi.deleteTransaction(tid).then(() => goToWalletHistory(currency))
|
|
|
|
}
|
|
|
|
onRetry={() =>
|
|
|
|
wxApi.retryTransaction(tid).then(() => goToWalletHistory(currency))
|
|
|
|
}
|
|
|
|
onBack={() => goToWalletHistory(currency)}
|
2021-11-15 15:18:58 +01:00
|
|
|
/>
|
|
|
|
);
|
2021-06-16 23:21:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export interface WalletTransactionProps {
|
2021-10-15 00:37:18 +02:00
|
|
|
transaction: Transaction;
|
|
|
|
onDelete: () => void;
|
|
|
|
onRetry: () => void;
|
|
|
|
onBack: () => void;
|
2021-06-16 23:21:03 +02:00
|
|
|
}
|
|
|
|
|
2021-11-15 15:18:58 +01:00
|
|
|
export function TransactionView({
|
|
|
|
transaction,
|
|
|
|
onDelete,
|
|
|
|
onRetry,
|
|
|
|
onBack,
|
2021-11-16 17:59:53 +01:00
|
|
|
}: WalletTransactionProps): VNode {
|
2021-11-19 18:51:27 +01:00
|
|
|
const [confirmBeforeForget, setConfirmBeforeForget] = useState(false);
|
2021-12-06 14:31:19 +01:00
|
|
|
|
2021-11-19 18:51:27 +01:00
|
|
|
function doCheckBeforeForget(): void {
|
|
|
|
if (
|
|
|
|
transaction.pending &&
|
|
|
|
transaction.type === TransactionType.Withdrawal
|
|
|
|
) {
|
|
|
|
setConfirmBeforeForget(true);
|
|
|
|
} else {
|
|
|
|
onDelete();
|
|
|
|
}
|
|
|
|
}
|
2021-12-06 14:31:19 +01:00
|
|
|
|
2022-03-14 19:20:32 +01:00
|
|
|
const { i18n } = useTranslationContext();
|
|
|
|
|
2021-11-19 18:51:27 +01:00
|
|
|
function TransactionTemplate({
|
|
|
|
children,
|
|
|
|
}: {
|
|
|
|
children: ComponentChildren;
|
|
|
|
}): VNode {
|
2021-12-06 14:31:19 +01:00
|
|
|
const showRetry =
|
|
|
|
transaction.error !== undefined ||
|
2022-03-18 15:32:41 +01:00
|
|
|
transaction.timestamp.t_s === "never" ||
|
2021-12-06 14:31:19 +01:00
|
|
|
(transaction.pending &&
|
2022-03-18 15:32:41 +01:00
|
|
|
differenceInSeconds(new Date(), transaction.timestamp.t_s * 1000) > 10);
|
2021-12-06 14:31:19 +01:00
|
|
|
|
2021-11-15 15:18:58 +01:00
|
|
|
return (
|
2021-11-19 18:51:27 +01:00
|
|
|
<Fragment>
|
2021-11-15 15:18:58 +01:00
|
|
|
<section style={{ padding: 8, textAlign: "center" }}>
|
2021-11-29 18:11:32 +01:00
|
|
|
<ErrorTalerOperation
|
2022-02-23 19:18:37 +01:00
|
|
|
title={
|
2022-02-23 19:44:14 +01:00
|
|
|
<i18n.Translate>
|
2022-02-23 19:18:37 +01:00
|
|
|
There was an error trying to complete the transaction
|
2022-02-23 19:44:14 +01:00
|
|
|
</i18n.Translate>
|
2022-02-23 19:18:37 +01:00
|
|
|
}
|
2021-11-29 18:11:32 +01:00
|
|
|
error={transaction?.error}
|
|
|
|
/>
|
2021-11-15 15:18:58 +01:00
|
|
|
{transaction.pending && (
|
2022-02-23 19:18:37 +01:00
|
|
|
<WarningBox>
|
2022-02-23 19:44:14 +01:00
|
|
|
<i18n.Translate>This transaction is not completed</i18n.Translate>
|
2022-02-23 19:18:37 +01:00
|
|
|
</WarningBox>
|
2021-11-15 15:18:58 +01:00
|
|
|
)}
|
|
|
|
</section>
|
|
|
|
<section>
|
|
|
|
<div style={{ textAlign: "center" }}>{children}</div>
|
|
|
|
</section>
|
|
|
|
<footer>
|
2022-03-17 16:39:16 +01:00
|
|
|
<div />
|
2021-11-15 15:18:58 +01:00
|
|
|
<div>
|
2021-12-06 14:31:19 +01:00
|
|
|
{showRetry ? (
|
2021-11-15 15:18:58 +01:00
|
|
|
<ButtonPrimary onClick={onRetry}>
|
2022-02-23 19:44:14 +01:00
|
|
|
<i18n.Translate>Retry</i18n.Translate>
|
2021-11-15 15:18:58 +01:00
|
|
|
</ButtonPrimary>
|
|
|
|
) : null}
|
2021-11-19 18:51:27 +01:00
|
|
|
<ButtonDestructive onClick={doCheckBeforeForget}>
|
2022-02-23 19:44:14 +01:00
|
|
|
<i18n.Translate>Forget</i18n.Translate>
|
2021-11-16 17:59:53 +01:00
|
|
|
</ButtonDestructive>
|
2021-11-15 15:18:58 +01:00
|
|
|
</div>
|
|
|
|
</footer>
|
2021-11-19 18:51:27 +01:00
|
|
|
</Fragment>
|
2021-11-15 15:18:58 +01:00
|
|
|
);
|
2021-07-13 20:33:28 +02:00
|
|
|
}
|
2021-08-24 20:16:11 +02:00
|
|
|
|
2021-06-16 23:21:03 +02:00
|
|
|
if (transaction.type === TransactionType.Withdrawal) {
|
2021-06-21 01:37:35 +02:00
|
|
|
const fee = Amounts.sub(
|
|
|
|
Amounts.parseOrThrow(transaction.amountRaw),
|
|
|
|
Amounts.parseOrThrow(transaction.amountEffective),
|
2021-11-15 15:18:58 +01:00
|
|
|
).amount;
|
|
|
|
return (
|
|
|
|
<TransactionTemplate>
|
2021-11-19 18:51:27 +01:00
|
|
|
{confirmBeforeForget ? (
|
|
|
|
<Overlay>
|
|
|
|
<CenteredDialog>
|
2022-02-23 19:18:37 +01:00
|
|
|
<header>
|
2022-02-23 19:44:14 +01:00
|
|
|
<i18n.Translate>Caution!</i18n.Translate>
|
2022-02-23 19:18:37 +01:00
|
|
|
</header>
|
2021-11-19 18:51:27 +01:00
|
|
|
<section>
|
2022-02-23 19:44:14 +01:00
|
|
|
<i18n.Translate>
|
2022-02-23 19:18:37 +01:00
|
|
|
If you have already wired money to the exchange you will loose
|
|
|
|
the chance to get the coins form it.
|
2022-02-23 19:44:14 +01:00
|
|
|
</i18n.Translate>
|
2021-11-19 18:51:27 +01:00
|
|
|
</section>
|
|
|
|
<footer>
|
|
|
|
<Button onClick={() => setConfirmBeforeForget(false)}>
|
2022-02-23 19:44:14 +01:00
|
|
|
<i18n.Translate>Cancel</i18n.Translate>
|
2021-11-19 18:51:27 +01:00
|
|
|
</Button>
|
|
|
|
|
|
|
|
<ButtonDestructive onClick={onDelete}>
|
2022-02-23 19:44:14 +01:00
|
|
|
<i18n.Translate>Confirm</i18n.Translate>
|
2021-11-19 18:51:27 +01:00
|
|
|
</ButtonDestructive>
|
|
|
|
</footer>
|
|
|
|
</CenteredDialog>
|
|
|
|
</Overlay>
|
|
|
|
) : undefined}
|
2022-03-28 19:03:59 +02:00
|
|
|
<SubTitle>
|
2022-02-23 19:44:14 +01:00
|
|
|
<i18n.Translate>Withdrawal</i18n.Translate>
|
2022-03-28 19:03:59 +02:00
|
|
|
</SubTitle>
|
|
|
|
<Time
|
|
|
|
timestamp={AbsoluteTime.fromTimestamp(transaction.timestamp)}
|
|
|
|
format="dd MMMM yyyy, HH:mm"
|
|
|
|
/>
|
2021-11-19 18:51:27 +01:00
|
|
|
{transaction.pending ? (
|
|
|
|
transaction.withdrawalDetails.type ===
|
|
|
|
WithdrawalType.ManualTransfer ? (
|
|
|
|
<Fragment>
|
|
|
|
<BankDetailsByPaytoType
|
2022-04-18 21:20:44 +02:00
|
|
|
amount={Amounts.parseOrThrow(transaction.amountRaw)}
|
2021-11-19 18:51:27 +01:00
|
|
|
exchangeBaseUrl={transaction.exchangeBaseUrl}
|
|
|
|
payto={parsePaytoUri(
|
|
|
|
transaction.withdrawalDetails.exchangePaytoUris[0],
|
|
|
|
)}
|
|
|
|
subject={transaction.withdrawalDetails.reservePub}
|
|
|
|
/>
|
|
|
|
<p>
|
|
|
|
<WarningBox>
|
2022-02-23 19:44:14 +01:00
|
|
|
<i18n.Translate>
|
2022-02-23 19:18:37 +01:00
|
|
|
Make sure to use the correct subject, otherwise the money
|
|
|
|
will not arrive in this wallet.
|
2022-02-23 19:44:14 +01:00
|
|
|
</i18n.Translate>
|
2021-11-19 18:51:27 +01:00
|
|
|
</WarningBox>
|
|
|
|
</p>
|
|
|
|
<Part
|
|
|
|
big
|
2022-02-23 19:44:14 +01:00
|
|
|
title={<i18n.Translate>Total withdrawn</i18n.Translate>}
|
2022-04-11 16:33:55 +02:00
|
|
|
text={<Amount value={transaction.amountEffective} />}
|
2021-11-19 18:51:27 +01:00
|
|
|
kind="positive"
|
|
|
|
/>
|
|
|
|
<Part
|
|
|
|
big
|
2022-02-23 19:44:14 +01:00
|
|
|
title={<i18n.Translate>Exchange fee</i18n.Translate>}
|
2022-04-11 16:33:55 +02:00
|
|
|
text={<Amount value={fee} />}
|
2021-11-19 18:51:27 +01:00
|
|
|
kind="negative"
|
|
|
|
/>
|
|
|
|
</Fragment>
|
|
|
|
) : (
|
|
|
|
<Fragment>
|
|
|
|
{!transaction.withdrawalDetails.confirmed &&
|
|
|
|
transaction.withdrawalDetails.bankConfirmationUrl ? (
|
|
|
|
<InfoBox>
|
2022-02-23 19:44:14 +01:00
|
|
|
<i18n.Translate>
|
2022-02-23 19:18:37 +01:00
|
|
|
The bank is waiting for confirmation. Go to the
|
|
|
|
<a
|
|
|
|
href={transaction.withdrawalDetails.bankConfirmationUrl}
|
|
|
|
target="_blank"
|
|
|
|
rel="noreferrer"
|
|
|
|
>
|
2022-02-23 19:44:14 +01:00
|
|
|
<i18n.Translate>bank site</i18n.Translate>
|
2022-02-23 19:18:37 +01:00
|
|
|
</a>
|
2022-02-23 19:44:14 +01:00
|
|
|
</i18n.Translate>
|
2021-11-19 18:51:27 +01:00
|
|
|
</InfoBox>
|
|
|
|
) : undefined}
|
|
|
|
{transaction.withdrawalDetails.confirmed && (
|
2022-02-23 19:18:37 +01:00
|
|
|
<InfoBox>
|
2022-02-23 19:44:14 +01:00
|
|
|
<i18n.Translate>
|
|
|
|
Waiting for the coins to arrive
|
|
|
|
</i18n.Translate>
|
2022-02-23 19:18:37 +01:00
|
|
|
</InfoBox>
|
2021-11-19 18:51:27 +01:00
|
|
|
)}
|
|
|
|
<Part
|
|
|
|
big
|
2022-02-23 19:44:14 +01:00
|
|
|
title={<i18n.Translate>Total withdrawn</i18n.Translate>}
|
2022-04-11 16:33:55 +02:00
|
|
|
text={<Amount value={transaction.amountEffective} />}
|
2021-11-19 18:51:27 +01:00
|
|
|
kind="positive"
|
|
|
|
/>
|
|
|
|
<Part
|
|
|
|
big
|
2022-02-23 19:44:14 +01:00
|
|
|
title={<i18n.Translate>Chosen amount</i18n.Translate>}
|
2022-04-11 16:33:55 +02:00
|
|
|
text={<Amount value={transaction.amountRaw} />}
|
2021-11-19 18:51:27 +01:00
|
|
|
kind="neutral"
|
|
|
|
/>
|
|
|
|
<Part
|
|
|
|
big
|
2022-02-23 19:44:14 +01:00
|
|
|
title={<i18n.Translate>Exchange fee</i18n.Translate>}
|
2022-04-11 16:33:55 +02:00
|
|
|
text={<Amount value={fee} />}
|
2021-11-19 18:51:27 +01:00
|
|
|
kind="negative"
|
|
|
|
/>
|
|
|
|
</Fragment>
|
|
|
|
)
|
|
|
|
) : (
|
|
|
|
<Fragment>
|
|
|
|
<Part
|
|
|
|
big
|
2022-02-23 19:44:14 +01:00
|
|
|
title={<i18n.Translate>Total withdrawn</i18n.Translate>}
|
2022-04-11 16:33:55 +02:00
|
|
|
text={<Amount value={transaction.amountEffective} />}
|
2021-11-19 18:51:27 +01:00
|
|
|
kind="positive"
|
|
|
|
/>
|
|
|
|
<Part
|
|
|
|
big
|
2022-02-23 19:44:14 +01:00
|
|
|
title={<i18n.Translate>Chosen amount</i18n.Translate>}
|
2022-04-11 16:33:55 +02:00
|
|
|
text={<Amount value={transaction.amountRaw} />}
|
2021-11-19 18:51:27 +01:00
|
|
|
kind="neutral"
|
|
|
|
/>
|
|
|
|
<Part
|
|
|
|
big
|
2022-02-23 19:44:14 +01:00
|
|
|
title={<i18n.Translate>Exchange fee</i18n.Translate>}
|
2022-04-11 16:33:55 +02:00
|
|
|
text={<Amount value={fee} />}
|
2021-11-19 18:51:27 +01:00
|
|
|
kind="negative"
|
|
|
|
/>
|
|
|
|
</Fragment>
|
|
|
|
)}
|
2021-11-15 15:18:58 +01:00
|
|
|
<Part
|
2022-02-23 19:44:14 +01:00
|
|
|
title={<i18n.Translate>Exchange</i18n.Translate>}
|
2021-11-15 15:18:58 +01:00
|
|
|
text={new URL(transaction.exchangeBaseUrl).hostname}
|
|
|
|
kind="neutral"
|
|
|
|
/>
|
|
|
|
</TransactionTemplate>
|
|
|
|
);
|
2021-06-16 23:21:03 +02:00
|
|
|
}
|
|
|
|
|
2021-11-16 17:59:53 +01:00
|
|
|
const showLargePic = (): void => {
|
|
|
|
return;
|
|
|
|
};
|
2021-06-21 01:37:35 +02:00
|
|
|
|
2021-06-16 23:21:03 +02:00
|
|
|
if (transaction.type === TransactionType.Payment) {
|
2021-06-21 01:37:35 +02:00
|
|
|
const fee = Amounts.sub(
|
|
|
|
Amounts.parseOrThrow(transaction.amountEffective),
|
|
|
|
Amounts.parseOrThrow(transaction.amountRaw),
|
2021-11-15 15:18:58 +01:00
|
|
|
).amount;
|
2021-08-24 20:16:11 +02:00
|
|
|
|
2022-05-14 23:09:33 +02:00
|
|
|
const refundFee = Amounts.sub(
|
|
|
|
Amounts.parseOrThrow(transaction.totalRefundRaw),
|
|
|
|
Amounts.parseOrThrow(transaction.totalRefundEffective),
|
|
|
|
).amount;
|
|
|
|
const refunded = Amounts.isNonZero(
|
|
|
|
Amounts.parseOrThrow(transaction.totalRefundRaw),
|
|
|
|
);
|
|
|
|
const pendingRefund =
|
|
|
|
transaction.refundPending === undefined
|
|
|
|
? undefined
|
|
|
|
: Amounts.parseOrThrow(transaction.refundPending);
|
2021-11-15 15:18:58 +01:00
|
|
|
return (
|
|
|
|
<TransactionTemplate>
|
2022-03-28 19:03:59 +02:00
|
|
|
<SubTitle>
|
2022-02-23 19:44:14 +01:00
|
|
|
<i18n.Translate>Payment</i18n.Translate>
|
2022-03-28 19:03:59 +02:00
|
|
|
</SubTitle>
|
|
|
|
<Time
|
|
|
|
timestamp={AbsoluteTime.fromTimestamp(transaction.timestamp)}
|
|
|
|
format="dd MMMM yyyy, HH:mm"
|
|
|
|
/>
|
2021-11-15 15:18:58 +01:00
|
|
|
<br />
|
|
|
|
<Part
|
|
|
|
big
|
2022-02-23 19:44:14 +01:00
|
|
|
title={<i18n.Translate>Total paid</i18n.Translate>}
|
2022-04-11 16:33:55 +02:00
|
|
|
text={<Amount value={transaction.amountEffective} />}
|
2021-11-15 15:18:58 +01:00
|
|
|
kind="negative"
|
|
|
|
/>
|
2022-05-14 23:09:33 +02:00
|
|
|
{Amounts.isNonZero(fee) && (
|
|
|
|
<Fragment>
|
|
|
|
<Part
|
|
|
|
big
|
|
|
|
title={<i18n.Translate>Purchase amount</i18n.Translate>}
|
|
|
|
text={<Amount value={transaction.amountRaw} />}
|
|
|
|
kind="neutral"
|
|
|
|
/>
|
|
|
|
<Part
|
|
|
|
title={<i18n.Translate>Purchase Fee</i18n.Translate>}
|
|
|
|
text={<Amount value={fee} />}
|
|
|
|
kind="negative"
|
|
|
|
/>
|
|
|
|
</Fragment>
|
|
|
|
)}
|
|
|
|
{refunded && (
|
|
|
|
<Fragment>
|
|
|
|
<Part
|
|
|
|
big
|
|
|
|
title={<i18n.Translate>Total refunded</i18n.Translate>}
|
|
|
|
text={<Amount value={transaction.totalRefundEffective} />}
|
|
|
|
kind="positive"
|
|
|
|
/>
|
|
|
|
{Amounts.isNonZero(refundFee) && (
|
|
|
|
<Fragment>
|
|
|
|
<Part
|
|
|
|
big
|
|
|
|
title={<i18n.Translate>Refund amount</i18n.Translate>}
|
|
|
|
text={<Amount value={transaction.totalRefundRaw} />}
|
|
|
|
kind="neutral"
|
|
|
|
/>
|
|
|
|
<Part
|
|
|
|
title={<i18n.Translate>Refund fee</i18n.Translate>}
|
|
|
|
text={<Amount value={refundFee} />}
|
|
|
|
kind="negative"
|
|
|
|
/>
|
|
|
|
</Fragment>
|
|
|
|
)}
|
|
|
|
</Fragment>
|
|
|
|
)}
|
|
|
|
{pendingRefund !== undefined && Amounts.isNonZero(pendingRefund) && (
|
|
|
|
<Part
|
|
|
|
big
|
|
|
|
title={<i18n.Translate>Refund pending</i18n.Translate>}
|
|
|
|
text={<Amount value={pendingRefund} />}
|
|
|
|
kind="positive"
|
|
|
|
/>
|
|
|
|
)}
|
2022-02-23 19:18:37 +01:00
|
|
|
<Part
|
2022-02-23 19:44:14 +01:00
|
|
|
title={<i18n.Translate>Merchant</i18n.Translate>}
|
2021-11-15 15:18:58 +01:00
|
|
|
text={transaction.info.merchant.name}
|
|
|
|
kind="neutral"
|
|
|
|
/>
|
|
|
|
<Part
|
2022-02-23 19:44:14 +01:00
|
|
|
title={<i18n.Translate>Purchase</i18n.Translate>}
|
2022-03-17 19:00:34 +01:00
|
|
|
text={
|
|
|
|
transaction.info.fulfillmentUrl ? (
|
|
|
|
<a
|
|
|
|
href={transaction.info.fulfillmentUrl}
|
|
|
|
target="_bank"
|
|
|
|
rel="noreferrer"
|
|
|
|
>
|
|
|
|
{transaction.info.summary}
|
|
|
|
</a>
|
|
|
|
) : (
|
|
|
|
transaction.info.summary
|
|
|
|
)
|
|
|
|
}
|
2022-02-23 19:18:37 +01:00
|
|
|
kind="neutral"
|
|
|
|
/>
|
|
|
|
<Part
|
2022-02-23 19:44:14 +01:00
|
|
|
title={<i18n.Translate>Receipt</i18n.Translate>}
|
2021-11-15 15:18:58 +01:00
|
|
|
text={`#${transaction.info.orderId}`}
|
|
|
|
kind="neutral"
|
|
|
|
/>
|
|
|
|
|
|
|
|
<div>
|
|
|
|
{transaction.info.products && transaction.info.products.length > 0 && (
|
|
|
|
<ListOfProducts>
|
|
|
|
{transaction.info.products.map((p, k) => (
|
|
|
|
<RowBorderGray key={k}>
|
|
|
|
<a href="#" onClick={showLargePic}>
|
|
|
|
<img src={p.image ? p.image : emptyImg} />
|
|
|
|
</a>
|
|
|
|
<div>
|
|
|
|
{p.quantity && p.quantity > 0 && (
|
|
|
|
<SmallLightText>
|
|
|
|
x {p.quantity} {p.unit}
|
|
|
|
</SmallLightText>
|
|
|
|
)}
|
|
|
|
<div>{p.description}</div>
|
|
|
|
</div>
|
|
|
|
</RowBorderGray>
|
|
|
|
))}
|
|
|
|
</ListOfProducts>
|
|
|
|
)}
|
|
|
|
</div>
|
|
|
|
</TransactionTemplate>
|
|
|
|
);
|
2021-06-16 23:21:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (transaction.type === TransactionType.Deposit) {
|
2021-06-21 01:37:35 +02:00
|
|
|
const fee = Amounts.sub(
|
|
|
|
Amounts.parseOrThrow(transaction.amountEffective),
|
2021-12-23 19:17:36 +01:00
|
|
|
Amounts.parseOrThrow(transaction.amountRaw),
|
2021-11-15 15:18:58 +01:00
|
|
|
).amount;
|
2022-05-03 05:16:03 +02:00
|
|
|
const payto = parsePaytoUri(transaction.targetPaytoUri);
|
2021-11-15 15:18:58 +01:00
|
|
|
return (
|
|
|
|
<TransactionTemplate>
|
2022-03-28 19:03:59 +02:00
|
|
|
<SubTitle>
|
2022-02-23 19:44:14 +01:00
|
|
|
<i18n.Translate>Deposit</i18n.Translate>
|
2022-03-28 19:03:59 +02:00
|
|
|
</SubTitle>
|
|
|
|
<Time
|
|
|
|
timestamp={AbsoluteTime.fromTimestamp(transaction.timestamp)}
|
|
|
|
format="dd MMMM yyyy, HH:mm"
|
|
|
|
/>
|
2021-11-15 15:18:58 +01:00
|
|
|
<br />
|
|
|
|
<Part
|
|
|
|
big
|
2022-02-23 19:44:14 +01:00
|
|
|
title={<i18n.Translate>Total send</i18n.Translate>}
|
2022-04-11 16:33:55 +02:00
|
|
|
text={<Amount value={transaction.amountEffective} />}
|
2021-12-23 19:17:36 +01:00
|
|
|
kind="neutral"
|
2021-11-15 15:18:58 +01:00
|
|
|
/>
|
2022-05-14 23:09:33 +02:00
|
|
|
{Amounts.isNonZero(fee) && (
|
|
|
|
<Fragment>
|
|
|
|
<Part
|
|
|
|
big
|
|
|
|
title={<i18n.Translate>Deposit amount</i18n.Translate>}
|
|
|
|
text={<Amount value={transaction.amountRaw} />}
|
|
|
|
kind="positive"
|
|
|
|
/>
|
|
|
|
<Part
|
|
|
|
big
|
|
|
|
title={<i18n.Translate>Fee</i18n.Translate>}
|
|
|
|
text={<Amount value={fee} />}
|
|
|
|
kind="negative"
|
|
|
|
/>
|
|
|
|
</Fragment>
|
|
|
|
)}
|
2022-05-03 05:16:03 +02:00
|
|
|
{payto && <PartPayto big payto={payto} kind="neutral" />}
|
2021-11-15 15:18:58 +01:00
|
|
|
</TransactionTemplate>
|
|
|
|
);
|
2021-06-16 23:21:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (transaction.type === TransactionType.Refresh) {
|
2021-06-21 01:37:35 +02:00
|
|
|
const fee = Amounts.sub(
|
|
|
|
Amounts.parseOrThrow(transaction.amountRaw),
|
|
|
|
Amounts.parseOrThrow(transaction.amountEffective),
|
2021-11-15 15:18:58 +01:00
|
|
|
).amount;
|
|
|
|
return (
|
|
|
|
<TransactionTemplate>
|
2022-03-28 19:03:59 +02:00
|
|
|
<SubTitle>
|
2022-02-23 19:44:14 +01:00
|
|
|
<i18n.Translate>Refresh</i18n.Translate>
|
2022-03-28 19:03:59 +02:00
|
|
|
</SubTitle>
|
|
|
|
<Time
|
|
|
|
timestamp={AbsoluteTime.fromTimestamp(transaction.timestamp)}
|
|
|
|
format="dd MMMM yyyy, HH:mm"
|
|
|
|
/>
|
2021-11-15 15:18:58 +01:00
|
|
|
<br />
|
|
|
|
<Part
|
|
|
|
big
|
2022-02-23 19:44:14 +01:00
|
|
|
title={<i18n.Translate>Total refresh</i18n.Translate>}
|
2022-04-11 16:33:55 +02:00
|
|
|
text={<Amount value={transaction.amountEffective} />}
|
2021-11-15 15:18:58 +01:00
|
|
|
kind="negative"
|
|
|
|
/>
|
2022-05-14 23:09:33 +02:00
|
|
|
{Amounts.isNonZero(fee) && (
|
|
|
|
<Fragment>
|
|
|
|
<Part
|
|
|
|
big
|
|
|
|
title={<i18n.Translate>Refresh amount</i18n.Translate>}
|
|
|
|
text={<Amount value={transaction.amountRaw} />}
|
|
|
|
kind="neutral"
|
|
|
|
/>
|
|
|
|
<Part
|
|
|
|
big
|
|
|
|
title={<i18n.Translate>Fee</i18n.Translate>}
|
|
|
|
text={<Amount value={fee} />}
|
|
|
|
kind="negative"
|
|
|
|
/>
|
|
|
|
</Fragment>
|
|
|
|
)}
|
2021-11-15 15:18:58 +01:00
|
|
|
</TransactionTemplate>
|
|
|
|
);
|
2021-06-16 23:21:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (transaction.type === TransactionType.Tip) {
|
2021-06-21 01:37:35 +02:00
|
|
|
const fee = Amounts.sub(
|
|
|
|
Amounts.parseOrThrow(transaction.amountRaw),
|
|
|
|
Amounts.parseOrThrow(transaction.amountEffective),
|
2021-11-15 15:18:58 +01:00
|
|
|
).amount;
|
|
|
|
return (
|
|
|
|
<TransactionTemplate>
|
2022-03-28 19:03:59 +02:00
|
|
|
<SubTitle>
|
2022-02-23 19:44:14 +01:00
|
|
|
<i18n.Translate>Tip</i18n.Translate>
|
2022-03-28 19:03:59 +02:00
|
|
|
</SubTitle>
|
|
|
|
<Time
|
|
|
|
timestamp={AbsoluteTime.fromTimestamp(transaction.timestamp)}
|
|
|
|
format="dd MMMM yyyy, HH:mm"
|
|
|
|
/>
|
2021-11-15 15:18:58 +01:00
|
|
|
<br />
|
|
|
|
<Part
|
|
|
|
big
|
2022-02-23 19:44:14 +01:00
|
|
|
title={<i18n.Translate>Total tip</i18n.Translate>}
|
2022-05-03 00:21:34 +02:00
|
|
|
text={<Amount value={transaction.amountRaw} />}
|
2021-11-15 15:18:58 +01:00
|
|
|
kind="positive"
|
|
|
|
/>
|
2022-05-14 23:09:33 +02:00
|
|
|
{Amounts.isNonZero(fee) && (
|
|
|
|
<Fragment>
|
|
|
|
<Part
|
|
|
|
big
|
|
|
|
title={<i18n.Translate>Received amount</i18n.Translate>}
|
|
|
|
text={<Amount value={transaction.amountEffective} />}
|
|
|
|
kind="neutral"
|
|
|
|
/>
|
|
|
|
<Part
|
|
|
|
big
|
|
|
|
title={<i18n.Translate>Fee</i18n.Translate>}
|
|
|
|
text={<Amount value={fee} />}
|
|
|
|
kind="negative"
|
|
|
|
/>
|
|
|
|
</Fragment>
|
|
|
|
)}
|
2021-11-15 15:18:58 +01:00
|
|
|
</TransactionTemplate>
|
|
|
|
);
|
2021-06-16 23:21:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (transaction.type === TransactionType.Refund) {
|
2021-06-21 01:37:35 +02:00
|
|
|
const fee = Amounts.sub(
|
|
|
|
Amounts.parseOrThrow(transaction.amountRaw),
|
|
|
|
Amounts.parseOrThrow(transaction.amountEffective),
|
2021-11-15 15:18:58 +01:00
|
|
|
).amount;
|
|
|
|
return (
|
|
|
|
<TransactionTemplate>
|
2022-03-28 19:03:59 +02:00
|
|
|
<SubTitle>
|
2022-02-23 19:44:14 +01:00
|
|
|
<i18n.Translate>Refund</i18n.Translate>
|
2022-03-28 19:03:59 +02:00
|
|
|
</SubTitle>
|
2022-03-18 15:32:41 +01:00
|
|
|
<Time
|
|
|
|
timestamp={AbsoluteTime.fromTimestamp(transaction.timestamp)}
|
|
|
|
format="dd MMMM yyyy, HH:mm"
|
|
|
|
/>
|
2021-11-15 15:18:58 +01:00
|
|
|
<br />
|
|
|
|
<Part
|
|
|
|
big
|
2022-02-23 19:44:14 +01:00
|
|
|
title={<i18n.Translate>Total refund</i18n.Translate>}
|
2022-04-11 16:33:55 +02:00
|
|
|
text={<Amount value={transaction.amountEffective} />}
|
2021-11-15 15:18:58 +01:00
|
|
|
kind="positive"
|
|
|
|
/>
|
2022-05-14 23:09:33 +02:00
|
|
|
{Amounts.isNonZero(fee) && (
|
|
|
|
<Fragment>
|
|
|
|
<Part
|
|
|
|
big
|
|
|
|
title={<i18n.Translate>Refund amount</i18n.Translate>}
|
|
|
|
text={<Amount value={transaction.amountRaw} />}
|
|
|
|
kind="neutral"
|
|
|
|
/>
|
|
|
|
<Part
|
|
|
|
big
|
|
|
|
title={<i18n.Translate>Fee</i18n.Translate>}
|
|
|
|
text={<Amount value={fee} />}
|
|
|
|
kind="negative"
|
|
|
|
/>
|
|
|
|
</Fragment>
|
|
|
|
)}
|
2022-02-23 19:18:37 +01:00
|
|
|
<Part
|
2022-02-23 19:44:14 +01:00
|
|
|
title={<i18n.Translate>Merchant</i18n.Translate>}
|
2021-11-15 15:18:58 +01:00
|
|
|
text={transaction.info.merchant.name}
|
|
|
|
kind="neutral"
|
|
|
|
/>
|
2022-05-14 23:09:33 +02:00
|
|
|
|
2021-11-15 15:18:58 +01:00
|
|
|
<Part
|
2022-02-23 19:44:14 +01:00
|
|
|
title={<i18n.Translate>Purchase</i18n.Translate>}
|
2022-03-17 19:00:34 +01:00
|
|
|
text={
|
2022-05-14 23:09:33 +02:00
|
|
|
<a
|
|
|
|
href={Pages.balance_transaction.replace(
|
|
|
|
":tid",
|
|
|
|
transaction.refundedTransactionId,
|
|
|
|
)}
|
|
|
|
// href={transaction.info.fulfillmentUrl}
|
|
|
|
// target="_bank"
|
|
|
|
// rel="noreferrer"
|
|
|
|
>
|
|
|
|
{transaction.info.summary}
|
|
|
|
</a>
|
2022-03-17 19:00:34 +01:00
|
|
|
}
|
2022-02-23 19:18:37 +01:00
|
|
|
kind="neutral"
|
|
|
|
/>
|
|
|
|
<Part
|
2022-02-23 19:44:14 +01:00
|
|
|
title={<i18n.Translate>Receipt</i18n.Translate>}
|
2021-11-15 15:18:58 +01:00
|
|
|
text={`#${transaction.info.orderId}`}
|
|
|
|
kind="neutral"
|
|
|
|
/>
|
2021-06-16 23:21:03 +02:00
|
|
|
|
2021-11-15 15:18:58 +01:00
|
|
|
<div>
|
|
|
|
{transaction.info.products && transaction.info.products.length > 0 && (
|
|
|
|
<ListOfProducts>
|
|
|
|
{transaction.info.products.map((p, k) => (
|
|
|
|
<RowBorderGray key={k}>
|
|
|
|
<a href="#" onClick={showLargePic}>
|
|
|
|
<img src={p.image ? p.image : emptyImg} />
|
|
|
|
</a>
|
|
|
|
<div>
|
|
|
|
{p.quantity && p.quantity > 0 && (
|
|
|
|
<SmallLightText>
|
|
|
|
x {p.quantity} {p.unit}
|
|
|
|
</SmallLightText>
|
|
|
|
)}
|
|
|
|
<div>{p.description}</div>
|
|
|
|
</div>
|
|
|
|
</RowBorderGray>
|
|
|
|
))}
|
|
|
|
</ListOfProducts>
|
|
|
|
)}
|
|
|
|
</div>
|
|
|
|
</TransactionTemplate>
|
|
|
|
);
|
|
|
|
}
|
2021-06-16 23:21:03 +02:00
|
|
|
|
2021-11-16 17:59:53 +01:00
|
|
|
return <div />;
|
2021-06-16 23:21:03 +02:00
|
|
|
}
|