[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-merchant-backoffice] 02/04: -format with prettier
From: |
gnunet |
Subject: |
[taler-merchant-backoffice] 02/04: -format with prettier |
Date: |
Thu, 02 Dec 2021 19:25:43 +0100 |
This is an automated email from the git hooks/post-receive script.
sebasjm pushed a commit to branch master
in repository merchant-backoffice.
commit a8f51ec0f991bb6ea2b4171c4b3ec50a3dc7ac9b
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Thu Dec 2 15:07:25 2021 -0300
-format with prettier
---
.../merchant-backoffice/src/InstanceRoutes.tsx | 623 ++++++++++++---------
.../src/components/menu/index.tsx | 219 +++++---
packages/merchant-backoffice/src/utils/types.ts | 7 +-
3 files changed, 521 insertions(+), 328 deletions(-)
diff --git a/packages/merchant-backoffice/src/InstanceRoutes.tsx
b/packages/merchant-backoffice/src/InstanceRoutes.tsx
index 588cfb4..aaf8de4 100644
--- a/packages/merchant-backoffice/src/InstanceRoutes.tsx
+++ b/packages/merchant-backoffice/src/InstanceRoutes.tsx
@@ -15,327 +15,448 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
-import { Fragment, FunctionComponent, h, VNode } from 'preact';
-import { Route, route, Router } from 'preact-router';
+import { Fragment, FunctionComponent, h, VNode } from "preact";
+import { Route, route, Router } from "preact-router";
import { useCallback, useEffect, useMemo, useState } from "preact/hooks";
-import { Loading } from './components/exception/loading';
-import { NotificationCard } from './components/menu';
-import { useBackendContext } from './context/backend';
-import { InstanceContextProvider } from './context/instance';
-import { useBackendDefaultToken, useBackendInstanceToken } from './hooks';
+import { Loading } from "./components/exception/loading";
+import { NotificationCard } from "./components/menu";
+import { useBackendContext } from "./context/backend";
+import { InstanceContextProvider } from "./context/instance";
+import { useBackendDefaultToken, useBackendInstanceToken } from "./hooks";
import { HttpError } from "./hooks/backend";
-import { useTranslator } from './i18n';
+import { useTranslator } from "./i18n";
import InstanceCreatePage from "./paths/admin/create";
-import InstanceListPage from './paths/admin/list';
-import OrderCreatePage from './paths/instance/orders/create';
-import OrderDetailsPage from './paths/instance/orders/details';
-import OrderListPage from './paths/instance/orders/list';
-import ProductCreatePage from './paths/instance/products/create';
-import ProductListPage from './paths/instance/products/list';
-import ProductUpdatePage from './paths/instance/products/update';
-import TransferListPage from './paths/instance/transfers/list';
-import TransferCreatePage from './paths/instance/transfers/create';
-import ReservesCreatePage from './paths/instance/reserves/create';
-import ReservesDetailsPage from './paths/instance/reserves/details';
-import ReservesListPage from './paths/instance/reserves/list';
-import InstanceUpdatePage, { Props as InstanceUpdatePageProps, AdminUpdate as
InstanceAdminUpdatePage } from "./paths/instance/update";
-import LoginPage from './paths/login';
-import NotFoundPage from './paths/notfound';
-import { Notification } from './utils/types';
+import InstanceListPage from "./paths/admin/list";
+import OrderCreatePage from "./paths/instance/orders/create";
+import OrderDetailsPage from "./paths/instance/orders/details";
+import OrderListPage from "./paths/instance/orders/list";
+import ProductCreatePage from "./paths/instance/products/create";
+import ProductListPage from "./paths/instance/products/list";
+import ProductUpdatePage from "./paths/instance/products/update";
+import TransferListPage from "./paths/instance/transfers/list";
+import TransferCreatePage from "./paths/instance/transfers/create";
+import ReservesCreatePage from "./paths/instance/reserves/create";
+import ReservesDetailsPage from "./paths/instance/reserves/details";
+import ReservesListPage from "./paths/instance/reserves/list";
+import InstanceUpdatePage, {
+ Props as InstanceUpdatePageProps,
+ AdminUpdate as InstanceAdminUpdatePage,
+} from "./paths/instance/update";
+import LoginPage from "./paths/login";
+import NotFoundPage from "./paths/notfound";
+import { Notification } from "./utils/types";
export enum InstancePaths {
// details = '/',
- error = '/error',
- update = '/update',
+ error = "/error",
+ update = "/update",
- product_list = '/products',
- product_update = '/product/:pid/update',
- product_new = '/product/new',
+ product_list = "/products",
+ product_update = "/product/:pid/update",
+ product_new = "/product/new",
- order_list = '/orders',
- order_new = '/order/new',
- order_details = '/order/:oid/details',
+ order_list = "/orders",
+ order_new = "/order/new",
+ order_details = "/order/:oid/details",
- reserves_list = '/reserves',
- reserves_details = '/reserves/:rid/details',
- reserves_new = '/reserves/new',
+ reserves_list = "/reserves",
+ reserves_details = "/reserves/:rid/details",
+ reserves_new = "/reserves/new",
- transfers_list = '/transfers',
- transfers_new = '/transfer/new',
+ transfers_list = "/transfers",
+ transfers_new = "/transfer/new",
}
// eslint-disable-next-line @typescript-eslint/no-empty-function
-const noop = () => { }
+const noop = () => {};
export enum AdminPaths {
- list_instances = '/instances',
- new_instance = '/instance/new',
- update_instance = '/instance/:id/update',
+ list_instances = "/instances",
+ new_instance = "/instance/new",
+ update_instance = "/instance/:id/update",
}
export interface Props {
id: string;
admin?: boolean;
- setInstanceName: (s:string) => void
+ setInstanceName: (s: string) => void;
}
export function InstanceRoutes({ id, admin, setInstanceName }: Props): VNode {
- const [_, updateDefaultToken] = useBackendDefaultToken()
+ const [_, updateDefaultToken] = useBackendDefaultToken();
const [token, updateToken] = useBackendInstanceToken(id);
- const { updateLoginStatus: changeBackend, addTokenCleaner } =
useBackendContext();
- const cleaner = useCallback(() => { updateToken(undefined); }, [id]);
+ const { updateLoginStatus: changeBackend, addTokenCleaner } =
+ useBackendContext();
+ const cleaner = useCallback(() => {
+ updateToken(undefined);
+ }, [id]);
const i18n = useTranslator();
- const [globalNotification, setGlobalNotification] = useState<Notification &
{ to: string } | undefined>(undefined)
+ const [globalNotification, setGlobalNotification] = useState<
+ (Notification & { to: string }) | undefined
+ >(undefined);
useEffect(() => {
addTokenCleaner(cleaner);
}, [addTokenCleaner, cleaner]);
- const changeToken = (token?:string) => {
+ const changeToken = (token?: string) => {
if (admin) {
updateToken(token);
} else {
- updateDefaultToken(token)
+ updateDefaultToken(token);
}
- }
+ };
const updateLoginStatus = (url: string, token?: string) => {
changeBackend(url);
- if (!token) return
- changeToken(token)
+ if (!token) return;
+ changeToken(token);
};
- const value = useMemo(() => ({ id, token, admin, changeToken }), [id, token,
admin])
-
- const ServerErrorRedirectTo = (to: InstancePaths | AdminPaths) => (error:
HttpError) => {
- setGlobalNotification({
- message: i18n`The backend reported a problem: HTTP status
#${error.status}`,
- description: i18n`Diagnostic from ${error.info?.url} is
"${error.message}"`,
- type: 'ERROR',
- to
- })
- return <Redirect to={to} />
- }
-
- const LoginPageAccessDenied = () => <Fragment>
- <NotificationCard notification={{ message: i18n`Access denied`,
description: i18n`The access token provided is invalid.`, type: 'ERROR', }} />
- <LoginPage onConfirm={updateLoginStatus} />
- </Fragment>
+ const value = useMemo(
+ () => ({ id, token, admin, changeToken }),
+ [id, token, admin]
+ );
+
+ const ServerErrorRedirectTo =
+ (to: InstancePaths | AdminPaths) => (error: HttpError) => {
+ setGlobalNotification({
+ message: i18n`The backend reported a problem: HTTP status
#${error.status}`,
+ description: i18n`Diagnostic from ${error.info?.url} is
"${error.message}"`,
+ type: "ERROR",
+ to,
+ });
+ return <Redirect to={to} />;
+ };
+
+ const LoginPageAccessDenied = () => (
+ <Fragment>
+ <NotificationCard
+ notification={{
+ message: i18n`Access denied`,
+ description: i18n`The access token provided is invalid.`,
+ type: "ERROR",
+ }}
+ />
+ <LoginPage onConfirm={updateLoginStatus} />
+ </Fragment>
+ );
function IfAdminCreateDefaultOr<T>(Next: FunctionComponent<any>) {
return function IfAdminCreateDefaultOrImpl(props?: T) {
- if (admin && id === 'default') {
- return <Fragment>
- <NotificationCard notification={{
- message: i18n`No 'default' instance configured yet.`,
- description: i18n`Create a 'default' instance to begin using the
merchant backoffice.`,
- type: 'INFO'
- }} />
- <InstanceCreatePage forceId="default" onConfirm={() => {
- route(AdminPaths.list_instances)
- }} />
- </Fragment>
+ if (admin && id === "default") {
+ return (
+ <Fragment>
+ <NotificationCard
+ notification={{
+ message: i18n`No 'default' instance configured yet.`,
+ description: i18n`Create a 'default' instance to begin using
the merchant backoffice.`,
+ type: "INFO",
+ }}
+ />
+ <InstanceCreatePage
+ forceId="default"
+ onConfirm={() => {
+ route(AdminPaths.list_instances);
+ }}
+ />
+ </Fragment>
+ );
}
if (props) {
- return <Next {...props} />
+ return <Next {...props} />;
}
- return <Next />
-
- }
+ return <Next />;
+ };
}
- return <InstanceContextProvider value={value}>
-
- <NotificationCard notification={globalNotification} />
-
- <Router onChange={(e) => {
- const movingOutFromNotification = globalNotification && e.url !==
globalNotification.to
- if (movingOutFromNotification) {
- setGlobalNotification(undefined)
- }
- }} >
-
- <Route path="/" component={Redirect} to={InstancePaths.order_list} />
-
- {/**
- * Admin pages
- */}
- {admin &&
- <Route path={AdminPaths.list_instances} component={InstanceListPage}
- onCreate={() => { route(AdminPaths.new_instance) }}
- onUpdate={(id: string): void => { route(`/instance/${id}/update`); }}
- setInstanceName={setInstanceName}
+ return (
+ <InstanceContextProvider value={value}>
+ <NotificationCard notification={globalNotification} />
+
+ <Router
+ onChange={(e) => {
+ const movingOutFromNotification =
+ globalNotification && e.url !== globalNotification.to;
+ if (movingOutFromNotification) {
+ setGlobalNotification(undefined);
+ }
+ }}
+ >
+ <Route path="/" component={Redirect} to={InstancePaths.order_list} />
+
+ {/**
+ * Admin pages
+ */}
+ {admin && (
+ <Route
+ path={AdminPaths.list_instances}
+ component={InstanceListPage}
+ onCreate={() => {
+ route(AdminPaths.new_instance);
+ }}
+ onUpdate={(id: string): void => {
+ route(`/instance/${id}/update`);
+ }}
+ setInstanceName={setInstanceName}
+ onUnauthorized={LoginPageAccessDenied}
+ onLoadError={ServerErrorRedirectTo(InstancePaths.error)}
+ />
+ )}
+
+ {admin && (
+ <Route
+ path={AdminPaths.new_instance}
+ component={InstanceCreatePage}
+ onBack={() => route(AdminPaths.list_instances)}
+ onConfirm={() => {
+ route(AdminPaths.list_instances);
+ }}
+ />
+ )}
+
+ {admin && (
+ <Route
+ path={AdminPaths.update_instance}
+ component={AdminInstanceUpdatePage}
+ onBack={() => route(AdminPaths.list_instances)}
+ onConfirm={() => {
+ route(AdminPaths.list_instances);
+ }}
+ onUpdateError={ServerErrorRedirectTo(AdminPaths.list_instances)}
+ onLoadError={ServerErrorRedirectTo(AdminPaths.list_instances)}
+ onNotFound={NotFoundPage}
+ />
+ )}
+
+ {/**
+ * Update instance page
+ */}
+ <Route
+ path={InstancePaths.update}
+ component={InstanceUpdatePage}
+ onBack={() => {
+ route(`/`);
+ }}
+ onConfirm={() => {
+ route(`/`);
+ }}
+ onUpdateError={noop}
+ onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
onUnauthorized={LoginPageAccessDenied}
onLoadError={ServerErrorRedirectTo(InstancePaths.error)}
/>
- }
- {admin &&
- <Route path={AdminPaths.new_instance} component={InstanceCreatePage}
- onBack={() => route(AdminPaths.list_instances)}
- onConfirm={() => { route(AdminPaths.list_instances); }}
+ {/**
+ * Product pages
+ */}
+ <Route
+ path={InstancePaths.product_list}
+ component={ProductListPage}
+ onUnauthorized={LoginPageAccessDenied}
+ onLoadError={ServerErrorRedirectTo(InstancePaths.update)}
+ onCreate={() => {
+ route(InstancePaths.product_new);
+ }}
+ onSelect={(id: string) => {
+ route(InstancePaths.product_update.replace(":pid", id));
+ }}
+ onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
/>
- }
-
- {admin &&
- <Route path={AdminPaths.update_instance}
component={AdminInstanceUpdatePage}
- onBack={() => route(AdminPaths.list_instances)}
- onConfirm={() => { route(AdminPaths.list_instances); }}
- onUpdateError={ServerErrorRedirectTo(AdminPaths.list_instances)}
- onLoadError={ServerErrorRedirectTo(AdminPaths.list_instances)}
- onNotFound={NotFoundPage}
+ <Route
+ path={InstancePaths.product_update}
+ component={ProductUpdatePage}
+ onUnauthorized={LoginPageAccessDenied}
+ onLoadError={ServerErrorRedirectTo(InstancePaths.product_list)}
+ onConfirm={() => {
+ route(InstancePaths.product_list);
+ }}
+ onBack={() => {
+ route(InstancePaths.product_list);
+ }}
+ onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
+ />
+ <Route
+ path={InstancePaths.product_new}
+ component={ProductCreatePage}
+ onConfirm={() => {
+ route(InstancePaths.product_list);
+ }}
+ onBack={() => {
+ route(InstancePaths.product_list);
+ }}
/>
- }
-
- {/**
- * Update instance page
- */}
- <Route path={InstancePaths.update} component={InstanceUpdatePage}
- onBack={() => { route(`/`); }}
- onConfirm={() => { route(`/`); }}
- onUpdateError={noop}
- onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
- onUnauthorized={LoginPageAccessDenied}
- onLoadError={ServerErrorRedirectTo(InstancePaths.error)}
- />
-
- {/**
- * Product pages
- */}
- <Route path={InstancePaths.product_list} component={ProductListPage}
- onUnauthorized={LoginPageAccessDenied}
- onLoadError={ServerErrorRedirectTo(InstancePaths.update)}
- onCreate={() => { route(InstancePaths.product_new) }}
- onSelect={(id: string) => {
route(InstancePaths.product_update.replace(':pid', id)) }}
- onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
- />
- <Route path={InstancePaths.product_update} component={ProductUpdatePage}
- onUnauthorized={LoginPageAccessDenied}
- onLoadError={ServerErrorRedirectTo(InstancePaths.product_list)}
- onConfirm={() => { route(InstancePaths.product_list); }}
- onBack={() => { route(InstancePaths.product_list); }}
- onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
- />
- <Route path={InstancePaths.product_new}
- component={ProductCreatePage}
- onConfirm={() => { route(InstancePaths.product_list); }}
- onBack={() => { route(InstancePaths.product_list); }}
- />
-
- {/**
- * Order pages
- */}
- <Route path={InstancePaths.order_list} component={OrderListPage}
- onCreate={() => { route(InstancePaths.order_new) }}
- onSelect={(id: string) => {
route(InstancePaths.order_details.replace(':oid', id)) }}
- onUnauthorized={LoginPageAccessDenied}
- onLoadError={ServerErrorRedirectTo(InstancePaths.update)}
- onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
- />
- <Route path={InstancePaths.order_details} component={OrderDetailsPage}
- onUnauthorized={LoginPageAccessDenied}
- onLoadError={ServerErrorRedirectTo(InstancePaths.order_list)}
- onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
- onBack={() => { route(InstancePaths.order_list) }}
- />
- <Route path={InstancePaths.order_new} component={OrderCreatePage}
- onConfirm={() => { route(InstancePaths.order_list) }}
- onBack={() => { route(InstancePaths.order_list) }}
- />
- {/**
- * Transfer pages
- */}
- <Route path={InstancePaths.transfers_list} component={TransferListPage}
- onUnauthorized={LoginPageAccessDenied}
- onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
- onLoadError={ServerErrorRedirectTo(InstancePaths.update)}
- onCreate={() => { route(InstancePaths.transfers_new) }}
- />
+ {/**
+ * Order pages
+ */}
+ <Route
+ path={InstancePaths.order_list}
+ component={OrderListPage}
+ onCreate={() => {
+ route(InstancePaths.order_new);
+ }}
+ onSelect={(id: string) => {
+ route(InstancePaths.order_details.replace(":oid", id));
+ }}
+ onUnauthorized={LoginPageAccessDenied}
+ onLoadError={ServerErrorRedirectTo(InstancePaths.update)}
+ onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
+ />
+ <Route
+ path={InstancePaths.order_details}
+ component={OrderDetailsPage}
+ onUnauthorized={LoginPageAccessDenied}
+ onLoadError={ServerErrorRedirectTo(InstancePaths.order_list)}
+ onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
+ onBack={() => {
+ route(InstancePaths.order_list);
+ }}
+ />
+ <Route
+ path={InstancePaths.order_new}
+ component={OrderCreatePage}
+ onConfirm={() => {
+ route(InstancePaths.order_list);
+ }}
+ onBack={() => {
+ route(InstancePaths.order_list);
+ }}
+ />
- <Route path={InstancePaths.transfers_new} component={TransferCreatePage}
- onConfirm={() => { route(InstancePaths.transfers_list) }}
- onBack={() => { route(InstancePaths.transfers_list) }}
- />
+ {/**
+ * Transfer pages
+ */}
+ <Route
+ path={InstancePaths.transfers_list}
+ component={TransferListPage}
+ onUnauthorized={LoginPageAccessDenied}
+ onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
+ onLoadError={ServerErrorRedirectTo(InstancePaths.update)}
+ onCreate={() => {
+ route(InstancePaths.transfers_new);
+ }}
+ />
- {/**
- * reserves pages
- */}
- <Route path={InstancePaths.reserves_list} component={ReservesListPage}
- onUnauthorized={LoginPageAccessDenied}
- onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
- onLoadError={ServerErrorRedirectTo(InstancePaths.update)}
- onSelect={(id: string) => {
route(InstancePaths.reserves_details.replace(':rid', id)) }}
- onCreate={() => { route(InstancePaths.reserves_new) }}
- />
+ <Route
+ path={InstancePaths.transfers_new}
+ component={TransferCreatePage}
+ onConfirm={() => {
+ route(InstancePaths.transfers_list);
+ }}
+ onBack={() => {
+ route(InstancePaths.transfers_list);
+ }}
+ />
- <Route path={InstancePaths.reserves_details}
component={ReservesDetailsPage}
- onUnauthorized={LoginPageAccessDenied}
- onLoadError={ServerErrorRedirectTo(InstancePaths.reserves_list)}
- onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
- onBack={() => { route(InstancePaths.reserves_list) }}
- />
+ {/**
+ * reserves pages
+ */}
+ <Route
+ path={InstancePaths.reserves_list}
+ component={ReservesListPage}
+ onUnauthorized={LoginPageAccessDenied}
+ onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
+ onLoadError={ServerErrorRedirectTo(InstancePaths.update)}
+ onSelect={(id: string) => {
+ route(InstancePaths.reserves_details.replace(":rid", id));
+ }}
+ onCreate={() => {
+ route(InstancePaths.reserves_new);
+ }}
+ />
- <Route path={InstancePaths.reserves_new} component={ReservesCreatePage}
- onConfirm={() => { route(InstancePaths.reserves_list) }}
- onBack={() => { route(InstancePaths.reserves_list) }}
- />
- {/**
- * Example pages
- */}
- <Route path="/loading" component={Loading} />
- <Route default component={NotFoundPage} />
- </Router>
- </InstanceContextProvider>;
+ <Route
+ path={InstancePaths.reserves_details}
+ component={ReservesDetailsPage}
+ onUnauthorized={LoginPageAccessDenied}
+ onLoadError={ServerErrorRedirectTo(InstancePaths.reserves_list)}
+ onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
+ onBack={() => {
+ route(InstancePaths.reserves_list);
+ }}
+ />
+ <Route
+ path={InstancePaths.reserves_new}
+ component={ReservesCreatePage}
+ onConfirm={() => {
+ route(InstancePaths.reserves_list);
+ }}
+ onBack={() => {
+ route(InstancePaths.reserves_list);
+ }}
+ />
+ {/**
+ * Example pages
+ */}
+ <Route path="/loading" component={Loading} />
+ <Route default component={NotFoundPage} />
+ </Router>
+ </InstanceContextProvider>
+ );
}
export function Redirect({ to }: { to: string }): null {
useEffect(() => {
- route(to, true)
- })
- return null
+ route(to, true);
+ });
+ return null;
}
-function AdminInstanceUpdatePage({ id, ...rest }: { id: string } &
InstanceUpdatePageProps) {
+function AdminInstanceUpdatePage({
+ id,
+ ...rest
+}: { id: string } & InstanceUpdatePageProps) {
const [token, changeToken] = useBackendInstanceToken(id);
const { updateLoginStatus: changeBackend } = useBackendContext();
const updateLoginStatus = (url: string, token?: string) => {
changeBackend(url);
- if (token)
- changeToken(token);
+ if (token) changeToken(token);
};
- const value = useMemo(() => ({ id, token, admin: true, changeToken }), [id,
token])
+ const value = useMemo(
+ () => ({ id, token, admin: true, changeToken }),
+ [id, token]
+ );
const i18n = useTranslator();
- return <InstanceContextProvider value={value}>
- <InstanceAdminUpdatePage {...rest}
- instanceId={id}
- onLoadError={(error: HttpError) => {
- return <Fragment>
- <NotificationCard notification={{
- message: i18n`The backend reported a problem: HTTP status
#${error.status}`,
- description: i18n`Diagnostic from ${error.info?.url} is
"${error.message}"`,
- type: 'ERROR'
- }} />
- <LoginPage onConfirm={updateLoginStatus} />
- </Fragment>
- }}
-
- onUnauthorized={() => {
- return <Fragment>
- <NotificationCard notification={{
- message: i18n`Access denied`,
- description: i18n`The access token provided is invalid`,
- type: 'ERROR',
- }} />
- <LoginPage onConfirm={updateLoginStatus} />
- </Fragment>
- }}
-
- />
- </InstanceContextProvider>
+ return (
+ <InstanceContextProvider value={value}>
+ <InstanceAdminUpdatePage
+ {...rest}
+ instanceId={id}
+ onLoadError={(error: HttpError) => {
+ return (
+ <Fragment>
+ <NotificationCard
+ notification={{
+ message: i18n`The backend reported a problem: HTTP status
#${error.status}`,
+ description: i18n`Diagnostic from ${error.info?.url} is
"${error.message}"`,
+ type: "ERROR",
+ }}
+ />
+ <LoginPage onConfirm={updateLoginStatus} />
+ </Fragment>
+ );
+ }}
+ onUnauthorized={() => {
+ return (
+ <Fragment>
+ <NotificationCard
+ notification={{
+ message: i18n`Access denied`,
+ description: i18n`The access token provided is invalid`,
+ type: "ERROR",
+ }}
+ />
+ <LoginPage onConfirm={updateLoginStatus} />
+ </Fragment>
+ );
+ }}
+ />
+ </InstanceContextProvider>
+ );
}
diff --git a/packages/merchant-backoffice/src/components/menu/index.tsx
b/packages/merchant-backoffice/src/components/menu/index.tsx
index fcba281..0bf9412 100644
--- a/packages/merchant-backoffice/src/components/menu/index.tsx
+++ b/packages/merchant-backoffice/src/components/menu/index.tsx
@@ -15,7 +15,7 @@
*/
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 { AdminPaths } from "../../AdminRoutes";
import { InstancePaths } from "../../InstanceRoutes";
@@ -23,28 +23,37 @@ import { Notification } from "../../utils/types";
import { NavigationBar } from "./NavigationBar";
import { Sidebar } from "./SideBar";
-
function getInstanceTitle(path: string, id: string): string {
-
switch (path) {
- case InstancePaths.update: return `${id}: Settings`
- case InstancePaths.order_list: return `${id}: Orders`
- case InstancePaths.order_new: return `${id}: New order`
- case InstancePaths.product_list: return `${id}: Products`
- case InstancePaths.product_new: return `${id}: New product`
- case InstancePaths.product_update: return `${id}: Update product`
- case InstancePaths.reserves_new: return `${id}: New reserve`
- case InstancePaths.reserves_list: return `${id}: Reserves`
- case InstancePaths.transfers_list: return `${id}: Transfers`
- case InstancePaths.transfers_new: return `${id}: New transfer`
- default: return '';
+ case InstancePaths.update:
+ return `${id}: Settings`;
+ case InstancePaths.order_list:
+ return `${id}: Orders`;
+ case InstancePaths.order_new:
+ return `${id}: New order`;
+ case InstancePaths.product_list:
+ return `${id}: Products`;
+ case InstancePaths.product_new:
+ return `${id}: New product`;
+ case InstancePaths.product_update:
+ return `${id}: Update product`;
+ case InstancePaths.reserves_new:
+ return `${id}: New reserve`;
+ case InstancePaths.reserves_list:
+ return `${id}: Reserves`;
+ case InstancePaths.transfers_list:
+ return `${id}: Transfers`;
+ case InstancePaths.transfers_new:
+ return `${id}: New transfer`;
+ default:
+ return "";
}
}
function getAdminTitle(path: string, instance: string) {
- if (path === AdminPaths.new_instance) return `New instance`
- if (path === AdminPaths.list_instances) return `Instances`
- return getInstanceTitle(path, instance)
+ if (path === AdminPaths.new_instance) return `New instance`;
+ if (path === AdminPaths.list_instances) return `Instances`;
+ return getInstanceTitle(path, instance);
}
interface MenuProps {
@@ -52,41 +61,85 @@ interface MenuProps {
instance: string;
admin?: boolean;
onLogout?: () => void;
- setInstanceName: (s:string) => void;
+ setInstanceName: (s: string) => void;
}
-function WithTitle({ title, children }: { title: string, children:
ComponentChildren }): VNode {
+function WithTitle({
+ title,
+ children,
+}: {
+ title: string;
+ children: ComponentChildren;
+}): VNode {
useEffect(() => {
- document.title = `Taler Backoffice: ${title}`
- }, [title])
- return <Fragment>{children}</Fragment>
+ document.title = `Taler Backoffice: ${title}`;
+ }, [title]);
+ return <Fragment>{children}</Fragment>;
}
-export function Menu({ onLogout, title, instance, admin, setInstanceName }:
MenuProps): VNode {
- const [mobileOpen, setMobileOpen] = useState(false)
-
- return <Match>{({ path }: any) => {
- const titleWithSubtitle = title ? title : (!admin ? getInstanceTitle(path,
instance) : getAdminTitle(path, instance))
- const adminInstance = instance === "default"
- const mimic = admin && !adminInstance
- return (<WithTitle title={titleWithSubtitle}>
- <div class={mobileOpen ? "has-aside-mobile-expanded" : ""} onClick={()
=> setMobileOpen(false)}>
- <NavigationBar onMobileMenu={() => setMobileOpen(!mobileOpen)}
title={titleWithSubtitle} />
-
- {onLogout && <Sidebar onLogout={onLogout} admin={admin} mimic={mimic}
instance={instance} mobile={mobileOpen} />}
-
- {mimic && <nav class="level">
- <div class="level-item has-text-centered has-background-warning">
- <p class="is-size-5">You are viewing the instance
<b>"{instance}"</b>. <a href="#/instances" onClick={(e) => {
- setInstanceName('default')
- }}>go back</a></p>
- </div>
- </nav>}
- </div>
- </WithTitle>
- )
- }}</Match>
-
+export function Menu({
+ onLogout,
+ title,
+ instance,
+ admin,
+ setInstanceName,
+}: MenuProps): VNode {
+ const [mobileOpen, setMobileOpen] = useState(false);
+
+ return (
+ <Match>
+ {({ path }: any) => {
+ const titleWithSubtitle = title
+ ? title
+ : !admin
+ ? getInstanceTitle(path, instance)
+ : getAdminTitle(path, instance);
+ const adminInstance = instance === "default";
+ const mimic = admin && !adminInstance;
+ return (
+ <WithTitle title={titleWithSubtitle}>
+ <div
+ class={mobileOpen ? "has-aside-mobile-expanded" : ""}
+ onClick={() => setMobileOpen(false)}
+ >
+ <NavigationBar
+ onMobileMenu={() => setMobileOpen(!mobileOpen)}
+ title={titleWithSubtitle}
+ />
+
+ {onLogout && (
+ <Sidebar
+ onLogout={onLogout}
+ admin={admin}
+ mimic={mimic}
+ instance={instance}
+ mobile={mobileOpen}
+ />
+ )}
+
+ {mimic && (
+ <nav class="level">
+ <div class="level-item has-text-centered
has-background-warning">
+ <p class="is-size-5">
+ You are viewing the instance <b>"{instance}"</b>.{" "}
+ <a
+ href="#/instances"
+ onClick={(e) => {
+ setInstanceName("default");
+ }}
+ >
+ go back
+ </a>
+ </p>
+ </div>
+ </nav>
+ )}
+ </div>
+ </WithTitle>
+ );
+ }}
+ </Match>
+ );
}
interface NotYetReadyAppMenuProps {
@@ -97,36 +150,56 @@ interface NotYetReadyAppMenuProps {
interface NotifProps {
notification?: Notification;
}
-export function NotificationCard({ notification: n }: NotifProps): VNode |
null {
- if (!n) return null
- return <div class="notification">
- <div class="columns is-vcentered">
- <div class="column is-12">
- <article class={n.type === 'ERROR' ? "message is-danger" : (n.type ===
'WARN' ? "message is-warning" : "message is-info")}>
- <div class="message-header">
- <p>{n.message}</p>
- </div>
- {n.description &&
- <div class="message-body">
- {n.description}
- </div>}
- </article>
+export function NotificationCard({
+ notification: n,
+}: NotifProps): VNode | null {
+ if (!n) return null;
+ return (
+ <div class="notification">
+ <div class="columns is-vcentered">
+ <div class="column is-12">
+ <article
+ class={
+ n.type === "ERROR"
+ ? "message is-danger"
+ : n.type === "WARN"
+ ? "message is-warning"
+ : "message is-info"
+ }
+ >
+ <div class="message-header">
+ <p>{n.message}</p>
+ </div>
+ {n.description && <div class="message-body">{n.description}</div>}
+ </article>
+ </div>
</div>
</div>
- </div>
+ );
}
-export function NotYetReadyAppMenu({ onLogout, title }:
NotYetReadyAppMenuProps): VNode {
- const [mobileOpen, setMobileOpen] = useState(false)
+export function NotYetReadyAppMenu({
+ onLogout,
+ title,
+}: NotYetReadyAppMenuProps): VNode {
+ const [mobileOpen, setMobileOpen] = useState(false);
useEffect(() => {
- document.title = `Taler Backoffice: ${title}`
- }, [title])
-
- return <div class={mobileOpen ? "has-aside-mobile-expanded" : ""}
onClick={() => setMobileOpen(false)}>
- <NavigationBar onMobileMenu={() => setMobileOpen(!mobileOpen)}
title={title} />
- {onLogout && <Sidebar onLogout={onLogout} instance="" mobile={mobileOpen}
/>}
- </div>
-
+ document.title = `Taler Backoffice: ${title}`;
+ }, [title]);
+
+ return (
+ <div
+ class={mobileOpen ? "has-aside-mobile-expanded" : ""}
+ onClick={() => setMobileOpen(false)}
+ >
+ <NavigationBar
+ onMobileMenu={() => setMobileOpen(!mobileOpen)}
+ title={title}
+ />
+ {onLogout && (
+ <Sidebar onLogout={onLogout} instance="" mobile={mobileOpen} />
+ )}
+ </div>
+ );
}
-
diff --git a/packages/merchant-backoffice/src/utils/types.ts
b/packages/merchant-backoffice/src/utils/types.ts
index 9e49d39..8e54c44 100644
--- a/packages/merchant-backoffice/src/utils/types.ts
+++ b/packages/merchant-backoffice/src/utils/types.ts
@@ -14,7 +14,7 @@
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
-import { VNode } from "preact"
+import { VNode } from "preact";
export interface KeyValue {
[key: string]: string;
@@ -26,6 +26,5 @@ export interface Notification {
type: MessageType;
}
-export type ValueOrFunction<T> = T | ((p: T) => T)
-export type MessageType = 'INFO' | 'WARN' | 'ERROR' | 'SUCCESS'
-
+export type ValueOrFunction<T> = T | ((p: T) => T);
+export type MessageType = "INFO" | "WARN" | "ERROR" | "SUCCESS";
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.