show bank details

This commit is contained in:
Sebastian 2023-06-21 11:28:27 -03:00
parent 8b85fe1775
commit 81bf1cc9c1
No known key found for this signature in database
GPG Key ID: 173909D1A5F66069
3 changed files with 171 additions and 156 deletions

View File

@ -17,31 +17,53 @@
import { import {
AmountJson, AmountJson,
Amounts, Amounts,
parsePaytoUri,
PaytoUri, PaytoUri,
segwitMinAmount, segwitMinAmount,
stringifyPaytoUri,
TranslatedString, TranslatedString,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { Fragment, h, VNode } from "preact"; import { Fragment, h, VNode } from "preact";
import { useEffect, useRef, useState } from "preact/hooks"; import { useEffect, useRef, useState } from "preact/hooks";
import { useTranslationContext } from "@gnu-taler/web-util/browser"; import {
useAsyncAsHook,
useTranslationContext,
} from "@gnu-taler/web-util/browser";
import { CopiedIcon, CopyIcon } from "../svg/index.js"; import { CopiedIcon, CopyIcon } from "../svg/index.js";
import { Amount } from "./Amount.js"; import { Amount } from "./Amount.js";
import { ButtonBox, TooltipLeft } from "./styled/index.js"; import { ButtonBox, TooltipLeft, WarningBox } from "./styled/index.js";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { useBackendContext } from "../context/backend.js";
export interface BankDetailsProps { export interface BankDetailsProps {
payto: PaytoUri | undefined;
exchangeBaseUrl: string; exchangeBaseUrl: string;
subject: string; subject: string;
amount: AmountJson; amount: AmountJson;
} }
export function BankDetailsByPaytoType({ export function BankDetailsByPaytoType({
payto,
subject, subject,
exchangeBaseUrl, exchangeBaseUrl,
amount, amount,
}: BankDetailsProps): VNode { }: BankDetailsProps): VNode {
const { i18n } = useTranslationContext(); const { i18n } = useTranslationContext();
const api = useBackendContext();
const hook = useAsyncAsHook(async () => {
const details = await api.wallet.call(
WalletApiOperation.GetExchangeDetailedInfo,
{
exchangeBaseUrl,
},
);
return { details };
});
if (!hook || hook.hasError) return <Fragment />;
const firstPayto = hook.response.details.exchange.paytoUris[0];
const payto = parsePaytoUri(firstPayto);
if (!payto) return <Fragment />; if (!payto) return <Fragment />;
if (payto.isKnown && payto.targetType === "bitcoin") { if (payto.isKnown && payto.targetType === "bitcoin") {
@ -124,29 +146,65 @@ export function BankDetailsByPaytoType({
const receiver = payto.params["receiver"] || undefined; const receiver = payto.params["receiver"] || undefined;
return ( return (
<div <section>
style={{ <div
textAlign: "left", style={{
border: "solid 1px black", textAlign: "left",
padding: 8, border: "solid 1px black",
borderRadius: 4, padding: 8,
}} borderRadius: 4,
> }}
<p style={{ marginTop: 0 }}> >
<i18n.Translate>Bank transfer details</i18n.Translate> <p style={{ marginTop: 0 }}>
</p> <i18n.Translate>Bank transfer details</i18n.Translate>
</p>
<table>
{accountPart}
<Row
name={i18n.str`Amount`}
value={<Amount value={amount} hideCurrency />}
/>
<Row name={i18n.str`Subject`} value={subject} literal />
{receiver ? (
<Row name={i18n.str`Receiver name`} value={receiver} />
) : undefined}
</table>
</div>
<table> <table>
{accountPart} <tbody>
<Row <tr>
name={i18n.str`Amount`} <td>
value={<Amount value={amount} hideCurrency />} <pre>
/> <b>
<Row name={i18n.str`Subject`} value={subject} literal /> <a
{receiver ? ( target="_bank"
<Row name={i18n.str`Receiver name`} value={receiver} /> rel="noreferrer"
) : undefined} title="RFC 8905 for designating targets for payments"
href="https://tools.ietf.org/html/rfc8905"
>
Payto URI
</a>
</b>
</pre>
</td>
<td width="100%" style={{ wordBreak: "break-all" }}>
{stringifyPaytoUri(payto)}
</td>
<td>
<CopyButton getContent={() => stringifyPaytoUri(payto)} />
</td>
</tr>
</tbody>
</table> </table>
</div> <p>
<WarningBox>
<i18n.Translate>
Make sure to use the correct subject, otherwise the money will not
arrive in this wallet.
</i18n.Translate>
</WarningBox>
</p>
</section>
); );
} }

View File

@ -50,48 +50,11 @@ export function ReserveCreated({
function TransferDetails(): VNode { function TransferDetails(): VNode {
if (!paytoURI) return <Fragment />; if (!paytoURI) return <Fragment />;
return ( return (
<section> <BankDetailsByPaytoType
<BankDetailsByPaytoType amount={amount}
amount={amount} exchangeBaseUrl={exchangeBaseUrl}
exchangeBaseUrl={exchangeBaseUrl} subject={reservePub}
payto={paytoURI} />
subject={reservePub}
/>
<table>
<tbody>
<tr>
<td>
<pre>
<b>
<a
target="_bank"
rel="noreferrer"
title="RFC 8905 for designating targets for payments"
href="https://tools.ietf.org/html/rfc8905"
>
Payto URI
</a>
</b>
</pre>
</td>
<td width="100%" style={{ wordBreak: "break-all" }}>
{stringifyPaytoUri(paytoURI)}
</td>
<td>
<CopyButton getContent={() => stringifyPaytoUri(paytoURI)} />
</td>
</tr>
</tbody>
</table>
<p>
<WarningBox>
<i18n.Translate>
Make sure to use the correct subject, otherwise the money will not
arrive in this wallet.
</i18n.Translate>
</WarningBox>
</p>
</section>
); );
} }

View File

@ -32,9 +32,11 @@ import {
TransactionAction, TransactionAction,
TransactionDeposit, TransactionDeposit,
TransactionIdStr, TransactionIdStr,
TransactionInternalWithdrawal,
TransactionMajorState, TransactionMajorState,
TransactionMinorState, TransactionMinorState,
TransactionType, TransactionType,
TransactionWithdrawal,
TranslatedString, TranslatedString,
WithdrawalType, WithdrawalType,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
@ -459,96 +461,14 @@ export function TransactionView({
TransactionMajorState.Pending ? undefined : transaction TransactionMajorState.Pending ? undefined : transaction
.withdrawalDetails.type === WithdrawalType.ManualTransfer ? ( .withdrawalDetails.type === WithdrawalType.ManualTransfer ? (
//manual withdrawal //manual withdrawal
<Fragment> <BankDetailsByPaytoType
<BankDetailsByPaytoType amount={raw}
amount={raw} exchangeBaseUrl={transaction.exchangeBaseUrl}
exchangeBaseUrl={transaction.exchangeBaseUrl} subject={transaction.withdrawalDetails.reservePub}
payto={parsePaytoUri( />
transaction.withdrawalDetails.exchangePaytoUris[0],
)}
subject={transaction.withdrawalDetails.reservePub}
/>
<table>
<tbody>
<tr>
<td>
<pre>
<b>
<a
target="_bank"
rel="noreferrer"
title="RFC 8905 for designating targets for payments"
href="https://tools.ietf.org/html/rfc8905"
>
Payto URI
</a>
</b>
</pre>
</td>
<td width="100%" style={{ wordBreak: "break-all" }}>
{transaction.withdrawalDetails.exchangePaytoUris[0]}
</td>
<td>
<CopyButton
getContent={() =>
transaction.withdrawalDetails.type ===
WithdrawalType.ManualTransfer
? transaction.withdrawalDetails.exchangePaytoUris[0]
: ""
}
/>
</td>
</tr>
</tbody>
</table>
<WarningBox>
<i18n.Translate>
Make sure to use the correct subject, otherwise the money will
not arrive in this wallet.
</i18n.Translate>
</WarningBox>
</Fragment>
) : ( ) : (
//integrated bank withdrawal //integrated bank withdrawal
<Fragment> <ShowWithdrawalDetailForBankIntegrated transaction={transaction} />
{!transaction.withdrawalDetails.confirmed &&
transaction.withdrawalDetails.bankConfirmationUrl ? (
<InfoBox>
<div style={{ display: "block" }}>
<i18n.Translate>
Wire transfer need a confirmation. Go to the{" "}
<a
href={transaction.withdrawalDetails.bankConfirmationUrl}
target="_blank"
rel="noreferrer"
style={{ display: "inline" }}
>
<i18n.Translate>bank site</i18n.Translate>
</a>{" "}
and check wire transfer operation to exchange account is
complete.
</i18n.Translate>
</div>
</InfoBox>
) : undefined}
{transaction.withdrawalDetails.confirmed &&
!transaction.withdrawalDetails.reserveIsReady && (
<InfoBox>
<i18n.Translate>
Bank has confirmed the wire transfer. Waiting for the
exchange to send the coins
</i18n.Translate>
</InfoBox>
)}
{transaction.withdrawalDetails.confirmed &&
transaction.withdrawalDetails.reserveIsReady && (
<InfoBox>
<i18n.Translate>
Exchange is ready to send the coins, withdrawal in progress.
</i18n.Translate>
</InfoBox>
)}
</Fragment>
)} )}
<Part <Part
title={i18n.str`Details`} title={i18n.str`Details`}
@ -1404,7 +1324,7 @@ export function WithdrawDetails({ amount }: { amount: AmountWithFee }): VNode {
<PurchaseDetailsTable> <PurchaseDetailsTable>
<tr> <tr>
<td> <td>
<i18n.Translate>Withdraw</i18n.Translate> <i18n.Translate>Wire transfer</i18n.Translate>
</td> </td>
<td> <td>
<Amount value={amount.value} maxFracSize={amount.maxFrac} /> <Amount value={amount.value} maxFracSize={amount.maxFrac} />
@ -1952,3 +1872,77 @@ function getShowButtonStates(transaction: Transaction) {
}); });
return { abort, fail, resume, retry, remove, suspend }; return { abort, fail, resume, retry, remove, suspend };
} }
function ShowWithdrawalDetailForBankIntegrated({
transaction,
}: {
transaction: TransactionWithdrawal | TransactionInternalWithdrawal;
}): VNode {
const { i18n } = useTranslationContext();
const [showDetails, setShowDetails] = useState(false);
if (
transaction.txState.major !== TransactionMajorState.Pending ||
transaction.withdrawalDetails.type === WithdrawalType.ManualTransfer
)
return <Fragment />;
const raw = Amounts.parseOrThrow(transaction.amountRaw);
return (
<Fragment>
<EnabledBySettings name="advanceMode">
<a
href="#"
onClick={(e) => {
e.preventDefault();
setShowDetails(!showDetails);
}}
>
show details
</a>
</EnabledBySettings>
{showDetails && (
<BankDetailsByPaytoType
amount={raw}
exchangeBaseUrl={transaction.exchangeBaseUrl}
subject={transaction.withdrawalDetails.reservePub}
/>
)}
{!transaction.withdrawalDetails.confirmed &&
transaction.withdrawalDetails.bankConfirmationUrl ? (
<InfoBox>
<div style={{ display: "block" }}>
<i18n.Translate>
Wire transfer need a confirmation. Go to the{" "}
<a
href={transaction.withdrawalDetails.bankConfirmationUrl}
target="_blank"
rel="noreferrer"
style={{ display: "inline" }}
>
<i18n.Translate>bank site</i18n.Translate>
</a>{" "}
and check wire transfer operation to exchange account is complete.
</i18n.Translate>
</div>
</InfoBox>
) : undefined}
{transaction.withdrawalDetails.confirmed &&
!transaction.withdrawalDetails.reserveIsReady && (
<InfoBox>
<i18n.Translate>
Bank has confirmed the wire transfer. Waiting for the exchange to
send the coins
</i18n.Translate>
</InfoBox>
)}
{transaction.withdrawalDetails.confirmed &&
transaction.withdrawalDetails.reserveIsReady && (
<InfoBox>
<i18n.Translate>
Exchange is ready to send the coins, withdrawal in progress.
</i18n.Translate>
</InfoBox>
)}
</Fragment>
);
}