From 2b895bea57ae486004d8173354ccd5af52cf042e Mon Sep 17 00:00:00 2001 From: Sebastian Date: Fri, 14 Jun 2024 12:33:17 -0300 Subject: new payto form --- .../paths/instance/accounts/create/CreatePage.tsx | 183 ++++++++++++++------- .../src/paths/instance/accounts/create/index.tsx | 22 ++- 2 files changed, 142 insertions(+), 63 deletions(-) (limited to 'packages/merchant-backoffice-ui/src/paths/instance/accounts/create') diff --git a/packages/merchant-backoffice-ui/src/paths/instance/accounts/create/CreatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/accounts/create/CreatePage.tsx index 2f19d0c91..bec32bac3 100644 --- a/packages/merchant-backoffice-ui/src/paths/instance/accounts/create/CreatePage.tsx +++ b/packages/merchant-backoffice-ui/src/paths/instance/accounts/create/CreatePage.tsx @@ -21,10 +21,12 @@ import { HttpStatusCode, + PaytoUri, TalerError, TalerMerchantApi, TranslatedString, assertUnreachable, + parsePaytoUri, } from "@gnu-taler/taler-util"; import { useTranslationContext } from "@gnu-taler/web-util/browser"; import { Fragment, h, VNode } from "preact"; @@ -37,12 +39,16 @@ import { import { Input } from "../../../../components/form/Input.js"; import { InputPaytoForm } from "../../../../components/form/InputPaytoForm.js"; import { InputSelector } from "../../../../components/form/InputSelector.js"; -import { ImportingAccountModal } from "../../../../components/modal/index.js"; +import { + CompareAccountsModal, + ImportingAccountModal, +} from "../../../../components/modal/index.js"; import { undefinedIfEmpty } from "../../../../utils/table.js"; import { safeConvertURL } from "../update/UpdatePage.js"; import { testRevenueAPI } from "./index.js"; +import { InputToggle } from "../../../../components/form/InputToggle.js"; -type Entity = TalerMerchantApi.AccountAddDetails; +type Entity = TalerMerchantApi.AccountAddDetails & { verified?: boolean }; interface Props { onCreate: (d: TalerMerchantApi.AccountAddDetails) => Promise; @@ -55,8 +61,12 @@ export function CreatePage({ onCreate, onBack }: Props): VNode { const { i18n } = useTranslationContext(); const [importing, setImporting] = useState(false); + const [revenuePayto, setRevenuePayto] = useState( + undefined, + ); const [state, setState] = useState>({}); const facadeURL = safeConvertURL(state.credit_facade_url); + const [testError, setTestError] = useState( undefined, ); @@ -133,70 +143,60 @@ export function CreatePage({ onCreate, onBack }: Props): VNode { ); if (resp instanceof TalerError) { setTestError(i18n.str`The request to check the revenue API failed.`); + setState({ + ...state, + verified: undefined, + }); return; - } - if (resp.type === "fail") { + } else if (resp.type === "fail") { switch (resp.case) { case HttpStatusCode.BadRequest: { setTestError(i18n.str`Server replied with "bad request".`); + setState({ + ...state, + verified: undefined, + }); return; } case HttpStatusCode.Unauthorized: { - setTestError(i18n.str`Unauthorized, try with another credentials.`); - + setTestError(i18n.str`Unauthorized, check credentials.`); + setState({ + ...state, + verified: undefined, + }); return; } case HttpStatusCode.NotFound: { setTestError( i18n.str`The endpoint doesn't seems to be a Taler Revenue API.`, ); + setState({ + ...state, + verified: undefined, + }); return; } default: { assertUnreachable(resp); } } + } else { + const found = resp.body; + const match = state.payto_uri === found; + setState({ + ...state, + verified: match, + }); + if (!match) { + setRevenuePayto(parsePaytoUri(resp.body)); + } + setTestError(undefined); } } } return ( -
- {importing && ( - { - setImporting(false); - }} - onConfirm={(ac) => { - const u = new URL(ac.infoURL); - const user = u.username; - const pwd = u.password; - u.password = ""; - u.username = ""; - const credit_facade_url = u.href; - setState({ - payto_uri: ac.accountURI, - credit_facade_credentials: - user || pwd - ? { - type: "basic", - password: pwd, - username: user, - } - : undefined, - credit_facade_url, - }); - // if (u.username && ac.accesToken) { - // state.credit_facade_credentials = { - // type: "bearer", - // token: ac.accesToken, - // username: u.username, - // }; - // } else - setImporting(false); - }} - /> - )} +
@@ -208,11 +208,19 @@ export function CreatePage({ onCreate, onBack }: Props): VNode { > name="payto_uri" - label={i18n.str`Account`} + label={i18n.str`Account details`} /> +
+

+ + If the bank supports Taler Revenue API then you can add the + endpoint URL below to keep the revenue information in sync. + +

+
name="credit_facade_url" - label={i18n.str`Account info URL`} + label={i18n.str`Endpoint URL`} help="https://bank.demo.taler.net/accounts/_username_/taler-revenue/" expand tooltip={i18n.str`From where the merchant can download information about incoming wire transfers to this account`} @@ -242,22 +250,39 @@ export function CreatePage({ onCreate, onBack }: Props): VNode { /> ) : undefined} + + label={i18n.str`Match`} + tooltip={i18n.str`Check where the information match agaisnt the server info.`} + name="verified" + readonly + threeState + help={ + testError !== undefined + ? testError + : state.verified === undefined + ? i18n.str`Not verified` + : state.verified + ? i18n.str`Last test was ok` + : i18n.str`Last test failed` + } + side={ + + } + />
- -
-
+ {!importing ? undefined : ( + { + setImporting(false); + }} + onConfirm={(ac) => { + const u = new URL(ac.infoURL); + const user = u.username; + const pwd = u.password; + u.password = ""; + u.username = ""; + const credit_facade_url = u.href; + setState({ + payto_uri: ac.accountURI, + credit_facade_credentials: + user || pwd + ? { + type: "basic", + password: pwd, + username: user, + } + : undefined, + credit_facade_url, + }); + setImporting(false); + }} + /> + )} + {!revenuePayto ? undefined : ( + { + setRevenuePayto(undefined); + }} + onConfirm={(d) => { + setState({ + ...state, + payto_uri: d, + }); + setRevenuePayto(undefined); + }} + formPayto={ + !state.payto_uri ? undefined : parsePaytoUri(state.payto_uri) + } + testPayto={revenuePayto} + /> + )} + ); } diff --git a/packages/merchant-backoffice-ui/src/paths/instance/accounts/create/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/accounts/create/index.tsx index 9e0830e6e..2c1a13e27 100644 --- a/packages/merchant-backoffice-ui/src/paths/instance/accounts/create/index.tsx +++ b/packages/merchant-backoffice-ui/src/paths/instance/accounts/create/index.tsx @@ -33,7 +33,7 @@ import { } from "@gnu-taler/taler-util"; import { BrowserFetchHttpLib, - useTranslationContext + useTranslationContext, } from "@gnu-taler/web-util/browser"; import { Fragment, VNode, h } from "preact"; import { useState } from "preact/hooks"; @@ -86,10 +86,13 @@ export enum TestRevenueErrorType { export async function testRevenueAPI( revenueAPI: URL, creds: FacadeCredentials | undefined, -): Promise | OperationFail -| OperationFail -| OperationFail -| TalerError> { +): Promise< + | OperationOk + | OperationFail + | OperationFail + | OperationFail + | TalerError +> { const api = new TalerRevenueHttpClient( revenueAPI.href, new BrowserFetchHttpLib(), @@ -113,6 +116,12 @@ export async function testRevenueAPI( return config; } + const resp = await api.getHistory(auth); + if (resp.type === "fail") { + return resp; + } + + return opFixedSuccess(resp.body.credit_account as PaytoString); } catch (err) { if (err instanceof TalerError) { return err; @@ -122,7 +131,6 @@ export async function testRevenueAPI( // detail: err.errorDetail, // }; } + throw err } - - return opFixedSuccess(undefined); } -- cgit v1.2.3