summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-webextension/src/wallet/Transaction.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'packages/taler-wallet-webextension/src/wallet/Transaction.tsx')
-rw-r--r--packages/taler-wallet-webextension/src/wallet/Transaction.tsx855
1 files changed, 421 insertions, 434 deletions
diff --git a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx
index 10ca67663..1f0293352 100644
--- a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx
@@ -19,6 +19,7 @@ import {
AmountJson,
Amounts,
AmountString,
+ DenomLossEventType,
MerchantInfo,
NotificationType,
OrderShortInfo,
@@ -230,72 +231,75 @@ function TransactionTemplate({
<Fragment>
<section style={{ padding: 8, textAlign: "center" }}>
{transaction?.error &&
- // FIXME: wallet core should stop sending this error on KYC
- transaction.error.code !==
+ // FIXME: wallet core should stop sending this error on KYC
+ transaction.error.code !==
TalerErrorCode.WALLET_WITHDRAWAL_KYC_REQUIRED ? (
<ErrorAlertView
error={alertFromError(
i18n,
- i18n.str`There was an error trying to complete the transaction`,
+ i18n.str`There was an error trying to complete the transaction.`,
transaction.error,
)}
/>
) : undefined}
- {transaction.txState.minor === TransactionMinorState.KycRequired && (
- <AlertView
- alert={{
- type: "warning",
- message: i18n.str`KYC check required for the transaction to complete`,
- description:
- transaction.kycUrl && typeof transaction.kycUrl === "string" ? (
- <div>
- <i18n.Translate>
- Follow this link to the{` `}
- <a
- rel="noreferrer"
- target="_bank"
- href={transaction.kycUrl}
- >
- KYC verifier
- </a>
- </i18n.Translate>
- </div>
- ) : (
- i18n.str`No more information has been provided`
- ),
- }}
- />
- )}
- {transaction.txState.minor === TransactionMinorState.AmlRequired && (
- <WarningBox>
- <i18n.Translate>
- The transaction has been blocked since the account required an AML
- check
- </i18n.Translate>
- </WarningBox>
- )}
- {transaction.txState.major === TransactionMajorState.Pending && (
- <WarningBox>
- <div style={{ justifyContent: "center", lineHeight: "25px" }}>
- <i18n.Translate>This transaction is not completed</i18n.Translate>
- <Link onClick={onRetry} style={{padding: 0}}>
- <SvgIcon
- title={i18n.str`Retry`}
- dangerouslySetInnerHTML={{ __html: refreshIcon }}
- color="black"
- />
- </Link>
- </div>
- </WarningBox>
- )}
+ {transaction.txState.major === TransactionMajorState.Pending &&
+ (transaction.txState.minor === TransactionMinorState.KycRequired ? (
+ <AlertView
+ alert={{
+ type: "warning",
+ message: i18n.str`KYC check required for the transaction to complete.`,
+ description:
+ transaction.kycUrl &&
+ typeof transaction.kycUrl === "string" ? (
+ <div>
+ <i18n.Translate>
+ Follow this link to the{` `}
+ <a
+ rel="noreferrer"
+ target="_bank"
+ href={transaction.kycUrl}
+ >
+ KYC verifier.
+ </a>
+ </i18n.Translate>
+ </div>
+ ) : (
+ i18n.str`No additional information has been provided.`
+ ),
+ }}
+ />
+ ) : transaction.txState.minor ===
+ TransactionMinorState.AmlRequired ? (
+ <WarningBox>
+ <i18n.Translate>
+ The transaction has been blocked since the account required an
+ AML check.
+ </i18n.Translate>
+ </WarningBox>
+ ) : (
+ <WarningBox>
+ <div style={{ justifyContent: "center", lineHeight: "25px" }}>
+ <i18n.Translate>
+ This transaction is not completed
+ </i18n.Translate>
+ <Link onClick={onRetry} style={{ padding: 0 }}>
+ <SvgIcon
+ title={i18n.str`Retry`}
+ dangerouslySetInnerHTML={{ __html: refreshIcon }}
+ color="black"
+ />
+ </Link>
+ </div>
+ </WarningBox>
+ ))}
{transaction.txState.major === TransactionMajorState.Aborted && (
<InfoBox>
- <i18n.Translate>This transaction was aborted</i18n.Translate>
+ <i18n.Translate>This transaction was aborted.</i18n.Translate>
</InfoBox>
)}
{transaction.txState.major === TransactionMajorState.Failed && (
<ErrorBox>
- <i18n.Translate>This transaction failed</i18n.Translate>
+ <i18n.Translate>This transaction failed.</i18n.Translate>
</ErrorBox>
)}
{confirmBeforeForget ? (
@@ -426,7 +430,7 @@ export function TransactionView({
transaction,
onDelete,
onAbort,
- onBack,
+ // onBack,
onResume,
onSuspend,
onRetry,
@@ -443,10 +447,13 @@ export function TransactionView({
transaction.type === TransactionType.Withdrawal ||
transaction.type === TransactionType.InternalWithdrawal
) {
- const conversion =
- transaction.withdrawalDetails.type === WithdrawalType.ManualTransfer
- ? transaction.withdrawalDetails.exchangeCreditAccountDetails ?? []
- : [];
+ // const conversion =
+ // transaction.withdrawalDetails.type === WithdrawalType.ManualTransfer
+ // ? transaction.withdrawalDetails.exchangeCreditAccountDetails ?? []
+ // : [];
+ const blockedByKycOrAml =
+ transaction.txState.minor === TransactionMinorState.KycRequired ||
+ transaction.txState.minor === TransactionMinorState.AmlRequired;
return (
<TransactionTemplate
transaction={transaction}
@@ -466,30 +473,32 @@ export function TransactionView({
{transaction.exchangeBaseUrl}
</Header>
- {transaction.txState.major !==
- TransactionMajorState.Pending ? undefined : transaction.txState
- .minor === TransactionMinorState.KycRequired ||
- transaction.txState.minor ===
- TransactionMinorState.AmlRequired ? undefined : transaction
- .withdrawalDetails.type === WithdrawalType.ManualTransfer
- && transaction.withdrawalDetails.exchangeCreditAccountDetails ? (
+ {transaction.txState.major !== TransactionMajorState.Pending ||
+ blockedByKycOrAml ? undefined : transaction.withdrawalDetails.type ===
+ WithdrawalType.ManualTransfer &&
+ transaction.withdrawalDetails.exchangeCreditAccountDetails ? (
<Fragment>
<InfoBox>
- {transaction.withdrawalDetails.exchangeCreditAccountDetails.length > 1 ?
+ {transaction.withdrawalDetails.exchangeCreditAccountDetails
+ .length > 1 ? (
<span>
<i18n.Translate>
- Now the payment service provider is waiting for <Amount value={raw} /> to
- be transferred. Select one of the accounts and use the information below
- to complete the operation by making a wire transfer from your bank account.
+ Now the payment service provider is waiting for{" "}
+ <Amount value={raw} /> to be transferred. Select one of the
+ accounts and use the information below to complete the
+ operation by making a wire transfer from your bank account.
</i18n.Translate>
</span>
- :
- <span><i18n.Translate>
- Now the payment service provider is waiting for <Amount value={raw} /> to
- be transferred. Use the information below to complete the operation
- by making a wire transfer from your bank account.
- </i18n.Translate></span>}
-
+ ) : (
+ <span>
+ <i18n.Translate>
+ Now the payment service provider is waiting for{" "}
+ <Amount value={raw} /> to be transferred. Use the
+ information below to complete the operation by making a wire
+ transfer from your bank account.
+ </i18n.Translate>
+ </span>
+ )}
</InfoBox>
<BankDetailsByPaytoType
amount={raw}
@@ -581,6 +590,7 @@ export function TransactionView({
format="dd MMMM yyyy"
/>
}
+ .
</i18n.Translate>
</td>
</tr>
@@ -649,11 +659,11 @@ export function TransactionView({
price={getAmountWithFee(effective, raw, "debit")}
effectiveRefund={effectiveRefund}
info={transaction.info}
- proposalId={transaction.proposalId}
/>
}
kind="neutral"
/>
+ <ShowFullContractTermPopup transactionId={transaction.transactionId} />
</TransactionTemplate>
);
}
@@ -695,7 +705,7 @@ export function TransactionView({
/>
{!shouldBeWired ? (
<Part
- title={i18n.str`Wire transfer deadline`}
+ title={i18n.str`Wire transfer deadline.`}
text={
<Time timestamp={wireTime} format="dd MMMM yyyy 'at' HH:mm" />
}
@@ -705,7 +715,7 @@ export function TransactionView({
<AlertView
alert={{
type: "warning",
- message: i18n.str`Wire transfer is not initiated`,
+ message: i18n.str`Wire transfer is not initiated.`,
description: i18n.str` `,
}}
/>
@@ -714,7 +724,7 @@ export function TransactionView({
<AlertView
alert={{
type: "success",
- message: i18n.str`Wire transfer completed`,
+ message: i18n.str`Wire transfer completed.`,
description: i18n.str` `,
}}
/>
@@ -732,7 +742,7 @@ export function TransactionView({
<AlertView
alert={{
type: "info",
- message: i18n.str`Wire transfer in progress`,
+ message: i18n.str`Wire transfer in progress.`,
description: i18n.str` `,
}}
/>
@@ -1026,10 +1036,110 @@ export function TransactionView({
);
}
- if (transaction.type === TransactionType.Recoup) {
- throw Error("recoup transaction not implemented");
+ if (transaction.type === TransactionType.DenomLoss) {
+ switch (transaction.lossEventType) {
+ case DenomLossEventType.DenomExpired: {
+ return (
+ <TransactionTemplate
+ transaction={transaction}
+ onDelete={onDelete}
+ onRetry={onRetry}
+ onAbort={onAbort}
+ onResume={onResume}
+ onSuspend={onSuspend}
+ onCancel={onCancel}
+ >
+ <Header
+ timestamp={transaction.timestamp}
+ type={i18n.str`Debit`}
+ total={effective}
+ kind="negative"
+ >
+ <i18n.Translate>Lost</i18n.Translate>
+ </Header>
+
+ <Part
+ title={i18n.str`Exchange`}
+ text={transaction.exchangeBaseUrl as TranslatedString}
+ kind="neutral"
+ />
+ <Part
+ title={i18n.str`Reason`}
+ text={i18n.str`Denomination expired.`}
+ />
+ </TransactionTemplate>
+ );
+ }
+ case DenomLossEventType.DenomVanished: {
+ return (
+ <TransactionTemplate
+ transaction={transaction}
+ onDelete={onDelete}
+ onRetry={onRetry}
+ onAbort={onAbort}
+ onResume={onResume}
+ onSuspend={onSuspend}
+ onCancel={onCancel}
+ >
+ <Header
+ timestamp={transaction.timestamp}
+ type={i18n.str`Debit`}
+ total={effective}
+ kind="negative"
+ >
+ <i18n.Translate>Lost</i18n.Translate>
+ </Header>
+
+ <Part
+ title={i18n.str`Exchange`}
+ text={transaction.exchangeBaseUrl as TranslatedString}
+ kind="neutral"
+ />
+ <Part
+ title={i18n.str`Reason`}
+ text={i18n.str`Denomination vanished.`}
+ />
+ </TransactionTemplate>
+ );
+ }
+ case DenomLossEventType.DenomUnoffered: {
+ return (
+ <TransactionTemplate
+ transaction={transaction}
+ onDelete={onDelete}
+ onRetry={onRetry}
+ onAbort={onAbort}
+ onResume={onResume}
+ onSuspend={onSuspend}
+ onCancel={onCancel}
+ >
+ <Header
+ timestamp={transaction.timestamp}
+ type={i18n.str`Debit`}
+ total={effective}
+ kind="negative"
+ >
+ <i18n.Translate>Lost</i18n.Translate>
+ </Header>
+
+ <Part
+ title={i18n.str`Exchange`}
+ text={transaction.exchangeBaseUrl as TranslatedString}
+ kind="neutral"
+ />
+ <Part
+ title={i18n.str`Reason`}
+ text={i18n.str`Denomination is unoffered.`}
+ />
+ </TransactionTemplate>
+ );
+ }
+ default: {
+ assertUnreachable(transaction.lossEventType);
+ }
+ }
}
- if (transaction.type === TransactionType.Reward) {
+ if (transaction.type === TransactionType.Recoup) {
throw Error("recoup transaction not implemented");
}
assertUnreachable(transaction);
@@ -1075,127 +1185,6 @@ export function MerchantDetails({
);
}
-// function DeliveryDetails({
-// date,
-// location,
-// }: {
-// date: TalerProtocolTimestamp | undefined;
-// location: Location | undefined;
-// }): VNode {
-// const { i18n } = useTranslationContext();
-// return (
-// <PurchaseDetailsTable>
-// {location && (
-// <Fragment>
-// {location.country && (
-// <tr>
-// <td>
-// <i18n.Translate>Country</i18n.Translate>
-// </td>
-// <td>{location.country}</td>
-// </tr>
-// )}
-// {location.address_lines && (
-// <tr>
-// <td>
-// <i18n.Translate>Address lines</i18n.Translate>
-// </td>
-// <td>{location.address_lines}</td>
-// </tr>
-// )}
-// {location.building_number && (
-// <tr>
-// <td>
-// <i18n.Translate>Building number</i18n.Translate>
-// </td>
-// <td>{location.building_number}</td>
-// </tr>
-// )}
-// {location.building_name && (
-// <tr>
-// <td>
-// <i18n.Translate>Building name</i18n.Translate>
-// </td>
-// <td>{location.building_name}</td>
-// </tr>
-// )}
-// {location.street && (
-// <tr>
-// <td>
-// <i18n.Translate>Street</i18n.Translate>
-// </td>
-// <td>{location.street}</td>
-// </tr>
-// )}
-// {location.post_code && (
-// <tr>
-// <td>
-// <i18n.Translate>Post code</i18n.Translate>
-// </td>
-// <td>{location.post_code}</td>
-// </tr>
-// )}
-// {location.town_location && (
-// <tr>
-// <td>
-// <i18n.Translate>Town location</i18n.Translate>
-// </td>
-// <td>{location.town_location}</td>
-// </tr>
-// )}
-// {location.town && (
-// <tr>
-// <td>
-// <i18n.Translate>Town</i18n.Translate>
-// </td>
-// <td>{location.town}</td>
-// </tr>
-// )}
-// {location.district && (
-// <tr>
-// <td>
-// <i18n.Translate>District</i18n.Translate>
-// </td>
-// <td>{location.district}</td>
-// </tr>
-// )}
-// {location.country_subdivision && (
-// <tr>
-// <td>
-// <i18n.Translate>Country subdivision</i18n.Translate>
-// </td>
-// <td>{location.country_subdivision}</td>
-// </tr>
-// )}
-// </Fragment>
-// )}
-
-// {!location || !date ? undefined : (
-// <tr>
-// <td colSpan={2}>
-// <hr />
-// </td>
-// </tr>
-// )}
-// {date && (
-// <Fragment>
-// <tr>
-// <td>
-// <i18n.Translate>Date</i18n.Translate>
-// </td>
-// <td>
-// <Time
-// timestamp={AbsoluteTime.fromProtocolTimestamp(date)}
-// format="dd MMMM yyyy, HH:mm"
-// />
-// </td>
-// </tr>
-// </Fragment>
-// )}
-// </PurchaseDetailsTable>
-// );
-// }
-
export function ExchangeDetails({ exchange }: { exchange: string }): VNode {
return (
<div>
@@ -1255,28 +1244,30 @@ export function InvoiceCreationDetails({
</tr>
{Amounts.isNonZero(amount.fee) && (
- <tr>
- <td>
- <i18n.Translate>Fees</i18n.Translate>
- </td>
- <td>
- <Amount value={amount.fee} maxFracSize={amount.maxFrac} />
- </td>
- </tr>
+ <Fragment>
+ <tr>
+ <td>
+ <i18n.Translate>Fees</i18n.Translate>
+ </td>
+ <td>
+ <Amount value={amount.fee} maxFracSize={amount.maxFrac} />
+ </td>
+ </tr>
+ <tr>
+ <td colSpan={2}>
+ <hr />
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <i18n.Translate>Total</i18n.Translate>
+ </td>
+ <td>
+ <Amount value={amount.total} maxFracSize={amount.maxFrac} />
+ </td>
+ </tr>
+ </Fragment>
)}
- <tr>
- <td colSpan={2}>
- <hr />
- </td>
- </tr>
- <tr>
- <td>
- <i18n.Translate>Total</i18n.Translate>
- </td>
- <td>
- <Amount value={amount.total} maxFracSize={amount.maxFrac} />
- </td>
- </tr>
</PurchaseDetailsTable>
);
}
@@ -1300,28 +1291,30 @@ export function InvoicePaymentDetails({
</tr>
{Amounts.isNonZero(amount.fee) && (
- <tr>
- <td>
- <i18n.Translate>Fees</i18n.Translate>
- </td>
- <td>
- <Amount value={amount.fee} maxFracSize={amount.maxFrac} />
- </td>
- </tr>
+ <Fragment>
+ <tr>
+ <td>
+ <i18n.Translate>Fees</i18n.Translate>
+ </td>
+ <td>
+ <Amount value={amount.fee} maxFracSize={amount.maxFrac} />
+ </td>
+ </tr>
+ <tr>
+ <td colSpan={2}>
+ <hr />
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <i18n.Translate>Total</i18n.Translate>
+ </td>
+ <td>
+ <Amount value={amount.value} maxFracSize={amount.maxFrac} />
+ </td>
+ </tr>
+ </Fragment>
)}
- <tr>
- <td colSpan={2}>
- <hr />
- </td>
- </tr>
- <tr>
- <td>
- <i18n.Translate>Total</i18n.Translate>
- </td>
- <td>
- <Amount value={amount.value} maxFracSize={amount.maxFrac} />
- </td>
- </tr>
</PurchaseDetailsTable>
);
}
@@ -1345,28 +1338,30 @@ export function TransferCreationDetails({
</tr>
{Amounts.isNonZero(amount.fee) && (
- <tr>
- <td>
- <i18n.Translate>Fees</i18n.Translate>
- </td>
- <td>
- <Amount value={amount.fee} maxFracSize={amount.maxFrac} />
- </td>
- </tr>
+ <Fragment>
+ <tr>
+ <td>
+ <i18n.Translate>Fees</i18n.Translate>
+ </td>
+ <td>
+ <Amount value={amount.fee} maxFracSize={amount.maxFrac} />
+ </td>
+ </tr>
+ <tr>
+ <td colSpan={2}>
+ <hr />
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <i18n.Translate>Transfer</i18n.Translate>
+ </td>
+ <td>
+ <Amount value={amount.total} maxFracSize={amount.maxFrac} />
+ </td>
+ </tr>
+ </Fragment>
)}
- <tr>
- <td colSpan={2}>
- <hr />
- </td>
- </tr>
- <tr>
- <td>
- <i18n.Translate>Transfer</i18n.Translate>
- </td>
- <td>
- <Amount value={amount.total} maxFracSize={amount.maxFrac} />
- </td>
- </tr>
</PurchaseDetailsTable>
);
}
@@ -1390,31 +1385,34 @@ export function TransferPickupDetails({
</tr>
{Amounts.isNonZero(amount.fee) && (
- <tr>
- <td>
- <i18n.Translate>Fees</i18n.Translate>
- </td>
- <td>
- <Amount value={amount.fee} maxFracSize={amount.maxFrac} />
- </td>
- </tr>
+ <Fragment>
+ <tr>
+ <td>
+ <i18n.Translate>Fees</i18n.Translate>
+ </td>
+ <td>
+ <Amount value={amount.fee} maxFracSize={amount.maxFrac} />
+ </td>
+ </tr>
+ <tr>
+ <td colSpan={2}>
+ <hr />
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <i18n.Translate>Total</i18n.Translate>
+ </td>
+ <td>
+ <Amount value={amount.total} maxFracSize={amount.maxFrac} />
+ </td>
+ </tr>
+ </Fragment>
)}
- <tr>
- <td colSpan={2}>
- <hr />
- </td>
- </tr>
- <tr>
- <td>
- <i18n.Translate>Total</i18n.Translate>
- </td>
- <td>
- <Amount value={amount.total} maxFracSize={amount.maxFrac} />
- </td>
- </tr>
</PurchaseDetailsTable>
);
}
+
export function WithdrawDetails({
conversion,
amount,
@@ -1424,12 +1422,6 @@ export function WithdrawDetails({
}): VNode {
const { i18n } = useTranslationContext();
- const maxFrac = [amount.fee, amount.fee]
- .map((a) => Amounts.maxFractionalDigits(a))
- .reduce((c, p) => Math.max(c, p), 0);
-
- const total = Amounts.add(amount.value, amount.fee).amount;
-
return (
<PurchaseDetailsTable>
{conversion ? (
@@ -1443,7 +1435,7 @@ export function WithdrawDetails({
</td>
</tr>
{conversion.fraction === amount.value.fraction &&
- conversion.value === amount.value.value ? undefined : (
+ conversion.value === amount.value.value ? undefined : (
<tr>
<td>
<i18n.Translate>Converted</i18n.Translate>
@@ -1465,28 +1457,30 @@ export function WithdrawDetails({
</tr>
)}
{Amounts.isNonZero(amount.fee) && (
- <tr>
- <td>
- <i18n.Translate>Fees</i18n.Translate>
- </td>
- <td>
- <Amount value={amount.fee} maxFracSize={amount.maxFrac} />
- </td>
- </tr>
+ <Fragment>
+ <tr>
+ <td>
+ <i18n.Translate>Fees</i18n.Translate>
+ </td>
+ <td>
+ <Amount value={amount.fee} maxFracSize={amount.maxFrac} />
+ </td>
+ </tr>
+ <tr>
+ <td colSpan={2}>
+ <hr />
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <i18n.Translate>Total</i18n.Translate>
+ </td>
+ <td>
+ <Amount value={amount.total} maxFracSize={amount.maxFrac} />
+ </td>
+ </tr>
+ </Fragment>
)}
- <tr>
- <td colSpan={2}>
- <hr />
- </td>
- </tr>
- <tr>
- <td>
- <i18n.Translate>Total</i18n.Translate>
- </td>
- <td>
- <Amount value={amount.total} maxFracSize={amount.maxFrac} />
- </td>
- </tr>
</PurchaseDetailsTable>
);
}
@@ -1494,27 +1488,16 @@ export function WithdrawDetails({
export function PurchaseDetails({
price,
effectiveRefund,
- info,
- proposalId,
+ info: _info,
}: {
price: AmountWithFee;
effectiveRefund?: AmountJson;
info: OrderShortInfo;
- proposalId: string;
}): VNode {
const { i18n } = useTranslationContext();
const total = Amounts.add(price.value, price.fee).amount;
- // const hasProducts = info.products && info.products.length > 0;
-
- // const hasShipping =
- // info.delivery_date !== undefined || info.delivery_location !== undefined;
-
- const showLargePic = (): void => {
- return;
- };
-
return (
<PurchaseDetailsTable>
<tr>
@@ -1526,69 +1509,72 @@ export function PurchaseDetails({
</td>
</tr>
{Amounts.isNonZero(price.fee) && (
- <tr>
- <td>
- <i18n.Translate>Fees</i18n.Translate>
- </td>
- <td>
- <Amount value={price.fee} />
- </td>
- </tr>
- )}
- {effectiveRefund && Amounts.isNonZero(effectiveRefund) ? (
- <Fragment>
- <tr>
- <td colSpan={2}>
- <hr />
- </td>
- </tr>
- <tr>
- <td>
- <i18n.Translate>Subtotal</i18n.Translate>
- </td>
- <td>
- <Amount value={price.total} />
- </td>
- </tr>
- <tr>
- <td>
- <i18n.Translate>Refunded</i18n.Translate>
- </td>
- <td>
- <Amount value={effectiveRefund} negative />
- </td>
- </tr>
- <tr>
- <td colSpan={2}>
- <hr />
- </td>
- </tr>
- <tr>
- <td>
- <i18n.Translate>Total</i18n.Translate>
- </td>
- <td>
- <Amount value={Amounts.sub(total, effectiveRefund).amount} />
- </td>
- </tr>
- </Fragment>
- ) : (
<Fragment>
<tr>
- <td colSpan={2}>
- <hr />
- </td>
- </tr>
- <tr>
<td>
- <i18n.Translate>Total</i18n.Translate>
+ <i18n.Translate>Fees</i18n.Translate>
</td>
<td>
- <Amount value={price.value} />
+ <Amount value={price.fee} />
</td>
</tr>
+ {effectiveRefund && Amounts.isNonZero(effectiveRefund) ? (
+ <Fragment>
+ <tr>
+ <td colSpan={2}>
+ <hr />
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <i18n.Translate>Subtotal</i18n.Translate>
+ </td>
+ <td>
+ <Amount value={price.total} />
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <i18n.Translate>Refunded</i18n.Translate>
+ </td>
+ <td>
+ <Amount value={effectiveRefund} negative />
+ </td>
+ </tr>
+ <tr>
+ <td colSpan={2}>
+ <hr />
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <i18n.Translate>Total</i18n.Translate>
+ </td>
+ <td>
+ <Amount value={Amounts.sub(total, effectiveRefund).amount} />
+ </td>
+ </tr>
+ </Fragment>
+ ) : (
+ <Fragment>
+ <tr>
+ <td colSpan={2}>
+ <hr />
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <i18n.Translate>Total</i18n.Translate>
+ </td>
+ <td>
+ <Amount value={price.value} />
+ </td>
+ </tr>
+ </Fragment>
+ )}
</Fragment>
)}
+
{/* {hasProducts && (
<tr>
<td colSpan={2}>
@@ -1634,11 +1620,6 @@ export function PurchaseDetails({
</td>
</tr>
)} */}
- <tr>
- <td>
- <ShowFullContractTermPopup proposalId={proposalId} />
- </td>
- </tr>
</PurchaseDetailsTable>
);
}
@@ -1658,28 +1639,30 @@ function RefundDetails({ amount }: { amount: AmountWithFee }): VNode {
</tr>
{Amounts.isNonZero(amount.fee) && (
- <tr>
- <td>
- <i18n.Translate>Fees</i18n.Translate>
- </td>
- <td>
- <Amount value={amount.fee} maxFracSize={amount.maxFrac} />
- </td>
- </tr>
+ <Fragment>
+ <tr>
+ <td>
+ <i18n.Translate>Fees</i18n.Translate>
+ </td>
+ <td>
+ <Amount value={amount.fee} maxFracSize={amount.maxFrac} />
+ </td>
+ </tr>
+ <tr>
+ <td colSpan={2}>
+ <hr />
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <i18n.Translate>Total</i18n.Translate>
+ </td>
+ <td>
+ <Amount value={amount.total} maxFracSize={amount.maxFrac} />
+ </td>
+ </tr>
+ </Fragment>
)}
- <tr>
- <td colSpan={2}>
- <hr />
- </td>
- </tr>
- <tr>
- <td>
- <i18n.Translate>Total</i18n.Translate>
- </td>
- <td>
- <Amount value={amount.total} maxFracSize={amount.maxFrac} />
- </td>
- </tr>
</PurchaseDetailsTable>
);
}
@@ -1740,7 +1723,7 @@ function TrackingDepositDetails({
</tr>
{wireTransfers.map((wire) => (
- <tr>
+ <tr key={wire.id}>
<td>{wire.id}</td>
<td>
<Amount value={wire.amount} />
@@ -1750,6 +1733,7 @@ function TrackingDepositDetails({
</PurchaseDetailsTable>
);
}
+
function DepositDetails({ amount }: { amount: AmountWithFee }): VNode {
const { i18n } = useTranslationContext();
@@ -1765,28 +1749,30 @@ function DepositDetails({ amount }: { amount: AmountWithFee }): VNode {
</tr>
{Amounts.isNonZero(amount.fee) && (
- <tr>
- <td>
- <i18n.Translate>Fees</i18n.Translate>
- </td>
- <td>
- <Amount value={amount.fee} maxFracSize={amount.maxFrac} />
- </td>
- </tr>
+ <Fragment>
+ <tr>
+ <td>
+ <i18n.Translate>Fees</i18n.Translate>
+ </td>
+ <td>
+ <Amount value={amount.fee} maxFracSize={amount.maxFrac} />
+ </td>
+ </tr>
+ <tr>
+ <td colSpan={2}>
+ <hr />
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <i18n.Translate>Total</i18n.Translate>
+ </td>
+ <td>
+ <Amount value={amount.total} maxFracSize={amount.maxFrac} />
+ </td>
+ </tr>
+ </Fragment>
)}
- <tr>
- <td colSpan={2}>
- <hr />
- </td>
- </tr>
- <tr>
- <td>
- <i18n.Translate>Total</i18n.Translate>
- </td>
- <td>
- <Amount value={amount.total} maxFracSize={amount.maxFrac} />
- </td>
- </tr>
</PurchaseDetailsTable>
);
}
@@ -1976,8 +1962,9 @@ function ShowWithdrawalDetailForBankIntegrated({
if (
transaction.txState.major !== TransactionMajorState.Pending ||
transaction.withdrawalDetails.type === WithdrawalType.ManualTransfer
- )
+ ) {
return <Fragment />;
+ }
const raw = Amounts.parseOrThrow(transaction.amountRaw);
return (
<Fragment>
@@ -1989,7 +1976,7 @@ function ShowWithdrawalDetailForBankIntegrated({
setShowDetails(!showDetails);
}}
>
- show details
+ Show details.
</a>
</EnabledBySettings>
@@ -2003,7 +1990,7 @@ function ShowWithdrawalDetailForBankIntegrated({
/>
)}
{!transaction.withdrawalDetails.confirmed &&
- transaction.withdrawalDetails.bankConfirmationUrl ? (
+ transaction.withdrawalDetails.bankConfirmationUrl ? (
<InfoBox>
<div style={{ display: "block" }}>
<i18n.Translate>
@@ -2026,7 +2013,7 @@ function ShowWithdrawalDetailForBankIntegrated({
<InfoBox>
<i18n.Translate>
Bank has confirmed the wire transfer. Waiting for the exchange to
- send the coins
+ send the coins.
</i18n.Translate>
</InfoBox>
)}