fix 7426: URI fragment routing
This commit is contained in:
parent
afa87c2cf4
commit
3eafb64912
@ -10,11 +10,12 @@
|
|||||||
"pretty": "prettier --write src"
|
"pretty": "prettier --write src"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@gnu-taler/taler-util": "workspace:*",
|
||||||
"date-fns": "2.29.3",
|
"date-fns": "2.29.3",
|
||||||
|
"history": "4.10.1",
|
||||||
"jed": "1.1.1",
|
"jed": "1.1.1",
|
||||||
"preact": "10.6.5",
|
"preact": "10.6.5",
|
||||||
"preact-router": "3.2.1",
|
"preact-router": "3.2.1",
|
||||||
"@gnu-taler/taler-util": "workspace:*",
|
|
||||||
"qrcode-generator": "^1.4.4",
|
"qrcode-generator": "^1.4.4",
|
||||||
"react": "npm:@preact/compat@^17.1.2",
|
"react": "npm:@preact/compat@^17.1.2",
|
||||||
"swr": "1.3.0"
|
"swr": "1.3.0"
|
||||||
|
@ -17,8 +17,8 @@
|
|||||||
import { ComponentChildren, Fragment, h, VNode } from "preact";
|
import { ComponentChildren, Fragment, h, VNode } from "preact";
|
||||||
import Match from "preact-router/match";
|
import Match from "preact-router/match";
|
||||||
import { useEffect, useState } from "preact/hooks";
|
import { useEffect, useState } from "preact/hooks";
|
||||||
import { NavigationBar } from "./NavigationBar";
|
import { NavigationBar } from "./NavigationBar.js";
|
||||||
import { Sidebar } from "./SideBar";
|
import { Sidebar } from "./SideBar.js";
|
||||||
|
|
||||||
interface MenuProps {
|
interface MenuProps {
|
||||||
title: string;
|
title: string;
|
||||||
|
@ -32,6 +32,8 @@ import { useLocalStorage, useNotNullLocalStorage } from "../../hooks/index.js";
|
|||||||
import { Translate, useTranslator } from "../../i18n/index.js";
|
import { Translate, useTranslator } from "../../i18n/index.js";
|
||||||
import "../../scss/main.scss";
|
import "../../scss/main.scss";
|
||||||
import { Amounts, HttpStatusCode, parsePaytoUri } from "@gnu-taler/taler-util";
|
import { Amounts, HttpStatusCode, parsePaytoUri } from "@gnu-taler/taler-util";
|
||||||
|
import { createHashHistory } from "history";
|
||||||
|
import Router, { Route, route } from "preact-router";
|
||||||
|
|
||||||
interface BankUiSettings {
|
interface BankUiSettings {
|
||||||
allowRegistrations: boolean;
|
allowRegistrations: boolean;
|
||||||
@ -94,7 +96,7 @@ const PageContextDefault: PageContextType = [
|
|||||||
isLoggedIn: false,
|
isLoggedIn: false,
|
||||||
isRawPayto: false,
|
isRawPayto: false,
|
||||||
showPublicHistories: false,
|
showPublicHistories: false,
|
||||||
tryRegister: false,
|
|
||||||
withdrawalInProgress: false,
|
withdrawalInProgress: false,
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
@ -158,7 +160,6 @@ interface WireTransferRequestType {
|
|||||||
interface PageStateType {
|
interface PageStateType {
|
||||||
isLoggedIn: boolean;
|
isLoggedIn: boolean;
|
||||||
isRawPayto: boolean;
|
isRawPayto: boolean;
|
||||||
tryRegister: boolean;
|
|
||||||
showPublicHistories: boolean;
|
showPublicHistories: boolean;
|
||||||
hasError: boolean;
|
hasError: boolean;
|
||||||
hasInfo: boolean;
|
hasInfo: boolean;
|
||||||
@ -480,7 +481,6 @@ function usePageState(
|
|||||||
state: PageStateType = {
|
state: PageStateType = {
|
||||||
isLoggedIn: false,
|
isLoggedIn: false,
|
||||||
isRawPayto: false,
|
isRawPayto: false,
|
||||||
tryRegister: false,
|
|
||||||
showPublicHistories: false,
|
showPublicHistories: false,
|
||||||
hasError: false,
|
hasError: false,
|
||||||
hasInfo: false,
|
hasInfo: false,
|
||||||
@ -502,17 +502,18 @@ function usePageState(
|
|||||||
//when moving from one page to another
|
//when moving from one page to another
|
||||||
//clean up the info and error bar
|
//clean up the info and error bar
|
||||||
function removeLatestInfo(val: any): ReturnType<typeof retSetter> {
|
function removeLatestInfo(val: any): ReturnType<typeof retSetter> {
|
||||||
const updater = typeof val === 'function' ? val : (c:any) => val
|
const updater = typeof val === "function" ? val : (c: any) => val;
|
||||||
return retSetter((current:any) => {
|
return retSetter((current: any) => {
|
||||||
const cleanedCurrent: PageStateType = {...current,
|
const cleanedCurrent: PageStateType = {
|
||||||
|
...current,
|
||||||
hasInfo: false,
|
hasInfo: false,
|
||||||
info: undefined,
|
info: undefined,
|
||||||
hasError: false,
|
hasError: false,
|
||||||
errors: undefined,
|
errors: undefined,
|
||||||
timestamp: new Date().getTime()
|
timestamp: new Date().getTime(),
|
||||||
}
|
};
|
||||||
return updater(cleanedCurrent)
|
return updater(cleanedCurrent);
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return [retObj, removeLatestInfo];
|
return [retObj, removeLatestInfo];
|
||||||
@ -926,7 +927,7 @@ async function registrationCall(
|
|||||||
const headers = new Headers();
|
const headers = new Headers();
|
||||||
headers.append("Content-Type", "application/json");
|
headers.append("Content-Type", "application/json");
|
||||||
const url = new URL("access-api/testing/register", baseUrl);
|
const url = new URL("access-api/testing/register", baseUrl);
|
||||||
let res: any;
|
let res: Response;
|
||||||
try {
|
try {
|
||||||
res = await fetch(url.href, {
|
res = await fetch(url.href, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
@ -953,19 +954,30 @@ async function registrationCall(
|
|||||||
}
|
}
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
const response = await res.json();
|
const response = await res.json();
|
||||||
pageStateSetter((prevState) => ({
|
if (res.status === 409) {
|
||||||
...prevState,
|
pageStateSetter((prevState) => ({
|
||||||
hasError: true,
|
...prevState,
|
||||||
error: {
|
hasError: true,
|
||||||
title: `New registration gave response error`,
|
error: {
|
||||||
debug: JSON.stringify(response),
|
title: `That username is already taken`,
|
||||||
},
|
debug: JSON.stringify(response),
|
||||||
}));
|
},
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
pageStateSetter((prevState) => ({
|
||||||
|
...prevState,
|
||||||
|
hasError: true,
|
||||||
|
error: {
|
||||||
|
title: `New registration gave response error`,
|
||||||
|
debug: JSON.stringify(response),
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// registration was ok
|
||||||
pageStateSetter((prevState) => ({
|
pageStateSetter((prevState) => ({
|
||||||
...prevState,
|
...prevState,
|
||||||
isLoggedIn: true,
|
isLoggedIn: true,
|
||||||
tryRegister: false,
|
|
||||||
}));
|
}));
|
||||||
backendStateSetter((prevState) => ({
|
backendStateSetter((prevState) => ({
|
||||||
...prevState,
|
...prevState,
|
||||||
@ -973,6 +985,7 @@ async function registrationCall(
|
|||||||
username: req.username,
|
username: req.username,
|
||||||
password: req.password,
|
password: req.password,
|
||||||
}));
|
}));
|
||||||
|
route("/account");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1072,7 +1085,10 @@ function BankFrame(Props: any): VNode {
|
|||||||
This part of the demo shows how a bank that supports Taler
|
This part of the demo shows how a bank that supports Taler
|
||||||
directly would work. In addition to using your own bank account,
|
directly would work. In addition to using your own bank account,
|
||||||
you can also see the transaction history of some{" "}
|
you can also see the transaction history of some{" "}
|
||||||
<a href="#" onClick={goPublicAccounts(pageStateSetter)}>
|
<a
|
||||||
|
href="/public-accounts"
|
||||||
|
onClick={goPublicAccounts(pageStateSetter)}
|
||||||
|
>
|
||||||
Public Accounts
|
Public Accounts
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
@ -1215,7 +1231,7 @@ function PaytoWireTransfer(Props: any): VNode {
|
|||||||
name="subject"
|
name="subject"
|
||||||
id="subject"
|
id="subject"
|
||||||
placeholder="subject"
|
placeholder="subject"
|
||||||
value={submitData?.subject ?? ""}
|
value={submitData?.subject ?? ""}
|
||||||
required
|
required
|
||||||
onInput={(e): void => {
|
onInput={(e): void => {
|
||||||
submitDataSetter((submitData: any) => ({
|
submitDataSetter((submitData: any) => ({
|
||||||
@ -1237,7 +1253,7 @@ function PaytoWireTransfer(Props: any): VNode {
|
|||||||
id="amount"
|
id="amount"
|
||||||
placeholder="amount"
|
placeholder="amount"
|
||||||
required
|
required
|
||||||
value={submitData?.amount ?? ""}
|
value={submitData?.amount ?? ""}
|
||||||
pattern={amountRegex}
|
pattern={amountRegex}
|
||||||
onInput={(e): void => {
|
onInput={(e): void => {
|
||||||
submitDataSetter((submitData: any) => ({
|
submitDataSetter((submitData: any) => ({
|
||||||
@ -1298,11 +1314,12 @@ function PaytoWireTransfer(Props: any): VNode {
|
|||||||
transactionData,
|
transactionData,
|
||||||
backendState,
|
backendState,
|
||||||
pageStateSetter,
|
pageStateSetter,
|
||||||
() => submitDataSetter((p) => ({
|
() =>
|
||||||
amount: undefined,
|
submitDataSetter((p) => ({
|
||||||
iban: undefined,
|
amount: undefined,
|
||||||
subject: undefined,
|
iban: undefined,
|
||||||
})),
|
subject: undefined,
|
||||||
|
})),
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@ -1537,7 +1554,7 @@ function QrCodeSection({
|
|||||||
//Taler Wallet WebExtension is listening to headers response and tab updates.
|
//Taler Wallet WebExtension is listening to headers response and tab updates.
|
||||||
//In the SPA there is no header response with the Taler URI so
|
//In the SPA there is no header response with the Taler URI so
|
||||||
//this hack manually triggers the tab update after the QR is in the DOM.
|
//this hack manually triggers the tab update after the QR is in the DOM.
|
||||||
window.location.href = `${window.location.href.split("#")[0]}#`;
|
window.location.hash = `/account/${new Date().getTime()}`;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -1786,10 +1803,7 @@ function RegistrationButton(Props: any): VNode {
|
|||||||
<button
|
<button
|
||||||
class="pure-button pure-button-secondary btn-cancel"
|
class="pure-button pure-button-secondary btn-cancel"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
pageStateSetter((prevState: PageStateType) => ({
|
route("/register");
|
||||||
...prevState,
|
|
||||||
tryRegister: true,
|
|
||||||
}));
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{i18n`Register`}
|
{i18n`Register`}
|
||||||
@ -1816,14 +1830,12 @@ function LoginForm(Props: any): VNode {
|
|||||||
ref.current?.focus();
|
ref.current?.focus();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const errors = !submitData ? undefined : undefinedIfEmpty({
|
const errors = !submitData
|
||||||
username: !submitData.username
|
? undefined
|
||||||
? i18n`Missing username`
|
: undefinedIfEmpty({
|
||||||
: undefined,
|
username: !submitData.username ? i18n`Missing username` : undefined,
|
||||||
password: !submitData.password
|
password: !submitData.password ? i18n`Missing password` : undefined,
|
||||||
? i18n`Missing password`
|
});
|
||||||
: undefined,
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="login-div">
|
<div class="login-div">
|
||||||
@ -1893,7 +1905,7 @@ function LoginForm(Props: any): VNode {
|
|||||||
submitDataSetter({
|
submitDataSetter({
|
||||||
password: "",
|
password: "",
|
||||||
repeatPassword: "",
|
repeatPassword: "",
|
||||||
username:"",
|
username: "",
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@ -2043,10 +2055,7 @@ function RegistrationForm(Props: any): VNode {
|
|||||||
password: "",
|
password: "",
|
||||||
repeatPassword: "",
|
repeatPassword: "",
|
||||||
});
|
});
|
||||||
pageStateSetter((prevState: PageStateType) => ({
|
route("/account");
|
||||||
...prevState,
|
|
||||||
tryRegister: false,
|
|
||||||
}));
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{i18n`Cancel`}
|
{i18n`Cancel`}
|
||||||
@ -2069,8 +2078,8 @@ function Transactions(Props: any): VNode {
|
|||||||
`access-api/accounts/${accountLabel}/transactions?page=${pageNumber}`,
|
`access-api/accounts/${accountLabel}/transactions?page=${pageNumber}`,
|
||||||
);
|
);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
mutate()
|
mutate();
|
||||||
}, [balanceValue])
|
}, [balanceValue]);
|
||||||
if (typeof error !== "undefined") {
|
if (typeof error !== "undefined") {
|
||||||
console.log("transactions not found error", error);
|
console.log("transactions not found error", error);
|
||||||
switch (error.status) {
|
switch (error.status) {
|
||||||
@ -2152,12 +2161,17 @@ function Account(Props: any): VNode {
|
|||||||
// revalidateOnReconnect: false,
|
// revalidateOnReconnect: false,
|
||||||
});
|
});
|
||||||
const [pageState, setPageState] = useContext(PageContext);
|
const [pageState, setPageState] = useContext(PageContext);
|
||||||
const { withdrawalInProgress, withdrawalId, isLoggedIn, talerWithdrawUri, timestamp } =
|
const {
|
||||||
pageState;
|
withdrawalInProgress,
|
||||||
|
withdrawalId,
|
||||||
|
isLoggedIn,
|
||||||
|
talerWithdrawUri,
|
||||||
|
timestamp,
|
||||||
|
} = pageState;
|
||||||
const i18n = useTranslator();
|
const i18n = useTranslator();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
mutate()
|
mutate();
|
||||||
}, [timestamp])
|
}, [timestamp]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This part shows a list of transactions: with 5 elements by
|
* This part shows a list of transactions: with 5 elements by
|
||||||
@ -2294,7 +2308,11 @@ function Account(Props: any): VNode {
|
|||||||
<section id="main">
|
<section id="main">
|
||||||
<article>
|
<article>
|
||||||
<h2>{i18n`Latest transactions:`}</h2>
|
<h2>{i18n`Latest transactions:`}</h2>
|
||||||
<Transactions balanceValue={balanceValue} pageNumber="0" accountLabel={accountLabel} />
|
<Transactions
|
||||||
|
balanceValue={balanceValue}
|
||||||
|
pageNumber="0"
|
||||||
|
accountLabel={accountLabel}
|
||||||
|
/>
|
||||||
</article>
|
</article>
|
||||||
</section>
|
</section>
|
||||||
</BankFrame>
|
</BankFrame>
|
||||||
@ -2440,50 +2458,39 @@ function PublicHistories(Props: any): VNode {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
function PublicHistoriesPage(): VNode {
|
||||||
* If the user is logged in, it displays
|
// const [backendState, backendStateSetter] = useBackendState();
|
||||||
* the balance, otherwise it offers to login.
|
const [pageState, pageStateSetter] = usePageState();
|
||||||
*/
|
// const i18n = useTranslator();
|
||||||
export function BankHome(): VNode {
|
return (
|
||||||
|
<SWRWithoutCredentials baseUrl={getBankBackendBaseUrl()}>
|
||||||
|
<PageContext.Provider value={[pageState, pageStateSetter]}>
|
||||||
|
<BankFrame>
|
||||||
|
<PublicHistories pageStateSetter={pageStateSetter}>
|
||||||
|
<br />
|
||||||
|
<a
|
||||||
|
class="pure-button"
|
||||||
|
onClick={() => {
|
||||||
|
pageStateSetter((prevState: PageStateType) => ({
|
||||||
|
...prevState,
|
||||||
|
showPublicHistories: false,
|
||||||
|
}));
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Go back
|
||||||
|
</a>
|
||||||
|
</PublicHistories>
|
||||||
|
</BankFrame>
|
||||||
|
</PageContext.Provider>
|
||||||
|
</SWRWithoutCredentials>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function RegistrationPage(): VNode {
|
||||||
const [backendState, backendStateSetter] = useBackendState();
|
const [backendState, backendStateSetter] = useBackendState();
|
||||||
const [pageState, pageStateSetter] = usePageState();
|
const [pageState, pageStateSetter] = usePageState();
|
||||||
const i18n = useTranslator();
|
const i18n = useTranslator();
|
||||||
|
if (!bankUiSettings.allowRegistrations) {
|
||||||
if (pageState.showPublicHistories)
|
|
||||||
return (
|
|
||||||
<SWRWithoutCredentials baseUrl={getBankBackendBaseUrl()}>
|
|
||||||
<PageContext.Provider value={[pageState, pageStateSetter]}>
|
|
||||||
<BankFrame>
|
|
||||||
<PublicHistories pageStateSetter={pageStateSetter}>
|
|
||||||
<br />
|
|
||||||
<a
|
|
||||||
class="pure-button"
|
|
||||||
onClick={() => {
|
|
||||||
pageStateSetter((prevState: PageStateType) => ({
|
|
||||||
...prevState,
|
|
||||||
showPublicHistories: false,
|
|
||||||
}));
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Go back
|
|
||||||
</a>
|
|
||||||
</PublicHistories>
|
|
||||||
</BankFrame>
|
|
||||||
</PageContext.Provider>
|
|
||||||
</SWRWithoutCredentials>
|
|
||||||
);
|
|
||||||
|
|
||||||
if (pageState.tryRegister) {
|
|
||||||
console.log("allow registrations?", bankUiSettings.allowRegistrations);
|
|
||||||
if (bankUiSettings.allowRegistrations)
|
|
||||||
return (
|
|
||||||
<PageContext.Provider value={[pageState, pageStateSetter]}>
|
|
||||||
<BankFrame>
|
|
||||||
<RegistrationForm backendStateSetter={backendStateSetter} />
|
|
||||||
</BankFrame>
|
|
||||||
</PageContext.Provider>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContext.Provider value={[pageState, pageStateSetter]}>
|
<PageContext.Provider value={[pageState, pageStateSetter]}>
|
||||||
<BankFrame>
|
<BankFrame>
|
||||||
@ -2492,44 +2499,82 @@ export function BankHome(): VNode {
|
|||||||
</PageContext.Provider>
|
</PageContext.Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (pageState.isLoggedIn) {
|
|
||||||
if (typeof backendState === "undefined") {
|
|
||||||
pageStateSetter((prevState) => ({
|
|
||||||
...prevState,
|
|
||||||
hasError: true,
|
|
||||||
isLoggedIn: false,
|
|
||||||
error: {
|
|
||||||
title: i18n`Page has a problem: logged in but backend state is lost.`,
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
return <p>Error: waiting for details...</p>;
|
|
||||||
}
|
|
||||||
console.log("Showing the profile page..");
|
|
||||||
return (
|
|
||||||
<SWRWithCredentials
|
|
||||||
username={backendState.username}
|
|
||||||
password={backendState.password}
|
|
||||||
backendUrl={backendState.url}
|
|
||||||
>
|
|
||||||
<PageContext.Provider value={[pageState, pageStateSetter]}>
|
|
||||||
<Account
|
|
||||||
accountLabel={backendState.username}
|
|
||||||
backendState={backendState}
|
|
||||||
/>
|
|
||||||
</PageContext.Provider>
|
|
||||||
</SWRWithCredentials>
|
|
||||||
);
|
|
||||||
} // end of logged-in state.
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContext.Provider value={[pageState, pageStateSetter]}>
|
<PageContext.Provider value={[pageState, pageStateSetter]}>
|
||||||
<BankFrame>
|
<BankFrame>
|
||||||
<h1 class="nav">{i18n`Welcome to ${bankUiSettings.bankName}!`}</h1>
|
<RegistrationForm backendStateSetter={backendStateSetter} />
|
||||||
<LoginForm
|
|
||||||
pageStateSetter={pageStateSetter}
|
|
||||||
backendStateSetter={backendStateSetter}
|
|
||||||
/>
|
|
||||||
</BankFrame>
|
</BankFrame>
|
||||||
</PageContext.Provider>
|
</PageContext.Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function AccountPage(): VNode {
|
||||||
|
const [backendState, backendStateSetter] = useBackendState();
|
||||||
|
const [pageState, pageStateSetter] = usePageState();
|
||||||
|
const i18n = useTranslator();
|
||||||
|
|
||||||
|
if (!pageState.isLoggedIn) {
|
||||||
|
return (
|
||||||
|
<PageContext.Provider value={[pageState, pageStateSetter]}>
|
||||||
|
<BankFrame>
|
||||||
|
<h1 class="nav">{i18n`Welcome to ${bankUiSettings.bankName}!`}</h1>
|
||||||
|
<LoginForm
|
||||||
|
pageStateSetter={pageStateSetter}
|
||||||
|
backendStateSetter={backendStateSetter}
|
||||||
|
/>
|
||||||
|
</BankFrame>
|
||||||
|
</PageContext.Provider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof backendState === "undefined") {
|
||||||
|
pageStateSetter((prevState) => ({
|
||||||
|
...prevState,
|
||||||
|
hasError: true,
|
||||||
|
isLoggedIn: false,
|
||||||
|
error: {
|
||||||
|
title: i18n`Page has a problem: logged in but backend state is lost.`,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
return <p>Error: waiting for details...</p>;
|
||||||
|
}
|
||||||
|
console.log("Showing the profile page..");
|
||||||
|
return (
|
||||||
|
<SWRWithCredentials
|
||||||
|
username={backendState.username}
|
||||||
|
password={backendState.password}
|
||||||
|
backendUrl={backendState.url}
|
||||||
|
>
|
||||||
|
<PageContext.Provider value={[pageState, pageStateSetter]}>
|
||||||
|
<Account
|
||||||
|
accountLabel={backendState.username}
|
||||||
|
backendState={backendState}
|
||||||
|
/>
|
||||||
|
</PageContext.Provider>
|
||||||
|
</SWRWithCredentials>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Redirect({ to }: { to: string }): VNode {
|
||||||
|
useEffect(() => {
|
||||||
|
debugger;
|
||||||
|
route(to, true);
|
||||||
|
}, []);
|
||||||
|
return <div>being redirected to {to}</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the user is logged in, it displays
|
||||||
|
* the balance, otherwise it offers to login.
|
||||||
|
*/
|
||||||
|
export function BankHome(): VNode {
|
||||||
|
const history = createHashHistory();
|
||||||
|
return (
|
||||||
|
<Router history={history}>
|
||||||
|
<Route path="/public-accounts" component={PublicHistoriesPage} />
|
||||||
|
<Route path="/register" component={RegistrationPage} />
|
||||||
|
<Route path="/account/:id*" component={AccountPage} />
|
||||||
|
<Route default component={Redirect} to="/account" />
|
||||||
|
</Router>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@ -105,6 +105,7 @@ importers:
|
|||||||
esbuild-sass-plugin: ^2.4.0
|
esbuild-sass-plugin: ^2.4.0
|
||||||
eslint: ^8.26.0
|
eslint: ^8.26.0
|
||||||
eslint-config-preact: ^1.2.0
|
eslint-config-preact: ^1.2.0
|
||||||
|
history: 4.10.1
|
||||||
jed: 1.1.1
|
jed: 1.1.1
|
||||||
po2json: ^0.4.5
|
po2json: ^0.4.5
|
||||||
preact: 10.6.5
|
preact: 10.6.5
|
||||||
@ -117,6 +118,7 @@ importers:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@gnu-taler/taler-util': link:../taler-util
|
'@gnu-taler/taler-util': link:../taler-util
|
||||||
date-fns: 2.29.3
|
date-fns: 2.29.3
|
||||||
|
history: 4.10.1
|
||||||
jed: 1.1.1
|
jed: 1.1.1
|
||||||
preact: 10.6.5
|
preact: 10.6.5
|
||||||
preact-router: 3.2.1_preact@10.6.5
|
preact-router: 3.2.1_preact@10.6.5
|
||||||
|
Loading…
Reference in New Issue
Block a user