240 lines
6.9 KiB
TypeScript
240 lines
6.9 KiB
TypeScript
/*
|
|
This file is part of GNU Taler
|
|
(C) 2022 Taler Systems S.A.
|
|
|
|
GNU Taler is free software; you can redistribute it and/or modify it under the
|
|
terms of the GNU General Public License as published by the Free Software
|
|
Foundation; either version 3, or (at your option) any later version.
|
|
|
|
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License along with
|
|
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
|
*/
|
|
|
|
import { Logger } from "@gnu-taler/taler-util";
|
|
import { useTranslationContext } from "@gnu-taler/web-util/lib/index.browser";
|
|
import { ComponentChildren, Fragment, h, VNode } from "preact";
|
|
import talerLogo from "../assets/logo-white.svg";
|
|
import { LangSelectorLikePy as LangSelector } from "../components/LangSelector.js";
|
|
import { useBackendContext } from "../context/backend.js";
|
|
import {
|
|
ErrorMessage,
|
|
PageStateType,
|
|
usePageContext,
|
|
} from "../context/pageState.js";
|
|
import { useBusinessAccountDetails } from "../hooks/circuit.js";
|
|
import { bankUiSettings } from "../settings.js";
|
|
|
|
const logger = new Logger("BankFrame");
|
|
|
|
function MaybeBusinessButton({
|
|
account,
|
|
onClick,
|
|
}: {
|
|
account: string;
|
|
onClick: () => void;
|
|
}): VNode {
|
|
const { i18n } = useTranslationContext();
|
|
const result = useBusinessAccountDetails(account);
|
|
if (!result.ok) return <Fragment />;
|
|
return (
|
|
<div class="some-space">
|
|
<a
|
|
href="#"
|
|
class="pure-button pure-button-primary"
|
|
onClick={(e) => {
|
|
e.preventDefault();
|
|
onClick();
|
|
}}
|
|
>{i18n.str`Business Profile`}</a>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function BankFrame({
|
|
children,
|
|
goToBusinessAccount,
|
|
}: {
|
|
children: ComponentChildren;
|
|
goToBusinessAccount?: () => void;
|
|
}): VNode {
|
|
const { i18n } = useTranslationContext();
|
|
const backend = useBackendContext();
|
|
const { pageState, pageStateSetter } = usePageContext();
|
|
logger.trace("state", pageState);
|
|
|
|
const demo_sites = [];
|
|
for (const i in bankUiSettings.demoSites)
|
|
demo_sites.push(
|
|
<a href={bankUiSettings.demoSites[i][1]}>
|
|
{bankUiSettings.demoSites[i][0]}
|
|
</a>,
|
|
);
|
|
|
|
return (
|
|
<Fragment>
|
|
<header
|
|
class="demobar"
|
|
style="display: flex; flex-direction: row; justify-content: space-between;"
|
|
>
|
|
<a href="#main" class="skip">{i18n.str`Skip to main content`}</a>
|
|
<div style="max-width: 50em; margin-left: 2em;">
|
|
<h1>
|
|
<span class="it">
|
|
<a href="/">{bankUiSettings.bankName}</a>
|
|
</span>
|
|
</h1>
|
|
{maybeDemoContent(
|
|
<p>
|
|
<i18n.Translate>
|
|
This part of the demo shows how a bank that supports Taler
|
|
directly would work. In addition to using your own bank account,
|
|
you can also see the transaction history of some{" "}
|
|
<a href="/public-accounts">Public Accounts</a>.
|
|
</i18n.Translate>
|
|
</p>,
|
|
)}
|
|
</div>
|
|
<a href="https://taler.net/">
|
|
<img
|
|
src={talerLogo}
|
|
alt={i18n.str`Taler logo`}
|
|
height="100"
|
|
width="224"
|
|
style="margin: 2em 2em"
|
|
/>
|
|
</a>
|
|
</header>
|
|
<div style="display:flex; flex-direction: column;" class="navcontainer">
|
|
<nav class="demolist">
|
|
{maybeDemoContent(<Fragment>{demo_sites}</Fragment>)}
|
|
<div class="right">
|
|
<LangSelector />
|
|
</div>
|
|
</nav>
|
|
</div>
|
|
<section id="main" class="content">
|
|
{pageState.error && (
|
|
<ErrorBanner
|
|
error={pageState.error}
|
|
onClear={() => {
|
|
pageStateSetter((prev) => ({ ...prev, error: undefined }));
|
|
}}
|
|
/>
|
|
)}
|
|
<StatusBanner />
|
|
{backend.state.status === "loggedIn" ? (
|
|
<div class="top-right">
|
|
{goToBusinessAccount ? (
|
|
<MaybeBusinessButton
|
|
account={backend.state.username}
|
|
onClick={goToBusinessAccount}
|
|
/>
|
|
) : undefined}
|
|
<div class="some-space">
|
|
<a
|
|
href="#"
|
|
class="pure-button logout-button"
|
|
onClick={() => {
|
|
pageStateSetter((prevState: PageStateType) => {
|
|
const { talerWithdrawUri, withdrawalId, ...rest } =
|
|
prevState;
|
|
backend.logOut();
|
|
return {
|
|
...rest,
|
|
withdrawalInProgress: false,
|
|
error: undefined,
|
|
info: undefined,
|
|
isRawPayto: false,
|
|
};
|
|
});
|
|
}}
|
|
>{i18n.str`Logout`}</a>
|
|
</div>
|
|
</div>
|
|
) : null}
|
|
{children}
|
|
</section>
|
|
<section id="footer" class="footer">
|
|
<div class="footer">
|
|
<hr />
|
|
<div>
|
|
<p>
|
|
You can learn more about GNU Taler on our{" "}
|
|
<a href="https://taler.net">main website</a>.
|
|
</p>
|
|
</div>
|
|
<div style="flex-grow:1" />
|
|
<p>Copyright © 2014—2022 Taler Systems SA</p>
|
|
</div>
|
|
</section>
|
|
</Fragment>
|
|
);
|
|
}
|
|
|
|
function maybeDemoContent(content: VNode): VNode {
|
|
if (bankUiSettings.showDemoNav) {
|
|
return content;
|
|
}
|
|
return <Fragment />;
|
|
}
|
|
|
|
export function ErrorBanner({
|
|
error,
|
|
onClear,
|
|
}: {
|
|
error: ErrorMessage;
|
|
onClear: () => void;
|
|
}): VNode | null {
|
|
return (
|
|
<div class="informational informational-fail" style={{ marginTop: 8 }}>
|
|
<div style={{ display: "flex", justifyContent: "space-between" }}>
|
|
<p>
|
|
<b>{error.title}</b>
|
|
</p>
|
|
<div>
|
|
<input
|
|
type="button"
|
|
class="pure-button"
|
|
value="Clear"
|
|
onClick={(e) => {
|
|
e.preventDefault();
|
|
onClear();
|
|
}}
|
|
/>
|
|
</div>
|
|
</div>
|
|
<p>{error.description}</p>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function StatusBanner(): VNode | null {
|
|
const { pageState, pageStateSetter } = usePageContext();
|
|
if (!pageState.info) return null;
|
|
|
|
const rval = (
|
|
<div class="informational informational-ok" style={{ marginTop: 8 }}>
|
|
<div style={{ display: "flex", justifyContent: "space-between" }}>
|
|
<p>
|
|
<b>{pageState.info}</b>
|
|
</p>
|
|
<div>
|
|
<input
|
|
type="button"
|
|
class="pure-button"
|
|
value="Clear"
|
|
onClick={async () => {
|
|
pageStateSetter((prev) => ({ ...prev, info: undefined }));
|
|
}}
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
return rval;
|
|
}
|