aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2023-08-07 06:51:10 -0300
committerSebastian <sebasjm@gmail.com>2023-08-07 08:14:44 -0300
commit7d1621767cec57e9e7217f620844655279ab1af5 (patch)
treef171293fc160dd9447e7f7f8a6bfb6917ac98e19
parent8eb0183c784865225569da1fa1f91a8038693405 (diff)
ui settings view
-rw-r--r--packages/merchant-backoffice-ui/src/Application.tsx24
-rw-r--r--packages/merchant-backoffice-ui/src/ApplicationReadyRoutes.tsx14
-rw-r--r--packages/merchant-backoffice-ui/src/InstanceRoutes.tsx7
-rw-r--r--packages/merchant-backoffice-ui/src/components/exception/login.tsx2
-rw-r--r--packages/merchant-backoffice-ui/src/components/menu/NavigationBar.tsx2
-rw-r--r--packages/merchant-backoffice-ui/src/components/menu/SideBar.tsx64
-rw-r--r--packages/merchant-backoffice-ui/src/components/menu/index.tsx7
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/orders/list/ListPage.tsx4
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/templates/create/CreatePage.tsx38
-rw-r--r--packages/merchant-backoffice-ui/src/paths/settings/index.tsx15
10 files changed, 118 insertions, 59 deletions
diff --git a/packages/merchant-backoffice-ui/src/Application.tsx b/packages/merchant-backoffice-ui/src/Application.tsx
index 23510c456..f6a81ff8d 100644
--- a/packages/merchant-backoffice-ui/src/Application.tsx
+++ b/packages/merchant-backoffice-ui/src/Application.tsx
@@ -26,7 +26,7 @@ import {
} from "@gnu-taler/web-util/browser";
import { Fragment, h, VNode } from "preact";
import { route } from "preact-router";
-import { useMemo } from "preact/hooks";
+import { useMemo, useState } from "preact/hooks";
import { ApplicationReadyRoutes } from "./ApplicationReadyRoutes.js";
import { Loading } from "./components/exception/loading.js";
import {
@@ -42,6 +42,7 @@ import { useBackendConfig } from "./hooks/backend.js";
import { strings } from "./i18n/strings.js";
import LoginPage from "./paths/login/index.js";
import { HttpStatusCode } from "@gnu-taler/taler-util";
+import { Settings } from "./paths/settings/index.js";
export function Application(): VNode {
return (
@@ -70,10 +71,19 @@ function ApplicationStatusRoutes(): VNode {
: { currency: "unknown", version: "unknown" };
const ctx = useMemo(() => ({ currency, version }), [currency, version]);
+ const [showSettings, setShowSettings] = useState(false)
+
+ if (showSettings) {
+ return <Fragment>
+ <NotYetReadyAppMenu onShowSettings={() => setShowSettings(true)} title="UI Settings" />
+ <Settings />
+ </Fragment>
+ }
+
if (!triedToLog) {
return (
<Fragment>
- <NotYetReadyAppMenu title="Welcome!" />
+ <NotYetReadyAppMenu title="Welcome!" onShowSettings={() => setShowSettings(true)} />
<LoginPage onConfirm={updateLoginInfoAndGoToRoot} />
</Fragment>
);
@@ -87,7 +97,7 @@ function ApplicationStatusRoutes(): VNode {
) {
return (
<Fragment>
- <NotYetReadyAppMenu title="Login" />
+ <NotYetReadyAppMenu title="Login" onShowSettings={() => setShowSettings(true)} />
<LoginPage onConfirm={updateLoginInfoAndGoToRoot} />
</Fragment>
);
@@ -98,7 +108,7 @@ function ApplicationStatusRoutes(): VNode {
) {
return (
<Fragment>
- <NotYetReadyAppMenu title="Error" />
+ <NotYetReadyAppMenu title="Error" onShowSettings={() => setShowSettings(true)} />
<NotificationCard
notification={{
message: i18n.str`Server not found`,
@@ -112,7 +122,7 @@ function ApplicationStatusRoutes(): VNode {
}
if (result.type === ErrorType.SERVER) {
<Fragment>
- <NotYetReadyAppMenu title="Error" />
+ <NotYetReadyAppMenu title="Error" onShowSettings={() => setShowSettings(true)} />
<NotificationCard
notification={{
message: i18n.str`Server response with an error code`,
@@ -125,7 +135,7 @@ function ApplicationStatusRoutes(): VNode {
}
if (result.type === ErrorType.UNREADABLE) {
<Fragment>
- <NotYetReadyAppMenu title="Error" />
+ <NotYetReadyAppMenu title="Error" onShowSettings={() => setShowSettings(true)} />
<NotificationCard
notification={{
message: i18n.str`Response from server is unreadable, http status: ${result.status}`,
@@ -138,7 +148,7 @@ function ApplicationStatusRoutes(): VNode {
}
return (
<Fragment>
- <NotYetReadyAppMenu title="Error" />
+ <NotYetReadyAppMenu title="Error" onShowSettings={() => setShowSettings(true)} />
<NotificationCard
notification={{
message: i18n.str`Unexpected Error`,
diff --git a/packages/merchant-backoffice-ui/src/ApplicationReadyRoutes.tsx b/packages/merchant-backoffice-ui/src/ApplicationReadyRoutes.tsx
index 7731dac88..277c2b176 100644
--- a/packages/merchant-backoffice-ui/src/ApplicationReadyRoutes.tsx
+++ b/packages/merchant-backoffice-ui/src/ApplicationReadyRoutes.tsx
@@ -33,6 +33,7 @@ import { InstanceRoutes } from "./InstanceRoutes.js";
import LoginPage from "./paths/login/index.js";
import { INSTANCE_ID_LOOKUP } from "./utils/constants.js";
import { HttpStatusCode } from "@gnu-taler/taler-util";
+import { Settings } from "./paths/settings/index.js";
export function ApplicationReadyRoutes(): VNode {
const { i18n } = useTranslationContext();
@@ -48,8 +49,15 @@ export function ApplicationReadyRoutes(): VNode {
clearAllTokens();
route("/");
};
+ const [showSettings, setShowSettings] = useState(false)
- if (result.loading) return <NotYetReadyAppMenu title="Loading..." />;
+ if (showSettings) {
+ return <Fragment>
+ <NotYetReadyAppMenu onShowSettings={() => setShowSettings(true)} title="UI Settings" onLogout={clearTokenAndGoToRoot} />
+ <Settings/>
+ </Fragment>
+ }
+ if (result.loading) return <NotYetReadyAppMenu onShowSettings={() => setShowSettings(true)} title="Loading..." />;
let admin = true;
let instanceNameByBackendURL;
@@ -61,7 +69,7 @@ export function ApplicationReadyRoutes(): VNode {
) {
return (
<Fragment>
- <NotYetReadyAppMenu title="Login" onLogout={clearTokenAndGoToRoot} />
+ <NotYetReadyAppMenu onShowSettings={() => setShowSettings(true)} title="Login" onLogout={clearTokenAndGoToRoot} />
<NotificationCard
notification={{
message: i18n.str`Access denied`,
@@ -81,7 +89,7 @@ export function ApplicationReadyRoutes(): VNode {
// does not match our pattern
return (
<Fragment>
- <NotYetReadyAppMenu title="Error" onLogout={clearTokenAndGoToRoot} />
+ <NotYetReadyAppMenu onShowSettings={() => setShowSettings(true)} title="Error" onLogout={clearTokenAndGoToRoot} />
<NotificationCard
notification={{
message: i18n.str`Couldn't access the server.`,
diff --git a/packages/merchant-backoffice-ui/src/InstanceRoutes.tsx b/packages/merchant-backoffice-ui/src/InstanceRoutes.tsx
index cb4abdd40..1547442ea 100644
--- a/packages/merchant-backoffice-ui/src/InstanceRoutes.tsx
+++ b/packages/merchant-backoffice-ui/src/InstanceRoutes.tsx
@@ -68,6 +68,7 @@ import LoginPage from "./paths/login/index.js";
import NotFoundPage from "./paths/notfound/index.js";
import { Notification } from "./utils/types.js";
import { MerchantBackend } from "./declaration.js";
+import { Settings } from "./paths/settings/index.js";
export enum InstancePaths {
// details = '/',
@@ -100,6 +101,8 @@ export enum InstancePaths {
webhooks_list = "/webhooks",
webhooks_update = "/webhooks/:tid/update",
webhooks_new = "/webhooks/new",
+
+ settings = "/settings",
}
// eslint-disable-next-line @typescript-eslint/no-empty-function
@@ -240,6 +243,9 @@ export function InstanceRoutes({
<Menu
instance={id}
admin={admin}
+ onShowSettings={() => {
+ route("/settings")
+ }}
path={path}
onLogout={clearTokenAndGoToRoot}
setInstanceName={setInstanceName}
@@ -558,6 +564,7 @@ export function InstanceRoutes({
}}
/>
<Route path={InstancePaths.kyc} component={ListKYCPage} />
+ <Route path={InstancePaths.settings} component={Settings} />
{/**
* Example pages
*/}
diff --git a/packages/merchant-backoffice-ui/src/components/exception/login.tsx b/packages/merchant-backoffice-ui/src/components/exception/login.tsx
index 984b6fe06..f2f94a7c5 100644
--- a/packages/merchant-backoffice-ui/src/components/exception/login.tsx
+++ b/packages/merchant-backoffice-ui/src/components/exception/login.tsx
@@ -229,7 +229,7 @@ export function LoginModal({ onConfirm, withMessage }: Props): VNode {
);
}
-function AsyncButton({onClick, children}:{onClick: () => Promise<void>, children: ComponentChildren}):VNode {
+function AsyncButton({ onClick, children }: { onClick: () => Promise<void>, children: ComponentChildren }): VNode {
const [running, setRunning] = useState(false)
return <button class="button is-info" disabled={running} onClick={() => {
setRunning(true)
diff --git a/packages/merchant-backoffice-ui/src/components/menu/NavigationBar.tsx b/packages/merchant-backoffice-ui/src/components/menu/NavigationBar.tsx
index 9624a2c38..9f1b33893 100644
--- a/packages/merchant-backoffice-ui/src/components/menu/NavigationBar.tsx
+++ b/packages/merchant-backoffice-ui/src/components/menu/NavigationBar.tsx
@@ -20,7 +20,6 @@
*/
import { h, VNode } from "preact";
-import { LangSelector } from "./LangSelector.js";
import logo from "../../assets/logo-2021.svg";
interface Props {
@@ -65,7 +64,6 @@ export function NavigationBar({ onMobileMenu, title }: Props): VNode {
</a>
<div class="navbar-end">
<div class="navbar-item" style={{ paddingTop: 4, paddingBottom: 4 }}>
- <LangSelector />
</div>
</div>
</div>
diff --git a/packages/merchant-backoffice-ui/src/components/menu/SideBar.tsx b/packages/merchant-backoffice-ui/src/components/menu/SideBar.tsx
index 6fee600eb..f3cf80b92 100644
--- a/packages/merchant-backoffice-ui/src/components/menu/SideBar.tsx
+++ b/packages/merchant-backoffice-ui/src/components/menu/SideBar.tsx
@@ -31,6 +31,7 @@ const VERSION = typeof __VERSION__ !== "undefined" ? __VERSION__ : undefined;
interface Props {
onLogout: () => void;
+ onShowSettings: () => void;
mobile?: boolean;
instance: string;
admin?: boolean;
@@ -40,6 +41,7 @@ interface Props {
export function Sidebar({
mobile,
instance,
+ onShowSettings,
onLogout,
admin,
mimic,
@@ -78,21 +80,8 @@ export function Sidebar({
<div class="menu is-menu-main">
{instance ? (
<Fragment>
- <p class="menu-label">
- <i18n.Translate>Instance</i18n.Translate>
- </p>
<ul class="menu-list">
- <li>
- <a href={"/update"} class="has-icon">
- <span class="icon">
- <i class="mdi mdi-square-edit-outline" />
- </span>
- <span class="menu-item-label">
- <i18n.Translate>Settings</i18n.Translate>
- </span>
- </a>
- </li>
- <li>
+ <li>
<a href={"/orders"} class="has-icon">
<span class="icon">
<i class="mdi mdi-cash-register" />
@@ -132,6 +121,31 @@ export function Sidebar({
</span>
</a>
</li>
+ {needKYC && (
+ <li>
+ <a href={"/kyc"} class="has-icon">
+ <span class="icon">
+ <i class="mdi mdi-account-check" />
+ </span>
+ <span class="menu-item-label">KYC Status</span>
+ </a>
+ </li>
+ )}
+ </ul>
+ <p class="menu-label">
+ <i18n.Translate>Configuration</i18n.Translate>
+ </p>
+ <ul class="menu-list">
+ <li>
+ <a href={"/update"} class="has-icon">
+ <span class="icon">
+ <i class="mdi mdi-square-edit-outline" />
+ </span>
+ <span class="menu-item-label">
+ <i18n.Translate>Account</i18n.Translate>
+ </span>
+ </a>
+ </li>
<li>
<a href={"/reserves"} class="has-icon">
<span class="icon">
@@ -150,16 +164,6 @@ export function Sidebar({
</span>
</a>
</li>
- {needKYC && (
- <li>
- <a href={"/kyc"} class="has-icon">
- <span class="icon">
- <i class="mdi mdi-account-check" />
- </span>
- <span class="menu-item-label">KYC Status</span>
- </a>
- </li>
- )}
</ul>
</Fragment>
) : undefined}
@@ -168,6 +172,18 @@ export function Sidebar({
</p>
<ul class="menu-list">
<li>
+ <a class="has-icon is-state-info is-hoverable"
+ onClick={(): void => onShowSettings()}
+ >
+ <span class="icon">
+ <i class="mdi mdi-newspaper" />
+ </span>
+ <span class="menu-item-label">
+ <i18n.Translate>Settings</i18n.Translate>
+ </span>
+ </a>
+ </li>
+ <li>
<div>
<span style={{ width: "3rem" }} class="icon">
<i class="mdi mdi-currency-eur" />
diff --git a/packages/merchant-backoffice-ui/src/components/menu/index.tsx b/packages/merchant-backoffice-ui/src/components/menu/index.tsx
index 2beaf6956..cdbae4ae0 100644
--- a/packages/merchant-backoffice-ui/src/components/menu/index.tsx
+++ b/packages/merchant-backoffice-ui/src/components/menu/index.tsx
@@ -75,6 +75,7 @@ interface MenuProps {
instance: string;
admin?: boolean;
onLogout?: () => void;
+ onShowSettings: () => void;
setInstanceName: (s: string) => void;
}
@@ -93,6 +94,7 @@ function WithTitle({
export function Menu({
onLogout,
+ onShowSettings,
title,
instance,
path,
@@ -121,6 +123,7 @@ export function Menu({
{onLogout && (
<Sidebar
+ onShowSettings={onShowSettings}
onLogout={onLogout}
admin={admin}
mimic={mimic}
@@ -159,6 +162,7 @@ export function Menu({
interface NotYetReadyAppMenuProps {
title: string;
onLogout?: () => void;
+ onShowSettings: () => void;
}
interface NotifProps {
@@ -199,6 +203,7 @@ export function NotificationCard({
export function NotYetReadyAppMenu({
onLogout,
+ onShowSettings,
title,
}: NotYetReadyAppMenuProps): VNode {
const [mobileOpen, setMobileOpen] = useState(false);
@@ -217,7 +222,7 @@ export function NotYetReadyAppMenu({
title={title}
/>
{onLogout && (
- <Sidebar onLogout={onLogout} instance="" mobile={mobileOpen} />
+ <Sidebar onShowSettings={onShowSettings} onLogout={onLogout} instance="" mobile={mobileOpen} />
)}
</div>
);
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/orders/list/ListPage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/orders/list/ListPage.tsx
index 56d9dda74..37770d273 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/orders/list/ListPage.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/orders/list/ListPage.tsx
@@ -164,7 +164,7 @@ export function ListPage({
<div class="field has-addons">
{jumpToDate && (
<div class="control">
- <a class="button" onClick={() => onSelectDate(undefined)}>
+ <a class="button is-fullwidth" onClick={() => onSelectDate(undefined)}>
<span
class="icon"
data-tooltip={i18n.str`clear date filter`}
@@ -191,7 +191,7 @@ export function ListPage({
<div class="control">
<span class="has-tooltip-left" data-tooltip={dateTooltip}>
<a
- class="button"
+ class="button is-fullwidth"
onClick={() => {
setPickDate(true);
}}
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/templates/create/CreatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/templates/create/CreatePage.tsx
index 4dde202c4..e20b9bc27 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/templates/create/CreatePage.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/templates/create/CreatePage.tsx
@@ -85,34 +85,34 @@ export function CreatePage({ onCreate, onBack }: Props): VNode {
template_contract: !state.template_contract
? undefined
: undefinedIfEmpty({
- amount: !state.template_contract?.amount
- ? undefined
- : !parsedPrice
+ amount: !state.template_contract?.amount
+ ? undefined
+ : !parsedPrice
? i18n.str`not valid`
: Amounts.isZero(parsedPrice)
- ? i18n.str`must be greater than 0`
- : undefined,
- minimum_age:
- state.template_contract.minimum_age < 0
- ? i18n.str`should be greater that 0`
+ ? i18n.str`must be greater than 0`
: undefined,
- pay_duration: !state.template_contract.pay_duration
- ? i18n.str`can't be empty`
- : state.template_contract.pay_duration.d_us === "forever"
+ minimum_age:
+ state.template_contract.minimum_age < 0
+ ? i18n.str`should be greater that 0`
+ : undefined,
+ pay_duration: !state.template_contract.pay_duration
+ ? i18n.str`can't be empty`
+ : state.template_contract.pay_duration.d_us === "forever"
? undefined
: state.template_contract.pay_duration.d_us < 1000 * 1000 //less than one second
- ? i18n.str`to short`
- : undefined,
- } as Partial<MerchantTemplateContractDetails>),
+ ? i18n.str`to short`
+ : undefined,
+ } as Partial<MerchantTemplateContractDetails>),
pos_key: !state.pos_key
? !state.pos_algorithm
? undefined
: i18n.str`required`
: !isBase32RFC3548Charset(state.pos_key)
- ? i18n.str`just letters and numbers from 2 to 7`
- : state.pos_key.length !== 32
- ? i18n.str`size of the key should be 32`
- : undefined,
+ ? i18n.str`just letters and numbers from 2 to 7`
+ : state.pos_key.length !== 32
+ ? i18n.str`size of the key should be 32`
+ : undefined,
};
const hasErrors = Object.keys(errors).some(
@@ -139,7 +139,7 @@ export function CreatePage({ onCreate, onBack }: Props): VNode {
>
<InputWithAddon<Entity>
name="template_id"
- addonBefore={`${backend.url}/instances/templates/`}
+ help={`${backend.url}/instances/templates/${state.template_id ?? ""}`}
label={i18n.str`Identifier`}
tooltip={i18n.str`Name of the template in URLs.`}
/>
diff --git a/packages/merchant-backoffice-ui/src/paths/settings/index.tsx b/packages/merchant-backoffice-ui/src/paths/settings/index.tsx
new file mode 100644
index 000000000..1d0b4128a
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/paths/settings/index.tsx
@@ -0,0 +1,15 @@
+import { VNode, h } from "preact";
+
+export function Settings(): VNode {
+ return <div>
+ <section class="section is-main-section">
+ <div class="columns">
+ <div class="column" />
+ <div class="column is-four-fifths">
+ settings view
+ </div>
+ <div class="column" />
+ </div>
+ </section>
+ </div>
+} \ No newline at end of file