summaryrefslogtreecommitdiff
path: root/packages/merchant-backoffice-ui/src/components/menu/SideBar.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'packages/merchant-backoffice-ui/src/components/menu/SideBar.tsx')
-rw-r--r--packages/merchant-backoffice-ui/src/components/menu/SideBar.tsx268
1 files changed, 268 insertions, 0 deletions
diff --git a/packages/merchant-backoffice-ui/src/components/menu/SideBar.tsx b/packages/merchant-backoffice-ui/src/components/menu/SideBar.tsx
new file mode 100644
index 000000000..2090704d9
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/menu/SideBar.tsx
@@ -0,0 +1,268 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021-2024 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/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { TalerError } from "@gnu-taler/taler-util";
+import { useTranslationContext } from "@gnu-taler/web-util/browser";
+import { Fragment, VNode, h } from "preact";
+import { useSessionContext } from "../../context/session.js";
+import { useInstanceKYCDetails } from "../../hooks/instance.js";
+import { LangSelector } from "./LangSelector.js";
+
+// const GIT_HASH = typeof __GIT_HASH__ !== "undefined" ? __GIT_HASH__ : undefined;
+const VERSION = typeof __VERSION__ !== "undefined" ? __VERSION__ : undefined;
+
+interface Props {
+ mobile?: boolean;
+}
+
+export function Sidebar({ mobile }: Props): VNode {
+ const { i18n } = useTranslationContext();
+ const { state, logOut, config } = useSessionContext();
+ const kycStatus = useInstanceKYCDetails();
+
+ const needKYC =
+ kycStatus !== undefined &&
+ !(kycStatus instanceof TalerError) &&
+ kycStatus.type === "ok" &&
+ !!kycStatus.body;
+ const isLoggedIn = state.status === "loggedIn";
+ const hasToken = isLoggedIn && state.token !== undefined;
+
+ return (
+ <aside
+ class="aside is-placed-left is-expanded"
+ style={{ overflowY: "scroll" }}
+ >
+ {mobile && (
+ <div
+ class="footer"
+ onClick={(e) => {
+ return e.stopImmediatePropagation();
+ }}
+ >
+ <LangSelector />
+ </div>
+ )}
+ <div class="aside-tools">
+ <div class="aside-tools-label">
+ <div>
+ <b>Taler</b> Backoffice
+ </div>
+ <div
+ class="is-size-7 has-text-right"
+ style={{ lineHeight: 0, marginTop: -10 }}
+ >
+ {VERSION} ({config.version})
+ </div>
+ </div>
+ </div>
+ <div class="menu is-menu-main">
+ {isLoggedIn ? (
+ <Fragment>
+ <ul class="menu-list">
+ <li>
+ <a href={"/orders"} class="has-icon">
+ <span class="icon">
+ <i class="mdi mdi-cash-register" />
+ </span>
+ <span class="menu-item-label">
+ <i18n.Translate>Orders</i18n.Translate>
+ </span>
+ </a>
+ </li>
+ <li>
+ <a href={"/inventory"} class="has-icon">
+ <span class="icon">
+ <i class="mdi mdi-shopping" />
+ </span>
+ <span class="menu-item-label">
+ <i18n.Translate>Inventory</i18n.Translate>
+ </span>
+ </a>
+ </li>
+ <li>
+ <a href={"/transfers"} class="has-icon">
+ <span class="icon">
+ <i class="mdi mdi-arrow-left-right" />
+ </span>
+ <span class="menu-item-label">
+ <i18n.Translate>Transfers</i18n.Translate>
+ </span>
+ </a>
+ </li>
+ <li>
+ <a href={"/templates"} class="has-icon">
+ <span class="icon">
+ <i class="mdi mdi-newspaper" />
+ </span>
+ <span class="menu-item-label">
+ <i18n.Translate>Templates</i18n.Translate>
+ </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={"/bank"} class="has-icon">
+ <span class="icon">
+ <i class="mdi mdi-bank" />
+ </span>
+ <span class="menu-item-label">
+ <i18n.Translate>Bank account</i18n.Translate>
+ </span>
+ </a>
+ </li>
+ <li>
+ <a href={"/otp-devices"} class="has-icon">
+ <span class="icon">
+ <i class="mdi mdi-lock" />
+ </span>
+ <span class="menu-item-label">
+ <i18n.Translate>OTP Devices</i18n.Translate>
+ </span>
+ </a>
+ </li>
+ <li>
+ <a href={"/webhooks"} class="has-icon">
+ <span class="icon">
+ <i class="mdi mdi-newspaper" />
+ </span>
+ <span class="menu-item-label">
+ <i18n.Translate>Webhooks</i18n.Translate>
+ </span>
+ </a>
+ </li>
+ <li>
+ <a href={"/settings"} 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>
+ <a href={"/token"} class="has-icon">
+ <span class="icon">
+ <i class="mdi mdi-security" />
+ </span>
+ <span class="menu-item-label">
+ <i18n.Translate>Access token</i18n.Translate>
+ </span>
+ </a>
+ </li>
+ </ul>
+ </Fragment>
+ ) : undefined}
+ <p class="menu-label">
+ <i18n.Translate>Connection</i18n.Translate>
+ </p>
+ <ul class="menu-list">
+ <li>
+ <a class="has-icon is-state-info is-hoverable" href="/interface">
+ <span class="icon">
+ <i class="mdi mdi-newspaper" />
+ </span>
+ <span class="menu-item-label">
+ <i18n.Translate>Interface</i18n.Translate>
+ </span>
+ </a>
+ </li>
+ <li>
+ <div>
+ <span style={{ width: "3rem" }} class="icon">
+ <i class="mdi mdi-web" />
+ </span>
+ <span class="menu-item-label">{state.backendUrl.hostname}</span>
+ </div>
+ </li>
+ <li>
+ <div>
+ <span style={{ width: "3rem" }} class="icon">
+ ID
+ </span>
+ <span class="menu-item-label">{state.instance}</span>
+ </div>
+ </li>
+ {state.isAdmin && (
+ <Fragment>
+ <p class="menu-label">
+ <i18n.Translate>Instances</i18n.Translate>
+ </p>
+ <li>
+ <a href={"/instance/new"} class="has-icon">
+ <span class="icon">
+ <i class="mdi mdi-plus" />
+ </span>
+ <span class="menu-item-label">
+ <i18n.Translate>New</i18n.Translate>
+ </span>
+ </a>
+ </li>
+ <li>
+ <a href={"/instances"} class="has-icon">
+ <span class="icon">
+ <i class="mdi mdi-format-list-bulleted" />
+ </span>
+ <span class="menu-item-label">
+ <i18n.Translate>List</i18n.Translate>
+ </span>
+ </a>
+ </li>
+ </Fragment>
+ )}
+ {hasToken ? (
+ <li>
+ <a
+ class="has-icon is-state-info is-hoverable"
+ onClick={(e): void => {
+ logOut();
+ e.preventDefault();
+ }}
+ >
+ <span class="icon">
+ <i class="mdi mdi-logout default" />
+ </span>
+ <span class="menu-item-label">
+ <i18n.Translate>Log out</i18n.Translate>
+ </span>
+ </a>
+ </li>
+ ) : undefined}
+ </ul>
+ </div>
+ </aside>
+ );
+}