diff options
Diffstat (limited to 'packages/demobank-ui/src')
24 files changed, 299 insertions, 203 deletions
diff --git a/packages/demobank-ui/src/Routing.tsx b/packages/demobank-ui/src/Routing.tsx index afc13636a..409d4ec2d 100644 --- a/packages/demobank-ui/src/Routing.tsx +++ b/packages/demobank-ui/src/Routing.tsx @@ -92,15 +92,15 @@ function PublicRounting({ const settings = useSettingsContext(); const { i18n } = useTranslationContext(); const location = useCurrentLocation(publicPages); - const { navigateTo } = useNavigationContext() + const { navigateTo } = useNavigationContext(); const { api } = useBankCoreApiContext(); const [notification, notify, handleError] = useLocalNotification(); useEffect(() => { if (location === undefined) { - navigateTo(publicPages.login.url({})) + navigateTo(publicPages.login.url({})); } - }, [location]) + }, [location]); if (location === undefined) { return <Fragment />; @@ -166,7 +166,9 @@ function PublicRounting({ operationId={wopid} onOperationAborted={() => navigateTo(publicPages.login.url({}))} routeClose={publicPages.login} - onAuthorizationRequired={() => navigateTo(publicPages.solveSecondFactor.url({}))} + onAuthorizationRequired={() => + navigateTo(publicPages.solveSecondFactor.url({})) + } /> ); } @@ -253,13 +255,13 @@ function PrivateRouting({ username: string; isAdmin: boolean; }): VNode { - const { navigateTo } = useNavigationContext() + const { navigateTo } = useNavigationContext(); const location = useCurrentLocation(privatePages); useEffect(() => { if (location === undefined) { - navigateTo(privatePages.home.url({})) + navigateTo(privatePages.home.url({})); } - }, [location]) + }, [location]); if (location === undefined) { return <Fragment />; @@ -277,7 +279,9 @@ function PrivateRouting({ operationId={wopid} onOperationAborted={() => navigateTo(privatePages.home.url({}))} routeClose={privatePages.home} - onAuthorizationRequired={() => navigateTo(privatePages.solveSecondFactor.url({}))} + onAuthorizationRequired={() => + navigateTo(privatePages.solveSecondFactor.url({})) + } /> ); } @@ -312,7 +316,9 @@ function PrivateRouting({ <ShowAccountDetails account={account} onUpdateSuccess={() => navigateTo(privatePages.home.url({}))} - onAuthorizationRequired={() => navigateTo(privatePages.solveSecondFactor.url({}))} + onAuthorizationRequired={() => + navigateTo(privatePages.solveSecondFactor.url({})) + } routeClose={privatePages.home} /> ); @@ -327,7 +333,9 @@ function PrivateRouting({ focus account={account} onUpdateSuccess={() => navigateTo(privatePages.home.url({}))} - onAuthorizationRequired={() => navigateTo(privatePages.solveSecondFactor.url({}))} + onAuthorizationRequired={() => + navigateTo(privatePages.solveSecondFactor.url({})) + } routeClose={privatePages.home} /> ); @@ -341,7 +349,9 @@ function PrivateRouting({ <RemoveAccount account={account} onUpdateSuccess={() => navigateTo(privatePages.home.url({}))} - onAuthorizationRequired={() => navigateTo(privatePages.solveSecondFactor.url({}))} + onAuthorizationRequired={() => + navigateTo(privatePages.solveSecondFactor.url({})) + } routeCancel={privatePages.home} /> ); @@ -356,7 +366,9 @@ function PrivateRouting({ account={account} routeCashoutDetails={privatePages.cashoutDetails} routeClose={privatePages.home} - onAuthorizationRequired={() => navigateTo(privatePages.solveSecondFactor.url({}))} + onAuthorizationRequired={() => + navigateTo(privatePages.solveSecondFactor.url({})) + } /> ); } @@ -365,7 +377,9 @@ function PrivateRouting({ <RemoveAccount account={username} onUpdateSuccess={() => navigateTo(privatePages.home.url({}))} - onAuthorizationRequired={() => navigateTo(privatePages.solveSecondFactor.url({}))} + onAuthorizationRequired={() => + navigateTo(privatePages.solveSecondFactor.url({})) + } routeCancel={privatePages.home} /> ); @@ -375,7 +389,9 @@ function PrivateRouting({ <ShowAccountDetails account={username} onUpdateSuccess={() => navigateTo(privatePages.home.url({}))} - onAuthorizationRequired={() => navigateTo(privatePages.solveSecondFactor.url({}))} + onAuthorizationRequired={() => + navigateTo(privatePages.solveSecondFactor.url({})) + } routeClose={privatePages.home} /> ); @@ -386,7 +402,9 @@ function PrivateRouting({ focus account={username} onUpdateSuccess={() => navigateTo(privatePages.home.url({}))} - onAuthorizationRequired={() => navigateTo(privatePages.solveSecondFactor.url({}))} + onAuthorizationRequired={() => + navigateTo(privatePages.solveSecondFactor.url({})) + } routeClose={privatePages.home} /> ); @@ -396,7 +414,9 @@ function PrivateRouting({ <CashoutListForAccount account={username} routeCashoutDetails={privatePages.cashoutDetails} - onAuthorizationRequired={() => navigateTo(privatePages.solveSecondFactor.url({}))} + onAuthorizationRequired={() => + navigateTo(privatePages.solveSecondFactor.url({})) + } routeClose={privatePages.home} /> ); @@ -405,7 +425,9 @@ function PrivateRouting({ if (isAdmin) { return ( <AdminHome - onAuthorizationRequired={() => navigateTo(privatePages.solveSecondFactor.url({}))} + onAuthorizationRequired={() => + navigateTo(privatePages.solveSecondFactor.url({})) + } routeCreate={privatePages.accountCreate} routeRemoveAccount={privatePages.accountDelete} routeShowAccount={privatePages.accountDetails} @@ -422,8 +444,12 @@ function PrivateRouting({ routeWireTransfer={privatePages.homeWireTransfer} routeClose={privatePages.home} onClose={() => navigateTo(privatePages.home.url({}))} - onAuthorizationRequired={() => navigateTo(privatePages.solveSecondFactor.url({}))} - onOperationCreated={(wopid) => navigateTo(privatePages.operationDetails.url({ wopid }))} + onAuthorizationRequired={() => + navigateTo(privatePages.solveSecondFactor.url({})) + } + onOperationCreated={(wopid) => + navigateTo(privatePages.operationDetails.url({ wopid })) + } /> ); } @@ -431,7 +457,9 @@ function PrivateRouting({ return ( <CreateCashout account={username} - onAuthorizationRequired={() => navigateTo(privatePages.solveSecondFactor.url({}))} + onAuthorizationRequired={() => + navigateTo(privatePages.solveSecondFactor.url({})) + } routeClose={privatePages.home} /> ); @@ -456,7 +484,9 @@ function PrivateRouting({ return ( <WireTransfer toAccount={destination} - onAuthorizationRequired={() => navigateTo(privatePages.solveSecondFactor.url({}))} + onAuthorizationRequired={() => + navigateTo(privatePages.solveSecondFactor.url({})) + } routeCancel={privatePages.home} onSuccess={() => navigateTo(privatePages.home.url({}))} /> @@ -471,8 +501,12 @@ function PrivateRouting({ routeWireTransfer={privatePages.homeWireTransfer} routeClose={privatePages.home} onClose={() => navigateTo(privatePages.home.url({}))} - onAuthorizationRequired={() => navigateTo(privatePages.solveSecondFactor.url({}))} - onOperationCreated={(wopid) => navigateTo(privatePages.operationDetails.url({ wopid }))} + onAuthorizationRequired={() => + navigateTo(privatePages.solveSecondFactor.url({})) + } + onOperationCreated={(wopid) => + navigateTo(privatePages.operationDetails.url({ wopid })) + } /> ); } @@ -485,8 +519,12 @@ function PrivateRouting({ routeWireTransfer={privatePages.homeWireTransfer} routeClose={privatePages.home} onClose={() => navigateTo(privatePages.home.url({}))} - onAuthorizationRequired={() => navigateTo(privatePages.solveSecondFactor.url({}))} - onOperationCreated={(wopid) => navigateTo(privatePages.operationDetails.url({ wopid }))} + onAuthorizationRequired={() => + navigateTo(privatePages.solveSecondFactor.url({})) + } + onOperationCreated={(wopid) => + navigateTo(privatePages.operationDetails.url({ wopid })) + } /> ); } diff --git a/packages/demobank-ui/src/components/Transactions/state.ts b/packages/demobank-ui/src/components/Transactions/state.ts index 4109c88b2..74e6b0d36 100644 --- a/packages/demobank-ui/src/components/Transactions/state.ts +++ b/packages/demobank-ui/src/components/Transactions/state.ts @@ -42,34 +42,34 @@ export function useComponentState({ account }: Props): State { result.data.type === "fail" ? [] : result.data.body.transactions - .map((tx) => { - const negative = tx.direction === "debit"; - const cp = parsePaytoUri( - negative ? tx.creditor_payto_uri : tx.debtor_payto_uri, - ); - const counterpart = - (cp === undefined || !cp.isKnown - ? undefined - : cp.targetType === "iban" - ? cp.iban - : cp.targetType === "x-taler-bank" - ? cp.account - : cp.targetType === "bitcoin" - ? `${cp.targetPath.substring(0, 6)}...` - : undefined) ?? "unknown"; + .map((tx) => { + const negative = tx.direction === "debit"; + const cp = parsePaytoUri( + negative ? tx.creditor_payto_uri : tx.debtor_payto_uri, + ); + const counterpart = + (cp === undefined || !cp.isKnown + ? undefined + : cp.targetType === "iban" + ? cp.iban + : cp.targetType === "x-taler-bank" + ? cp.account + : cp.targetType === "bitcoin" + ? `${cp.targetPath.substring(0, 6)}...` + : undefined) ?? "unknown"; - const when = AbsoluteTime.fromProtocolTimestamp(tx.date); - const amount = Amounts.parse(tx.amount); - const subject = tx.subject; - return { - negative, - counterpart, - when, - amount, - subject, - }; - }) - .filter((x): x is Transaction => x !== undefined); + const when = AbsoluteTime.fromProtocolTimestamp(tx.date); + const amount = Amounts.parse(tx.amount); + const subject = tx.subject; + return { + negative, + counterpart, + when, + amount, + subject, + }; + }) + .filter((x): x is Transaction => x !== undefined); return { status: "ready", diff --git a/packages/demobank-ui/src/components/Transactions/views.tsx b/packages/demobank-ui/src/components/Transactions/views.tsx index f4f6f66ba..51fb90b61 100644 --- a/packages/demobank-ui/src/components/Transactions/views.tsx +++ b/packages/demobank-ui/src/components/Transactions/views.tsx @@ -93,8 +93,8 @@ export function ReadyView({ item.when.t_ms === "never" ? "" : format(item.when.t_ms, "HH:mm:ss", { - locale: dateLocale, - }); + locale: dateLocale, + }); return ( <tr key={idx} diff --git a/packages/demobank-ui/src/context/navigation.ts b/packages/demobank-ui/src/context/navigation.ts index fc1460c02..acdac4364 100644 --- a/packages/demobank-ui/src/context/navigation.ts +++ b/packages/demobank-ui/src/context/navigation.ts @@ -35,17 +35,19 @@ const Context = createContext<Type>(undefined); export const useNavigationContext = (): Type => useContext(Context); function getPathAndParamsFromWindow() { - const path = typeof window !== "undefined" ? window.location.hash.substring(1) : "/"; - const params: Record<string, string> = {} + const path = + typeof window !== "undefined" ? window.location.hash.substring(1) : "/"; + const params: Record<string, string> = {}; if (typeof window !== "undefined") { for (const [key, value] of new URLSearchParams(window.location.search)) { params[key] = value; } } - return { path, params } + return { path, params }; } -const { path: initialPath, params: initialParams } = getPathAndParamsFromWindow() +const { path: initialPath, params: initialParams } = + getPathAndParamsFromWindow(); // there is a posibility that if the browser does a redirection // (which doesn't go through navigatTo function) and that exectued @@ -53,26 +55,35 @@ const { path: initialPath, params: initialParams } = getPathAndParamsFromWindow( // into account const PopStateEventType = "popstate"; -export const BrowserHashNavigationProvider = ({ children }: { children: ComponentChildren }): VNode => { - const [{ path, params }, setState] = useState({ path: initialPath, params: initialParams }) +export const BrowserHashNavigationProvider = ({ + children, +}: { + children: ComponentChildren; +}): VNode => { + const [{ path, params }, setState] = useState({ + path: initialPath, + params: initialParams, + }); if (typeof window === "undefined") { - throw Error("Can't use BrowserHashNavigationProvider if there is no window object") + throw Error( + "Can't use BrowserHashNavigationProvider if there is no window object", + ); } function navigateTo(path: string) { - const { params } = getPathAndParamsFromWindow() - setState({ path, params }) - window.location.href = path + const { params } = getPathAndParamsFromWindow(); + setState({ path, params }); + window.location.href = path; } useEffect(() => { function eventListener() { - setState(getPathAndParamsFromWindow()) + setState(getPathAndParamsFromWindow()); } window.addEventListener(PopStateEventType, eventListener); return () => { - window.removeEventListener(PopStateEventType, eventListener) - } - }, []) + window.removeEventListener(PopStateEventType, eventListener); + }; + }, []); return h(Context.Provider, { value: { path, params, navigateTo }, children, diff --git a/packages/demobank-ui/src/context/wallet-integration.ts b/packages/demobank-ui/src/context/wallet-integration.ts index 47bdc90ec..e14988ed1 100644 --- a/packages/demobank-ui/src/context/wallet-integration.ts +++ b/packages/demobank-ui/src/context/wallet-integration.ts @@ -14,47 +14,38 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { - stringifyTalerUri, - TalerUri -} from "@gnu-taler/taler-util"; -import { - ComponentChildren, - createContext, - h, - VNode -} from "preact"; +import { stringifyTalerUri, TalerUri } from "@gnu-taler/taler-util"; +import { ComponentChildren, createContext, h, VNode } from "preact"; import { useContext } from "preact/hooks"; /** * https://docs.taler.net/design-documents/039-taler-browser-integration.html - * - * @param uri + * + * @param uri */ function createHeadMetaTag(uri: TalerUri, onNotFound?: () => void) { - const meta = document.createElement("meta"); meta.setAttribute("name", "taler-uri"); meta.setAttribute("content", stringifyTalerUri(uri)); document.head.appendChild(meta); - let walletFound = false + let walletFound = false; window.addEventListener("beforeunload", () => { - walletFound = true - }) + walletFound = true; + }); setTimeout(() => { if (!walletFound && onNotFound) { - onNotFound() + onNotFound(); } - }, 10)//very short timeout + }, 10); //very short timeout } interface Type { /** * Tell the active wallet that an action is found - * - * @param uri - * @returns + * + * @param uri + * @returns */ publishTalerAction: (uri: TalerUri, onNotFound?: () => void) => void; } @@ -64,9 +55,13 @@ const Context = createContext<Type>(undefined); export const useTalerWalletIntegrationAPI = (): Type => useContext(Context); -export const TalerWalletIntegrationBrowserProvider = ({ children }: { children: ComponentChildren }): VNode => { +export const TalerWalletIntegrationBrowserProvider = ({ + children, +}: { + children: ComponentChildren; +}): VNode => { const value: Type = { - publishTalerAction: createHeadMetaTag + publishTalerAction: createHeadMetaTag, }; return h(Context.Provider, { value, @@ -74,7 +69,6 @@ export const TalerWalletIntegrationBrowserProvider = ({ children }: { children: }); }; - export const TalerWalletIntegrationTestingProvider = ({ children, value, @@ -82,7 +76,6 @@ export const TalerWalletIntegrationTestingProvider = ({ children: ComponentChildren; value: Type; }): VNode => { - return h(Context.Provider, { value, children, diff --git a/packages/demobank-ui/src/index.html b/packages/demobank-ui/src/index.html index 6e0638e3f..0789ecf89 100644 --- a/packages/demobank-ui/src/index.html +++ b/packages/demobank-ui/src/index.html @@ -17,25 +17,25 @@ --> <!doctype html> <html lang="en" class="h-full bg-gray-100"> + <head> + <meta http-equiv="content-type" content="text/html; charset=utf-8" /> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width,initial-scale=1" /> + <meta name="taler-support" content="uri,api" /> + <meta name="mobile-web-app-capable" content="yes" /> + <meta name="apple-mobile-web-app-capable" content="yes" /> + <link + rel="icon" + href="data:;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAD///////////////////////////////////////////////////////////////////////////////////////////////////7//v38//78/P/+/fz//vz7///+/v/+/f3//vz7///+/v/+/fz//v38///////////////////////+/v3///7+/////////////////////////////////////////////////////////v3//v79///////+/v3///////r28v/ct5//06SG/9Gffv/Xqo7/7N/V/9e2nf/bsJb/6uDW/9Sskf/euKH/+/j2///////+/v3//////+3azv+/eE3/2rWd/9Kkhv/Vr5T/48i2/8J+VP/Qn3//3ryn/795Tf/WrpP/2LCW/8B6T//w4Nb///////Pn4P+/d0v/9u3n/+7d0v/EhV7//v///+HDr//fxLD/zph2/+TJt//8/Pv/woBX//Lm3f/y5dz/v3hN//bu6f/JjGn/4sW0///////Df1j/8OLZ//v6+P+/elH/+vj1//jy7f+/elL//////+zYzP/Eg13//////967p//MlHT/wn5X///////v4Nb/yY1s///////jw7H/06KG////////////z5t9/+fNvf//////x4pn//Pp4v/8+vn/w39X/8WEX///////5s/A/9CbfP//////27Oc/9y2n////////////9itlf/gu6f//////86Vdf/r2Mz//////8SCXP/Df1j//////+7d0v/KkG7//////+HBrf/VpYr////////////RnoH/5sq6///////Ii2n/8ubf//39/P/Cf1j/xohk/+bNvv//////wn5W//Tq4//58/D/wHxV//7+/f/59fH/v3xU//39/P/w4Nf/xIFb///////hw7H/yo9t/+/f1f/AeU3/+/n2/+nSxP/FhmD//////9qzm//Upon/4MSx/96+qf//////xINc/+3bz//48e3/v3hN//Pn3///////6M+//752S//gw6//06aK/8J+VP/kzLr/zZd1/8OCWv/q18r/17KZ/9Ooi//fv6r/v3dK/+vWyP///////v39///////27un/1aeK/9Opjv/m1cf/1KCC/9a0nP/n08T/0Jx8/82YdP/QnHz/16yR//jx7P///////v39///////+/f3///7+///////+//7//v7+///////+/v7//v/+/////////////////////////v7//v79///////////////////+/v/+/Pv//v39///+/v/+/Pv///7+//7+/f/+/Pv//v39//79/P/+/Pv///7+////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==" + /> + <link rel="shortcut icon" href="data:image/x-icon;," type="image/x-icon" /> + <title>Bank</title> + <!-- Entry point for the bank SPA. --> + <script type="module" src="index.js"></script> + <link rel="stylesheet" href="index.css" /> + </head> -<head> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - <meta charset="utf-8" /> - <meta name="viewport" content="width=device-width,initial-scale=1" /> - <meta name="taler-support" content="uri,api" /> - <meta name="mobile-web-app-capable" content="yes" /> - <meta name="apple-mobile-web-app-capable" content="yes" /> - <link rel="icon" - href="data:;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAD///////////////////////////////////////////////////////////////////////////////////////////////////7//v38//78/P/+/fz//vz7///+/v/+/f3//vz7///+/v/+/fz//v38///////////////////////+/v3///7+/////////////////////////////////////////////////////////v3//v79///////+/v3///////r28v/ct5//06SG/9Gffv/Xqo7/7N/V/9e2nf/bsJb/6uDW/9Sskf/euKH/+/j2///////+/v3//////+3azv+/eE3/2rWd/9Kkhv/Vr5T/48i2/8J+VP/Qn3//3ryn/795Tf/WrpP/2LCW/8B6T//w4Nb///////Pn4P+/d0v/9u3n/+7d0v/EhV7//v///+HDr//fxLD/zph2/+TJt//8/Pv/woBX//Lm3f/y5dz/v3hN//bu6f/JjGn/4sW0///////Df1j/8OLZ//v6+P+/elH/+vj1//jy7f+/elL//////+zYzP/Eg13//////967p//MlHT/wn5X///////v4Nb/yY1s///////jw7H/06KG////////////z5t9/+fNvf//////x4pn//Pp4v/8+vn/w39X/8WEX///////5s/A/9CbfP//////27Oc/9y2n////////////9itlf/gu6f//////86Vdf/r2Mz//////8SCXP/Df1j//////+7d0v/KkG7//////+HBrf/VpYr////////////RnoH/5sq6///////Ii2n/8ubf//39/P/Cf1j/xohk/+bNvv//////wn5W//Tq4//58/D/wHxV//7+/f/59fH/v3xU//39/P/w4Nf/xIFb///////hw7H/yo9t/+/f1f/AeU3/+/n2/+nSxP/FhmD//////9qzm//Upon/4MSx/96+qf//////xINc/+3bz//48e3/v3hN//Pn3///////6M+//752S//gw6//06aK/8J+VP/kzLr/zZd1/8OCWv/q18r/17KZ/9Ooi//fv6r/v3dK/+vWyP///////v39///////27un/1aeK/9Opjv/m1cf/1KCC/9a0nP/n08T/0Jx8/82YdP/QnHz/16yR//jx7P///////v39///////+/f3///7+///////+//7//v7+///////+/v7//v/+/////////////////////////v7//v79///////////////////+/v/+/Pv//v39///+/v/+/Pv///7+//7+/f/+/Pv//v39//79/P/+/Pv///7+////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==" /> - <link rel="shortcut icon" href="data:image/x-icon;," type="image/x-icon" /> - <title>Bank</title> - <!-- Entry point for the bank SPA. --> - <script type="module" src="index.js"></script> - <link rel="stylesheet" href="index.css" /> -</head> - -<body class="h-full"> - <div id="app"></div> -</body> - -</html>
\ No newline at end of file + <body class="h-full"> + <div id="app"></div> + </body> +</html> diff --git a/packages/demobank-ui/src/pages/BankFrame.tsx b/packages/demobank-ui/src/pages/BankFrame.tsx index 35cb30065..d6ab882f1 100644 --- a/packages/demobank-ui/src/pages/BankFrame.tsx +++ b/packages/demobank-ui/src/pages/BankFrame.tsx @@ -86,9 +86,9 @@ export function BankFrame({ backend.state.status !== "loggedIn" ? undefined : () => { - backend.logOut(); - resetBankState(); - } + backend.logOut(); + resetBankState(); + } } sites={ !settings.topNavSites ? [] : Object.entries(settings.topNavSites) @@ -176,7 +176,7 @@ export function BankFrame({ function WelcomeAccount({ account }: { account: string }): VNode { const { i18n } = useTranslationContext(); - const result = useAccountDetails(account) + const result = useAccountDetails(account); if (!result) { return <Loading />; } @@ -184,16 +184,23 @@ function WelcomeAccount({ account }: { account: string }): VNode { return <div />; } if (result.type === "fail") { - return <a href={privatePages.myAccountDetails.url({})} class="underline underline-offset-2" > - <i18n.Translate>Welcome</i18n.Translate> - </a>; + return ( + <a + href={privatePages.myAccountDetails.url({})} + class="underline underline-offset-2" + > + <i18n.Translate>Welcome</i18n.Translate> + </a> + ); } return ( <a href={privatePages.myAccountDetails.url({})} class="underline underline-offset-2" > - <i18n.Translate>Welcome, <span class="whitespace-nowrap">{result.body.name}</span></i18n.Translate> + <i18n.Translate> + Welcome, <span class="whitespace-nowrap">{result.body.name}</span> + </i18n.Translate> </a> ); } diff --git a/packages/demobank-ui/src/pages/DownloadStats.tsx b/packages/demobank-ui/src/pages/DownloadStats.tsx index 2a876d233..e53f1f4e2 100644 --- a/packages/demobank-ui/src/pages/DownloadStats.tsx +++ b/packages/demobank-ui/src/pages/DownloadStats.tsx @@ -269,7 +269,9 @@ export function DownloadStats({ routeCancel }: Props): VNode { class="text-sm text-black font-medium leading-6 " id="availability-label" > - <i18n.Translate>Add previous metric for compare</i18n.Translate> + <i18n.Translate> + Add previous metric for compare + </i18n.Translate> </span> </span> <button @@ -376,7 +378,10 @@ export function DownloadStats({ routeCancel }: Props): VNode { }} > <span class="absolute inset-0 flex items-center justify-center text-xs font-semibold text-white"> - <i18n.Translate>downloading...{" "}{Math.round((lastStep.step / lastStep.total) * 100)}</i18n.Translate> + <i18n.Translate> + downloading...{" "} + {Math.round((lastStep.step / lastStep.total) * 100)} + </i18n.Translate> </span> </div> </div> @@ -392,7 +397,9 @@ export function DownloadStats({ routeCancel }: Props): VNode { download={"bank-stats.csv"} > <Attention title={i18n.str`Download completed`}> - <i18n.Translate>Click here to save the file in your computer.</i18n.Translate> + <i18n.Translate> + Click here to save the file in your computer. + </i18n.Translate> </Attention> </a> )} @@ -443,9 +450,9 @@ async function fetchAllStatus( // await delay() const previous = options.compareWithPrevious ? await api.getMonitor(token, { - timeframe: frame.timeframe, - which: frame.moment.previous, - }) + timeframe: frame.timeframe, + which: frame.moment.previous, + }) : undefined; if (previous && previous.type === "fail" && options.endOnFirstFail) { diff --git a/packages/demobank-ui/src/pages/LoginForm.tsx b/packages/demobank-ui/src/pages/LoginForm.tsx index 9816972ac..8acc79cfc 100644 --- a/packages/demobank-ui/src/pages/LoginForm.tsx +++ b/packages/demobank-ui/src/pages/LoginForm.tsx @@ -70,8 +70,8 @@ export function LoginForm({ username: !username ? i18n.str`Missing username` : // : !USERNAME_REGEX.test(username) - // ? i18n.str`Use letters and numbers only, and start with a lowercase letter` - undefined, + // ? i18n.str`Use letters and numbers only, and start with a lowercase letter` + undefined, password: !password ? i18n.str`Missing password` : undefined, }) ?? busy; diff --git a/packages/demobank-ui/src/pages/OperationState/views.tsx b/packages/demobank-ui/src/pages/OperationState/views.tsx index 4d193505e..dbd8e9b77 100644 --- a/packages/demobank-ui/src/pages/OperationState/views.tsx +++ b/packages/demobank-ui/src/pages/OperationState/views.tsx @@ -329,12 +329,12 @@ export function ReadyView({ onAbort: doAbort, }: State.Ready): VNode<Record<string, never>> { const { i18n } = useTranslationContext(); - const walletInegrationApi = useTalerWalletIntegrationAPI() + const walletInegrationApi = useTalerWalletIntegrationAPI(); const [notification, notify, errorHandler] = useLocalNotification(); const talerWithdrawUri = stringifyWithdrawUri(uri); useEffect(() => { - walletInegrationApi.publishTalerAction(uri) + walletInegrationApi.publishTalerAction(uri); }, []); async function onAbort() { diff --git a/packages/demobank-ui/src/pages/PaymentOptions.tsx b/packages/demobank-ui/src/pages/PaymentOptions.tsx index 9fa30cc41..eb21f637a 100644 --- a/packages/demobank-ui/src/pages/PaymentOptions.tsx +++ b/packages/demobank-ui/src/pages/PaymentOptions.tsx @@ -24,32 +24,42 @@ import { useTranslationContext } from "@gnu-taler/web-util/browser"; import { useWithdrawalDetails } from "../hooks/access.js"; import { useEffect } from "preact/hooks"; -function ShowOperationPendingTag({ woid, onOperationAlreadyCompleted }: { woid: string, onOperationAlreadyCompleted?: () => void }): VNode { +function ShowOperationPendingTag({ + woid, + onOperationAlreadyCompleted, +}: { + woid: string; + onOperationAlreadyCompleted?: () => void; +}): VNode { const { i18n } = useTranslationContext(); const result = useWithdrawalDetails(woid); - const error = !result || result instanceof TalerError || result.type === "fail" - const completed = !error && (result.body.status === "aborted" || result.body.status === "confirmed") + const error = + !result || result instanceof TalerError || result.type === "fail"; + const completed = + !error && + (result.body.status === "aborted" || result.body.status === "confirmed"); useEffect(() => { if (completed && onOperationAlreadyCompleted) { - onOperationAlreadyCompleted() + onOperationAlreadyCompleted(); } - }, [completed]) + }, [completed]); if (error || completed) { return <Fragment />; } - return <span class="flex items-center gap-x-1.5 w-fit rounded-md bg-green-100 px-2 py-1 text-xs font-medium text-green-700 whitespace-pre"> - <svg - class="h-1.5 w-1.5 fill-green-500" - viewBox="0 0 6 6" - aria-hidden="true" - > - <circle cx="3" cy="3" r="3" /> - </svg> - <i18n.Translate>Operation ready</i18n.Translate> - </span> - + return ( + <span class="flex items-center gap-x-1.5 w-fit rounded-md bg-green-100 px-2 py-1 text-xs font-medium text-green-700 whitespace-pre"> + <svg + class="h-1.5 w-1.5 fill-green-500" + viewBox="0 0 6 6" + aria-hidden="true" + > + <circle cx="3" cy="3" r="3" /> + </svg> + <i18n.Translate>Operation ready</i18n.Translate> + </span> + ); } /** @@ -100,7 +110,9 @@ export function PaymentOptions({ <span class="flex"> <div class="text-4xl mr-4 my-auto">💵</div> <span class="grow self-center text-lg text-gray-900 align-middle text-center"> - <i18n.Translate>to a <b>Taler</b> wallet</i18n.Translate> + <i18n.Translate> + to a <b>Taler</b> wallet + </i18n.Translate> </span> <svg class="self-center flex-none h-5 w-5 text-indigo-600" @@ -126,9 +138,15 @@ export function PaymentOptions({ </i18n.Translate> </div> {!!bankState.currentWithdrawalOperationId && ( - <ShowOperationPendingTag woid={bankState.currentWithdrawalOperationId} onOperationAlreadyCompleted={() => { - updateBankState("currentWithdrawalOperationId", undefined) - }} /> + <ShowOperationPendingTag + woid={bankState.currentWithdrawalOperationId} + onOperationAlreadyCompleted={() => { + updateBankState( + "currentWithdrawalOperationId", + undefined, + ); + }} + /> )} </div> </label> diff --git a/packages/demobank-ui/src/pages/PaytoWireTransferForm.tsx b/packages/demobank-ui/src/pages/PaytoWireTransferForm.tsx index ffcf9eb8b..3643e1f6b 100644 --- a/packages/demobank-ui/src/pages/PaytoWireTransferForm.tsx +++ b/packages/demobank-ui/src/pages/PaytoWireTransferForm.tsx @@ -356,7 +356,9 @@ export function PaytoWireTransferForm({ /> </div> <p class="mt-2 text-sm text-gray-500"> - <i18n.Translate>IBAN of the recipient's account</i18n.Translate> + <i18n.Translate> + IBAN of the recipient's account + </i18n.Translate> </p> </div> @@ -385,7 +387,9 @@ export function PaytoWireTransferForm({ /> </div> <p class="mt-2 text-sm text-gray-500"> - <i18n.Translate>Some text to identify the transfer</i18n.Translate> + <i18n.Translate> + Some text to identify the transfer + </i18n.Translate> </p> </div> @@ -534,13 +538,13 @@ export function InputAmount( if ( sep_pos !== -1 && l - sep_pos - 1 > - config.currency_specification.num_fractional_input_digits + config.currency_specification.num_fractional_input_digits ) { e.currentTarget.value = e.currentTarget.value.substring( 0, sep_pos + - config.currency_specification.num_fractional_input_digits + - 1, + config.currency_specification.num_fractional_input_digits + + 1, ); } onChange(e.currentTarget.value); diff --git a/packages/demobank-ui/src/pages/ProfileNavigation.tsx b/packages/demobank-ui/src/pages/ProfileNavigation.tsx index 02f30d8e8..607487c9d 100644 --- a/packages/demobank-ui/src/pages/ProfileNavigation.tsx +++ b/packages/demobank-ui/src/pages/ProfileNavigation.tsx @@ -33,7 +33,7 @@ export function ProfileNavigation({ credentials.status !== "loggedIn" ? false : !credentials.isUserAdministrator; - const { navigateTo } = useNavigationContext() + const { navigateTo } = useNavigationContext(); return ( <div> <div class="sm:hidden"> diff --git a/packages/demobank-ui/src/pages/QrCodeSection.tsx b/packages/demobank-ui/src/pages/QrCodeSection.tsx index 037849804..bf0369855 100644 --- a/packages/demobank-ui/src/pages/QrCodeSection.tsx +++ b/packages/demobank-ui/src/pages/QrCodeSection.tsx @@ -19,7 +19,7 @@ import { HttpStatusCode, stringifyWithdrawUri, TranslatedString, - WithdrawUriResult + WithdrawUriResult, } from "@gnu-taler/taler-util"; import { LocalNotificationBanner, @@ -41,13 +41,13 @@ export function QrCodeSection({ onAborted: () => void; }): VNode { const { i18n } = useTranslationContext(); - const walletInegrationApi = useTalerWalletIntegrationAPI() + const walletInegrationApi = useTalerWalletIntegrationAPI(); const talerWithdrawUri = stringifyWithdrawUri(withdrawUri); const { state: credentials } = useBackendState(); const creds = credentials.status !== "loggedIn" ? undefined : credentials; useEffect(() => { - walletInegrationApi.publishTalerAction(withdrawUri) + walletInegrationApi.publishTalerAction(withdrawUri); }, []); const [notification, notify, handleError] = useLocalNotification(); diff --git a/packages/demobank-ui/src/pages/RegistrationPage.tsx b/packages/demobank-ui/src/pages/RegistrationPage.tsx index cbf5758aa..b7b02b76d 100644 --- a/packages/demobank-ui/src/pages/RegistrationPage.tsx +++ b/packages/demobank-ui/src/pages/RegistrationPage.tsx @@ -218,7 +218,9 @@ function RegistrationForm({ ? "123" : getRandomPassword(); const username = `_${user.first}-${user.second}_`; - const name = `${capitalizeFirstLetter(user.first)} ${capitalizeFirstLetter(user.second)}`; + const name = `${capitalizeFirstLetter(user.first)} ${capitalizeFirstLetter( + user.second, + )}`; await doRegistrationAndLogin(name, username, password, () => { onRegistrationSuccesful(username, password); }); diff --git a/packages/demobank-ui/src/pages/SolveChallengePage.tsx b/packages/demobank-ui/src/pages/SolveChallengePage.tsx index 4d3169390..de0ba483f 100644 --- a/packages/demobank-ui/src/pages/SolveChallengePage.tsx +++ b/packages/demobank-ui/src/pages/SolveChallengePage.tsx @@ -485,10 +485,14 @@ function ChallengeDetails({ {challenge.request.is_public !== undefined && ( <div class="px-4 py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0"> <dt class="text-sm font-medium leading-6 text-gray-900"> - <i18n.Translate>Is this account public?</i18n.Translate> + <i18n.Translate> + Is this account public? + </i18n.Translate> </dt> <dd class="mt-1 text-sm leading-6 text-gray-700 sm:col-span-2 sm:mt-0"> - {challenge.request.is_public ? i18n.str`Enable` : i18n.str`Disable`} + {challenge.request.is_public + ? i18n.str`Enable` + : i18n.str`Disable`} </dd> </div> )} @@ -505,7 +509,9 @@ function ChallengeDetails({ {challenge.request.tan_channel !== undefined && ( <div class="px-4 py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0"> <dt class="text-sm font-medium leading-6 text-gray-900"> - <i18n.Translate>Authentication channel</i18n.Translate> + <i18n.Translate> + Authentication channel + </i18n.Translate> </dt> <dd class="mt-1 text-sm leading-6 text-gray-700 sm:col-span-2 sm:mt-0"> {challenge.request.tan_channel ?? i18n.str`Remove`} diff --git a/packages/demobank-ui/src/pages/WalletWithdrawForm.tsx b/packages/demobank-ui/src/pages/WalletWithdrawForm.tsx index c9c2f174e..8ce4c6a09 100644 --- a/packages/demobank-ui/src/pages/WalletWithdrawForm.tsx +++ b/packages/demobank-ui/src/pages/WalletWithdrawForm.tsx @@ -85,7 +85,7 @@ function OldWithdrawalForm({ // const uri = parseWithdrawUri(suri)! const url = privatePages.operationDetails.url({ wopid: bankState.currentWithdrawalOperationId, - }) + }); return ( <Attention type="warning" title={i18n.str`There is an operation already`}> <span ref={focus ? doAutoFocus : undefined} /> @@ -95,12 +95,12 @@ function OldWithdrawalForm({ <a class="font-semibold text-yellow-700 hover:text-yellow-600" href={url} - // onClick={(e) => { - // e.preventDefault() - // walletInegrationApi.publishTalerAction(uri, () => { - // navigateTo(url) - // }) - // }} + // onClick={(e) => { + // e.preventDefault() + // walletInegrationApi.publishTalerAction(uri, () => { + // navigateTo(url) + // }) + // }} > <i18n.Translate>this page</i18n.Translate> </a> @@ -345,7 +345,7 @@ export function WalletWithdrawForm({ onAuthorizationRequired={onAuthorizationRequired} routeClose={routeCancel} onAbort={onOperationAborted} - // route={routeCancel} + // route={routeCancel} /> )} </div> diff --git a/packages/demobank-ui/src/pages/WithdrawalQRCode.tsx b/packages/demobank-ui/src/pages/WithdrawalQRCode.tsx index 03f6556af..a23909338 100644 --- a/packages/demobank-ui/src/pages/WithdrawalQRCode.tsx +++ b/packages/demobank-ui/src/pages/WithdrawalQRCode.tsx @@ -78,8 +78,17 @@ export function WithdrawalQRCode({ <div class="relative ml-auto mr-auto transform overflow-hidden rounded-lg bg-white px-4 pb-4 pt-5 text-left shadow-xl transition-all sm:my-8 sm:w-full sm:max-w-sm sm:p-6"> <div> <div class="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-yellow-100"> - <svg class="h-5 w-5 text-yellow-400" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"> - <path fill-rule="evenodd" d="M8.485 2.495c.673-1.167 2.357-1.167 3.03 0l6.28 10.875c.673 1.167-.17 2.625-1.516 2.625H3.72c-1.347 0-2.189-1.458-1.515-2.625L8.485 2.495zM10 5a.75.75 0 01.75.75v3.5a.75.75 0 01-1.5 0v-3.5A.75.75 0 0110 5zm0 9a1 1 0 100-2 1 1 0 000 2z" clip-rule="evenodd" /> + <svg + class="h-5 w-5 text-yellow-400" + viewBox="0 0 20 20" + fill="currentColor" + aria-hidden="true" + > + <path + fill-rule="evenodd" + d="M8.485 2.495c.673-1.167 2.357-1.167 3.03 0l6.28 10.875c.673 1.167-.17 2.625-1.516 2.625H3.72c-1.347 0-2.189-1.458-1.515-2.625L8.485 2.495zM10 5a.75.75 0 01.75.75v3.5a.75.75 0 01-1.5 0v-3.5A.75.75 0 0110 5zm0 9a1 1 0 100-2 1 1 0 000 2z" + clip-rule="evenodd" + /> </svg> </div> <div class="mt-3 text-center sm:mt-5"> diff --git a/packages/demobank-ui/src/pages/account/ShowAccountDetails.tsx b/packages/demobank-ui/src/pages/account/ShowAccountDetails.tsx index 8fec0f682..6d5a1c18d 100644 --- a/packages/demobank-ui/src/pages/account/ShowAccountDetails.tsx +++ b/packages/demobank-ui/src/pages/account/ShowAccountDetails.tsx @@ -88,10 +88,11 @@ export function ShowAccountDetails({ async function doUpdate() { if (!submitAccount || !creds) return; await handleError(async () => { - const resp = await api.updateAccount({ - token: creds.token, - username: account, - }, + const resp = await api.updateAccount( + { + token: creds.token, + username: account, + }, submitAccount, ); diff --git a/packages/demobank-ui/src/pages/admin/AccountForm.tsx b/packages/demobank-ui/src/pages/admin/AccountForm.tsx index 300508abe..fcad47b4a 100644 --- a/packages/demobank-ui/src/pages/admin/AccountForm.tsx +++ b/packages/demobank-ui/src/pages/admin/AccountForm.tsx @@ -129,7 +129,7 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({ purpose === "create" || (purpose === "update" && (config.allow_edit_name || userIsAdmin)); - const isCashoutEnabled = config.allow_conversion + const isCashoutEnabled = config.allow_conversion; const editableCashout = showingCurrentUserInfo && (purpose === "create" || @@ -475,9 +475,9 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({ !editableThreshold ? undefined : (e) => { - form.debit_threshold = e as AmountString; - updateForm(structuredClone(form)); - } + form.debit_threshold = e as AmountString; + updateForm(structuredClone(form)); + } } /> <ShowInputErrorLabel @@ -537,8 +537,8 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({ </div> )} {/* channel, not shown if old cashout api */} - {OLD_CASHOUT_API || config.supported_tan_channels - .length === 0 ? undefined : ( + {OLD_CASHOUT_API || + config.supported_tan_channels.length === 0 ? undefined : ( <div class="sm:col-span-5"> <label class="block text-sm font-medium leading-6 text-gray-900" @@ -549,7 +549,7 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({ <div class="mt-2 max-w-xl text-sm text-gray-500"> <div class="px-4 mt-4 grid grid-cols-1 gap-y-6"> {config.supported_tan_channels.indexOf(TanChannel.EMAIL) === - -1 ? undefined : ( + -1 ? undefined : ( <label onClick={(e) => { if (!hasEmail) return; @@ -607,7 +607,7 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({ )} {config.supported_tan_channels.indexOf(TanChannel.SMS) === - -1 ? undefined : ( + -1 ? undefined : ( <label onClick={(e) => { if (!hasPhone) return; diff --git a/packages/demobank-ui/src/pages/admin/AdminHome.tsx b/packages/demobank-ui/src/pages/admin/AdminHome.tsx index d6276e050..f0f8f71be 100644 --- a/packages/demobank-ui/src/pages/admin/AdminHome.tsx +++ b/packages/demobank-ui/src/pages/admin/AdminHome.tsx @@ -335,7 +335,7 @@ function Metrics(): VNode { </div> <dl class="mt-5 grid grid-cols-1 md:grid-cols-2 divide-y divide-gray-200 overflow-hidden rounded-lg bg-white shadow-lg md:divide-x md:divide-y-0"> {resp.current.body.type !== "with-conversions" || - resp.previous.body.type !== "with-conversions" ? undefined : ( + resp.previous.body.type !== "with-conversions" ? undefined : ( <Fragment> <div class="px-4 py-5 sm:p-6"> <dt class="text-base font-normal text-gray-900"> @@ -411,9 +411,9 @@ function MetricValue({ const rate = !currAmount || - Number.isNaN(currAmount) || - !prevAmount || - Number.isNaN(prevAmount) + Number.isNaN(currAmount) || + !prevAmount || + Number.isNaN(prevAmount) ? 0 : cmp === -1 ? 1 - Math.round(currAmount) / Math.round(prevAmount) diff --git a/packages/demobank-ui/src/pages/business/CreateCashout.tsx b/packages/demobank-ui/src/pages/business/CreateCashout.tsx index 050c1069e..8ec34276f 100644 --- a/packages/demobank-ui/src/pages/business/CreateCashout.tsx +++ b/packages/demobank-ui/src/pages/business/CreateCashout.tsx @@ -188,7 +188,8 @@ export function CreateCashout({ * depending on the isDebit flag */ const inputAmount = Amounts.parseOrThrow( - `${form.isDebit ? regional_currency : fiat_currency}:${!form.amount ? "0" : form.amount + `${form.isDebit ? regional_currency : fiat_currency}:${ + !form.amount ? "0" : form.amount }`, ); @@ -470,9 +471,9 @@ export function CreateCashout({ cashoutDisabled ? undefined : (value) => { - form.amount = value; - updateForm(structuredClone(form)); - } + form.amount = value; + updateForm(structuredClone(form)); + } } /> <ShowInputErrorLabel @@ -513,7 +514,7 @@ export function CreateCashout({ </dd> </div> {Amounts.isZero(sellFee) || - Amounts.isZero(calc.beforeFee) ? undefined : ( + Amounts.isZero(calc.beforeFee) ? undefined : ( <div class="flex items-center justify-between border-t-2 afu pt-4"> <dt class="flex items-center text-sm text-gray-600"> <span> @@ -546,7 +547,7 @@ export function CreateCashout({ {/* channel, not shown if new cashout api */} {!OLD_CASHOUT_API ? undefined : config.supported_tan_channels - .length === 0 ? ( + .length === 0 ? ( <div class="sm:col-span-5"> <Attention type="warning" @@ -618,7 +619,7 @@ export function CreateCashout({ )} {config.supported_tan_channels.indexOf(TanChannel.SMS) === - -1 ? undefined : ( + -1 ? undefined : ( <label onClick={() => { if (!resultAccount.body.contact_data?.phone) return; diff --git a/packages/demobank-ui/src/route.ts b/packages/demobank-ui/src/route.ts index 912ba274d..4b021d762 100644 --- a/packages/demobank-ui/src/route.ts +++ b/packages/demobank-ui/src/route.ts @@ -74,8 +74,8 @@ function findMatch<DEF, RM extends RouteMap<DEF>, ROUTES extends keyof RM>( found.groups === undefined ? {} : structuredClone(found.groups); Object.entries(params).forEach(([key, value]) => { - values[key] = value - }) + values[key] = value; + }); // @ts-expect-error values is a map string which is equivalent to the RouteParamsType return { name, parent: pagesMap, values }; @@ -90,7 +90,7 @@ export function useCurrentLocation< ROUTES extends keyof RM, >(pagesMap: RM) { const pageList = Object.keys(pagesMap) as Array<ROUTES>; - const { path, params } = useNavigationContext() + const { path, params } = useNavigationContext(); return findMatch(pagesMap, pageList, path, params); } diff --git a/packages/demobank-ui/src/utils.ts b/packages/demobank-ui/src/utils.ts index 1d3650772..4413ce814 100644 --- a/packages/demobank-ui/src/utils.ts +++ b/packages/demobank-ui/src/utils.ts @@ -89,8 +89,7 @@ export type RecursivePartial<Type> = { : Type[P]; }; export type ErrorMessageMappingFor<Type> = { - [prop in keyof Type]+?: // enumerate known object - Exclude<Type[prop], undefined> extends PaytoString + [prop in keyof Type]+?: Exclude<Type[prop], undefined> extends PaytoString // enumerate known object ? TranslatedString : Exclude<Type[prop], undefined> extends AmountString ? TranslatedString |