added new continue after wire transfer confirmed
This commit is contained in:
parent
6f4548c892
commit
acf110dd78
@ -21,9 +21,11 @@ export function Loading(): VNode {
|
|||||||
<div
|
<div
|
||||||
class="columns is-centered is-vcentered"
|
class="columns is-centered is-vcentered"
|
||||||
style={{
|
style={{
|
||||||
height: "calc(100% - 3rem)",
|
|
||||||
position: "absolute",
|
|
||||||
width: "100%",
|
width: "100%",
|
||||||
|
height: "200px",
|
||||||
|
display: "flex",
|
||||||
|
margin: "auto",
|
||||||
|
justifyContent: "center",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Spinner />
|
<Spinner />
|
||||||
@ -33,7 +35,7 @@ export function Loading(): VNode {
|
|||||||
|
|
||||||
export function Spinner(): VNode {
|
export function Spinner(): VNode {
|
||||||
return (
|
return (
|
||||||
<div class="lds-ring">
|
<div class="lds-ring" style={{margin:"auto"}}>
|
||||||
<div />
|
<div />
|
||||||
<div />
|
<div />
|
||||||
<div />
|
<div />
|
||||||
|
@ -84,11 +84,11 @@ export function HomePage({
|
|||||||
export function WithdrawalOperationPage({
|
export function WithdrawalOperationPage({
|
||||||
operationId,
|
operationId,
|
||||||
onLoadNotOk,
|
onLoadNotOk,
|
||||||
onAbort,
|
onContinue,
|
||||||
}: {
|
}: {
|
||||||
operationId: string;
|
operationId: string;
|
||||||
onLoadNotOk: () => void;
|
onLoadNotOk: () => void;
|
||||||
onAbort: () => void;
|
onContinue: () => void;
|
||||||
}): VNode {
|
}): VNode {
|
||||||
//FIXME: libeufin sandbox should return show to create the integration api endpoint
|
//FIXME: libeufin sandbox should return show to create the integration api endpoint
|
||||||
//or return withdrawal uri from response
|
//or return withdrawal uri from response
|
||||||
@ -99,12 +99,6 @@ export function WithdrawalOperationPage({
|
|||||||
const parsedUri = parseWithdrawUri(uri);
|
const parsedUri = parseWithdrawUri(uri);
|
||||||
const { i18n } = useTranslationContext();
|
const { i18n } = useTranslationContext();
|
||||||
|
|
||||||
const [settings, updateSettings] = useSettings();
|
|
||||||
function clearCurrentWithdrawal(): void {
|
|
||||||
updateSettings("currentWithdrawalOperationId", undefined);
|
|
||||||
onAbort();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!parsedUri) {
|
if (!parsedUri) {
|
||||||
notifyError({
|
notifyError({
|
||||||
title: i18n.str`The Withdrawal URI is not valid: "${uri}"`,
|
title: i18n.str`The Withdrawal URI is not valid: "${uri}"`,
|
||||||
@ -115,10 +109,7 @@ export function WithdrawalOperationPage({
|
|||||||
return (
|
return (
|
||||||
<WithdrawalQRCode
|
<WithdrawalQRCode
|
||||||
withdrawUri={parsedUri}
|
withdrawUri={parsedUri}
|
||||||
onConfirmed={() => {
|
onContinue={onContinue}
|
||||||
notifyInfo(i18n.str`Withdrawal confirmed!`);
|
|
||||||
}}
|
|
||||||
onAborted={clearCurrentWithdrawal}
|
|
||||||
onLoadNotOk={onLoadNotOk}
|
onLoadNotOk={onLoadNotOk}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -40,7 +40,7 @@ export function Routing(): VNode {
|
|||||||
component={({ wopid }: { wopid: string }) => (
|
component={({ wopid }: { wopid: string }) => (
|
||||||
<WithdrawalOperationPage
|
<WithdrawalOperationPage
|
||||||
operationId={wopid}
|
operationId={wopid}
|
||||||
onAbort={() => {
|
onContinue={() => {
|
||||||
route("/account");
|
route("/account");
|
||||||
}}
|
}}
|
||||||
onLoadNotOk={() => {
|
onLoadNotOk={() => {
|
||||||
|
@ -33,7 +33,6 @@ import { ShowInputErrorLabel } from "./ShowInputErrorLabel.js";
|
|||||||
const logger = new Logger("WithdrawalConfirmationQuestion");
|
const logger = new Logger("WithdrawalConfirmationQuestion");
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
onConfirmed: () => void;
|
|
||||||
onAborted: () => void;
|
onAborted: () => void;
|
||||||
withdrawUri: WithdrawUriResult;
|
withdrawUri: WithdrawUriResult;
|
||||||
}
|
}
|
||||||
@ -42,7 +41,6 @@ interface Props {
|
|||||||
* Not providing a back button, only abort.
|
* Not providing a back button, only abort.
|
||||||
*/
|
*/
|
||||||
export function WithdrawalConfirmationQuestion({
|
export function WithdrawalConfirmationQuestion({
|
||||||
onConfirmed,
|
|
||||||
onAborted,
|
onAborted,
|
||||||
withdrawUri,
|
withdrawUri,
|
||||||
}: Props): VNode {
|
}: Props): VNode {
|
||||||
@ -119,7 +117,6 @@ export function WithdrawalConfirmationQuestion({
|
|||||||
await confirmWithdrawal(
|
await confirmWithdrawal(
|
||||||
withdrawUri.withdrawalOperationId,
|
withdrawUri.withdrawalOperationId,
|
||||||
);
|
);
|
||||||
onConfirmed();
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof RequestError) {
|
if (error instanceof RequestError) {
|
||||||
notifyError(
|
notifyError(
|
||||||
|
@ -24,6 +24,7 @@ import { Fragment, VNode, h } from "preact";
|
|||||||
import { Loading } from "../components/Loading.js";
|
import { Loading } from "../components/Loading.js";
|
||||||
import { useWithdrawalDetails } from "../hooks/access.js";
|
import { useWithdrawalDetails } from "../hooks/access.js";
|
||||||
import { notifyInfo } from "../hooks/notification.js";
|
import { notifyInfo } from "../hooks/notification.js";
|
||||||
|
import { useSettings } from "../hooks/settings.js";
|
||||||
import { handleNotOkResult } from "./HomePage.js";
|
import { handleNotOkResult } from "./HomePage.js";
|
||||||
import { QrCodeSection } from "./QrCodeSection.js";
|
import { QrCodeSection } from "./QrCodeSection.js";
|
||||||
import { WithdrawalConfirmationQuestion } from "./WithdrawalConfirmationQuestion.js";
|
import { WithdrawalConfirmationQuestion } from "./WithdrawalConfirmationQuestion.js";
|
||||||
@ -32,8 +33,7 @@ const logger = new Logger("WithdrawalQRCode");
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
withdrawUri: WithdrawUriResult;
|
withdrawUri: WithdrawUriResult;
|
||||||
onAborted: () => void;
|
onContinue: () => void;
|
||||||
onConfirmed: () => void;
|
|
||||||
onLoadNotOk: () => void;
|
onLoadNotOk: () => void;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -43,10 +43,14 @@ interface Props {
|
|||||||
*/
|
*/
|
||||||
export function WithdrawalQRCode({
|
export function WithdrawalQRCode({
|
||||||
withdrawUri,
|
withdrawUri,
|
||||||
onConfirmed,
|
onContinue,
|
||||||
onAborted,
|
|
||||||
onLoadNotOk,
|
onLoadNotOk,
|
||||||
}: Props): VNode {
|
}: Props): VNode {
|
||||||
|
const [settings, updateSettings] = useSettings();
|
||||||
|
function clearCurrentWithdrawal(): void {
|
||||||
|
updateSettings("currentWithdrawalOperationId", undefined);
|
||||||
|
onContinue();
|
||||||
|
}
|
||||||
const { i18n } = useTranslationContext();
|
const { i18n } = useTranslationContext();
|
||||||
const result = useWithdrawalDetails(withdrawUri.withdrawalOperationId);
|
const result = useWithdrawalDetails(withdrawUri.withdrawalOperationId);
|
||||||
if (!result.ok) {
|
if (!result.ok) {
|
||||||
@ -64,13 +68,64 @@ export function WithdrawalQRCode({
|
|||||||
}
|
}
|
||||||
const { data } = result;
|
const { data } = result;
|
||||||
|
|
||||||
logger.trace("withdrawal status", data);
|
if (data.aborted) {
|
||||||
if (data.aborted || data.confirmation_done) {
|
return <section id="main" class="content">
|
||||||
// signal that this withdrawal is aborted
|
<h1 class="nav">{i18n.str`Operation aborted`}</h1>
|
||||||
// will redirect to account info
|
<section>
|
||||||
notifyInfo(i18n.str`Operation completed`);
|
<p>
|
||||||
onAborted();
|
<i18n.Translate>
|
||||||
return <Loading />;
|
The wire transfer to the GNU Taler Exchange bank's account was aborted, your balance
|
||||||
|
was not affected.
|
||||||
|
</i18n.Translate>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<i18n.Translate>
|
||||||
|
You can close this page now or continue to the account page.
|
||||||
|
</i18n.Translate>
|
||||||
|
</p>
|
||||||
|
<a class="pure-button pure-button-primary"
|
||||||
|
style={{float:"right"}}
|
||||||
|
onClick={async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
clearCurrentWithdrawal()
|
||||||
|
onContinue()
|
||||||
|
}}>
|
||||||
|
{i18n.str`Continue`}
|
||||||
|
</a>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.confirmation_done) {
|
||||||
|
return <section id="main" class="content">
|
||||||
|
<h1 class="nav">{i18n.str`Operation completed`}</h1>
|
||||||
|
|
||||||
|
<section id="assets" style={{maxWidth: 400, marginLeft: "auto", marginRight:"auto"}}>
|
||||||
|
<p>
|
||||||
|
<i18n.Translate>
|
||||||
|
The wire transfer to the GNU Taler Exchange bank's account is completed, now the
|
||||||
|
exchange will send the requested amount into your GNU Taler wallet.
|
||||||
|
</i18n.Translate>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<i18n.Translate>
|
||||||
|
You can close this page now or continue to the account page.
|
||||||
|
</i18n.Translate>
|
||||||
|
</p>
|
||||||
|
<div style={{textAlign:"center"}}>
|
||||||
|
|
||||||
|
<a class="pure-button pure-button-primary"
|
||||||
|
onClick={async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
clearCurrentWithdrawal()
|
||||||
|
onContinue()
|
||||||
|
}}>
|
||||||
|
{i18n.str`Continue`}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!data.selection_done) {
|
if (!data.selection_done) {
|
||||||
@ -79,24 +134,20 @@ export function WithdrawalQRCode({
|
|||||||
withdrawUri={withdrawUri}
|
withdrawUri={withdrawUri}
|
||||||
onAborted={() => {
|
onAborted={() => {
|
||||||
notifyInfo(i18n.str`Operation canceled`);
|
notifyInfo(i18n.str`Operation canceled`);
|
||||||
onAborted();
|
clearCurrentWithdrawal()
|
||||||
|
onContinue()
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wallet POSTed the withdrawal details! Ask the
|
|
||||||
// user to authorize the operation (here CAPTCHA).
|
|
||||||
return (
|
return (
|
||||||
<WithdrawalConfirmationQuestion
|
<WithdrawalConfirmationQuestion
|
||||||
withdrawUri={withdrawUri}
|
withdrawUri={withdrawUri}
|
||||||
onConfirmed={() => {
|
|
||||||
notifyInfo(i18n.str`Operation confirmed`);
|
|
||||||
onConfirmed();
|
|
||||||
}}
|
|
||||||
onAborted={() => {
|
onAborted={() => {
|
||||||
notifyInfo(i18n.str`Operation canceled`);
|
notifyInfo(i18n.str`Operation canceled`);
|
||||||
onAborted();
|
clearCurrentWithdrawal()
|
||||||
|
onContinue()
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -315,3 +315,39 @@ h1.nav {
|
|||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.lds-ring {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
width: 80px;
|
||||||
|
height: 80px;
|
||||||
|
}
|
||||||
|
.lds-ring div {
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
width: 64px;
|
||||||
|
height: 64px;
|
||||||
|
margin: 8px;
|
||||||
|
border: 8px solid black;
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: lds-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
|
||||||
|
border-color: black transparent transparent transparent;
|
||||||
|
}
|
||||||
|
.lds-ring div:nth-child(1) {
|
||||||
|
animation-delay: -0.45s;
|
||||||
|
}
|
||||||
|
.lds-ring div:nth-child(2) {
|
||||||
|
animation-delay: -0.3s;
|
||||||
|
}
|
||||||
|
.lds-ring div:nth-child(3) {
|
||||||
|
animation-delay: -0.15s;
|
||||||
|
}
|
||||||
|
@keyframes lds-ring {
|
||||||
|
0% {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -134,7 +134,7 @@ export function buildRequestErrorMessage(
|
|||||||
specialCases.onClientError && specialCases.onClientError(cause.status);
|
specialCases.onClientError && specialCases.onClientError(cause.status);
|
||||||
result = {
|
result = {
|
||||||
title: title ? title : i18n.str`The server didn't accept the request`,
|
title: title ? title : i18n.str`The server didn't accept the request`,
|
||||||
description: cause.payload.error.description,
|
description: cause?.payload?.error?.description,
|
||||||
debug: JSON.stringify(cause),
|
debug: JSON.stringify(cause),
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
@ -146,7 +146,7 @@ export function buildRequestErrorMessage(
|
|||||||
title: title
|
title: title
|
||||||
? title
|
? title
|
||||||
: i18n.str`The server had problems processing the request`,
|
: i18n.str`The server had problems processing the request`,
|
||||||
description: cause.payload.error.description,
|
description: cause?.payload?.error?.description,
|
||||||
debug: JSON.stringify(cause),
|
debug: JSON.stringify(cause),
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
@ -154,7 +154,7 @@ export function buildRequestErrorMessage(
|
|||||||
case ErrorType.UNREADABLE: {
|
case ErrorType.UNREADABLE: {
|
||||||
result = {
|
result = {
|
||||||
title: i18n.str`Unexpected error`,
|
title: i18n.str`Unexpected error`,
|
||||||
description: `Response from ${cause.info?.url} is unreadable, status: ${cause.status}`,
|
description: `Response from ${cause?.info?.url} is unreadable, status: ${cause?.status}`,
|
||||||
debug: JSON.stringify(cause),
|
debug: JSON.stringify(cause),
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user