diff options
Diffstat (limited to 'packages/demobank-ui/src/pages')
9 files changed, 66 insertions, 27 deletions
diff --git a/packages/demobank-ui/src/pages/AccountPage/state.ts b/packages/demobank-ui/src/pages/AccountPage/state.ts index a23d3b569..c212e7484 100644 --- a/packages/demobank-ui/src/pages/AccountPage/state.ts +++ b/packages/demobank-ui/src/pages/AccountPage/state.ts @@ -49,7 +49,7 @@ export function useComponentState({ account, goToBusinessAccount, goToConfirmOpe }; } if (result.status === HttpStatusCode.Unauthorized) { - notifyError(i18n.str`Require login`, undefined); + notifyError(i18n.str`Authorization denied`, i18n.str`Maybe the session has expired, login again.`); return { status: "error-user-not-found", error: result, diff --git a/packages/demobank-ui/src/pages/BankFrame.tsx b/packages/demobank-ui/src/pages/BankFrame.tsx index 39ca09f1b..c4f872679 100644 --- a/packages/demobank-ui/src/pages/BankFrame.tsx +++ b/packages/demobank-ui/src/pages/BankFrame.tsx @@ -15,9 +15,9 @@ */ import { Amounts, Logger, PaytoUriIBAN, TranslatedString, parsePaytoUri, stringifyPaytoUri } from "@gnu-taler/taler-util"; -import { useNotifications, useTranslationContext } from "@gnu-taler/web-util/browser"; +import { notifyError, useNotifications, useTranslationContext } from "@gnu-taler/web-util/browser"; import { ComponentChildren, Fragment, h, VNode } from "preact"; -import { StateUpdater, useEffect, useState } from "preact/hooks"; +import { StateUpdater, useEffect, useErrorBoundary, useState } from "preact/hooks"; import { LangSelectorLikePy as LangSelector } from "../components/LangSelector.js"; import { useBackendContext } from "../context/backend.js"; import { useBusinessAccountDetails } from "../hooks/circuit.js"; @@ -50,6 +50,15 @@ export function BankFrame({ const [settings, updateSettings] = useSettings(); const [open, setOpen] = useState(false) + const [error, resetError] = useErrorBoundary(); + + useEffect(() => { + if (error) { + notifyError(i18n.str`Internal error, please report.`, (error instanceof Error ? error.message : String(error)) as TranslatedString) + resetError() + } + }, [error]) + const demo_sites = []; for (const i in bankUiSettings.demoSites) demo_sites.push( @@ -355,7 +364,9 @@ function StatusBanner(): VNode { </div> <div class="ml-3 flex-1 md:flex md:justify-between"> <p class="text-sm font-medium text-red-800">{n.message.title}</p> - <p class="mt-3 text-sm md:ml-6 md:mt-0"> + </div> + <div> + <p class="text-sm"> <button type="button" class="inline-flex font-semibold items-center rounded bg-white px-2 py-1 text-xs text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50" onClick={(e) => { e.preventDefault(); diff --git a/packages/demobank-ui/src/pages/HomePage.tsx b/packages/demobank-ui/src/pages/HomePage.tsx index fb30c1218..d945d80d1 100644 --- a/packages/demobank-ui/src/pages/HomePage.tsx +++ b/packages/demobank-ui/src/pages/HomePage.tsx @@ -68,7 +68,7 @@ export function HomePage({ account={account} goToConfirmOperation={goToConfirmOperation} goToBusinessAccount={goToBusinessAccount} - onLoadNotOk={handleNotOkResult(i18n, onRegister)} + onLoadNotOk={handleNotOkResult(i18n)} /> ); } @@ -112,7 +112,6 @@ export function WithdrawalOperationPage({ export function handleNotOkResult( i18n: ReturnType<typeof useTranslationContext>["i18n"], - onRegister?: () => void, ): <T>( result: | HttpResponsePaginated<T, SandboxBackend.SandboxError> @@ -133,7 +132,7 @@ export function handleNotOkResult( case ErrorType.CLIENT: { if (result.status === HttpStatusCode.Unauthorized) { notifyError(i18n.str`Wrong credentials`, undefined); - return <LoginForm onRegister={onRegister} />; + return <LoginForm />; } const errorData = result.payload; notify({ diff --git a/packages/demobank-ui/src/pages/LoginForm.tsx b/packages/demobank-ui/src/pages/LoginForm.tsx index f1ba439ac..f579678f2 100644 --- a/packages/demobank-ui/src/pages/LoginForm.tsx +++ b/packages/demobank-ui/src/pages/LoginForm.tsx @@ -24,6 +24,7 @@ import { useCredentialsChecker } from "../hooks/useCredentialsChecker.js"; import { bankUiSettings } from "../settings.js"; import { undefinedIfEmpty } from "../utils.js"; + /** * Collect and submit login data. */ @@ -35,7 +36,6 @@ export function LoginForm({ onRegister }: { onRegister?: () => void }): VNode { const { i18n } = useTranslationContext(); const { requestNewLoginToken, refreshLoginToken } = useCredentialsChecker(); - // const testLogin = useCredentialsCheckerOld(); const ref = useRef<HTMLInputElement>(null); useEffect(function focusInput() { ref.current?.focus(); @@ -120,6 +120,13 @@ export function LoginForm({ onRegister }: { onRegister?: () => void }): VNode { setBusy(undefined) } + /** + * Register form may be shown in the initialization step. + * If this is an error when usgin the app the registration + * callback is not set + */ + const isSessionExpired = !onRegister + return ( <Fragment> <h1 class="nav"></h1> @@ -128,9 +135,9 @@ export function LoginForm({ onRegister }: { onRegister?: () => void }): VNode { )} */} <div class="flex min-h-full flex-col justify-center"> - <div class="sm:mx-auto sm:w-full sm:max-w-sm"> + {/* <div class="sm:mx-auto sm:w-full sm:max-w-sm"> <h2 class="text-center text-2xl font-bold leading-9 tracking-tight text-gray-900">{i18n.str`Welcome to ${bankUiSettings.bankName}!`}</h2> - </div> + </div> */} <div class="mt-10 sm:mx-auto sm:w-full sm:max-w-sm"> <form class="space-y-6" noValidate @@ -151,8 +158,9 @@ export function LoginForm({ onRegister }: { onRegister?: () => void }): VNode { type="text" name="username" id="username" - class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6" + class="block w-full disabled:bg-gray-200 rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6" value={username ?? ""} + disabled={isSessionExpired} enterkeyhint="next" placeholder="identification" autocomplete="username" @@ -194,7 +202,28 @@ export function LoginForm({ onRegister }: { onRegister?: () => void }): VNode { </div> </div> - <div> + {isSessionExpired ? <div class="flex justify-between"> + <button type="submit" + class="rounded-md bg-white-600 px-3 py-1.5 text-sm font-semibold leading-6 text-black shadow-sm hover:bg-gray-100 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gray-600" + onClick={(e) => { + e.preventDefault() + doLogin() + }} + > + <i18n.Translate>Cancel</i18n.Translate> + </button> + + <button type="submit" + class="rounded-md bg-indigo-600 disabled:bg-gray-300 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600" + disabled={!!errors} + onClick={(e) => { + e.preventDefault() + doLogin() + }} + > + <i18n.Translate>Renew session</i18n.Translate> + </button> + </div> : <div> <button type="submit" class="flex w-full justify-center rounded-md bg-indigo-600 disabled:bg-gray-300 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600" disabled={!!errors} @@ -205,7 +234,7 @@ export function LoginForm({ onRegister }: { onRegister?: () => void }): VNode { > <i18n.Translate>Log in</i18n.Translate> </button> - </div> + </div>} </form> {bankUiSettings.allowRegistrations && onRegister && diff --git a/packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx b/packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx index 30fcbdff7..d160a88b3 100644 --- a/packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx +++ b/packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx @@ -317,8 +317,9 @@ export function WithdrawalConfirmationQuestion({ </div> <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">Amount</dt> - <dd class="mt-1 text-sm leading-6 text-gray-700 sm:col-span-2 sm:mt-0">To be added</dd> - {/* Amounts.stringifyValue(details.amount) */} + <dd class="mt-1 text-sm leading-6 text-gray-700 sm:col-span-2 sm:mt-0"> + {Amounts.stringifyValue(details.amount)} + </dd> </div> </dl> </div> diff --git a/packages/demobank-ui/src/pages/admin/Account.tsx b/packages/demobank-ui/src/pages/admin/Account.tsx index 8ea59cdcb..521bc8eb3 100644 --- a/packages/demobank-ui/src/pages/admin/Account.tsx +++ b/packages/demobank-ui/src/pages/admin/Account.tsx @@ -13,7 +13,7 @@ export function AdminAccount({ onRegister }: { onRegister: () => void }): VNode const result = useAccountDetails(account); if (!result.ok) { - return handleNotOkResult(i18n, onRegister)(result); + return handleNotOkResult(i18n)(result); } const { data } = result; diff --git a/packages/demobank-ui/src/pages/admin/AccountList.tsx b/packages/demobank-ui/src/pages/admin/AccountList.tsx index eb5765533..f99b320a4 100644 --- a/packages/demobank-ui/src/pages/admin/AccountList.tsx +++ b/packages/demobank-ui/src/pages/admin/AccountList.tsx @@ -8,17 +8,16 @@ import { useTranslationContext } from "@gnu-taler/web-util/browser"; interface Props { onAction: (type: AccountAction, account: string) => void; account: string | undefined; - onRegister: () => void; onCreateAccount: () => void; } -export function AccountList({ account, onAction, onCreateAccount, onRegister }: Props): VNode { +export function AccountList({ account, onAction, onCreateAccount }: Props): VNode { const result = useBusinessAccounts({ account }); const { i18n } = useTranslationContext(); if (result.loading) return <div />; if (!result.ok) { - return handleNotOkResult(i18n, onRegister)(result); + return handleNotOkResult(i18n)(result); } const { customers } = result.data; diff --git a/packages/demobank-ui/src/pages/admin/Home.tsx b/packages/demobank-ui/src/pages/admin/Home.tsx index 5033b7fdc..725820ada 100644 --- a/packages/demobank-ui/src/pages/admin/Home.tsx +++ b/packages/demobank-ui/src/pages/admin/Home.tsx @@ -37,7 +37,7 @@ export function AdminHome({ onRegister }: Props): VNode { switch (action.type) { case "show-cashouts-details": return <ShowCashoutDetails id={action.account} - onLoadNotOk={handleNotOkResult(i18n, onRegister)} + onLoadNotOk={handleNotOkResult(i18n)} onCancel={() => { setAction(undefined); }} @@ -73,7 +73,7 @@ export function AdminHome({ onRegister }: Props): VNode { ) case "update-password": return <UpdateAccountPassword account={action.account} - onLoadNotOk={handleNotOkResult(i18n, onRegister)} + onLoadNotOk={handleNotOkResult(i18n)} onUpdateSuccess={() => { notifyInfo(i18n.str`Password changed`); setAction(undefined); @@ -84,7 +84,7 @@ export function AdminHome({ onRegister }: Props): VNode { /> case "remove-account": return <RemoveAccount account={action.account} - onLoadNotOk={handleNotOkResult(i18n, onRegister)} + onLoadNotOk={handleNotOkResult(i18n)} onUpdateSuccess={() => { notifyInfo(i18n.str`Account removed`); setAction(undefined); @@ -95,7 +95,7 @@ export function AdminHome({ onRegister }: Props): VNode { /> case "show-details": return <ShowAccountDetails account={action.account} - onLoadNotOk={handleNotOkResult(i18n, onRegister)} + onLoadNotOk={handleNotOkResult(i18n)} onChangePassword={() => { setAction({ type: "update-password", diff --git a/packages/demobank-ui/src/pages/business/Home.tsx b/packages/demobank-ui/src/pages/business/Home.tsx index 628ae328d..c9d798082 100644 --- a/packages/demobank-ui/src/pages/business/Home.tsx +++ b/packages/demobank-ui/src/pages/business/Home.tsx @@ -75,7 +75,7 @@ export function BusinessAccount({ return ( <CreateCashout account={account} - onLoadNotOk={handleNotOkResult(i18n, onRegister)} + onLoadNotOk={handleNotOkResult(i18n)} onCancel={() => { setNewcashout(false); }} @@ -93,7 +93,7 @@ export function BusinessAccount({ return ( <ShowCashoutDetails id={showCashoutDetails} - onLoadNotOk={handleNotOkResult(i18n, onRegister)} + onLoadNotOk={handleNotOkResult(i18n)} onCancel={() => { setShowCashoutDetails(undefined); }} @@ -104,7 +104,7 @@ export function BusinessAccount({ return ( <UpdateAccountPassword account={account} - onLoadNotOk={handleNotOkResult(i18n, onRegister)} + onLoadNotOk={handleNotOkResult(i18n)} onUpdateSuccess={() => { notifyInfo(i18n.str`Password changed`); setUpdatePassword(false); @@ -119,7 +119,7 @@ export function BusinessAccount({ <div> <ShowAccountDetails account={account} - onLoadNotOk={handleNotOkResult(i18n, onRegister)} + onLoadNotOk={handleNotOkResult(i18n)} onUpdateSuccess={() => { notifyInfo(i18n.str`Account updated`); }} |