summaryrefslogtreecommitdiff
path: root/packages/bank-ui/src/pages/ProfileNavigation.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'packages/bank-ui/src/pages/ProfileNavigation.tsx')
-rw-r--r--packages/bank-ui/src/pages/ProfileNavigation.tsx202
1 files changed, 202 insertions, 0 deletions
diff --git a/packages/bank-ui/src/pages/ProfileNavigation.tsx b/packages/bank-ui/src/pages/ProfileNavigation.tsx
new file mode 100644
index 000000000..3e81e307c
--- /dev/null
+++ b/packages/bank-ui/src/pages/ProfileNavigation.tsx
@@ -0,0 +1,202 @@
+/*
+ This file is part of GNU Taler
+ (C) 2022-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/>
+ */
+import { assertUnreachable } from "@gnu-taler/taler-util";
+import {
+ useNavigationContext,
+ useTranslationContext,
+} from "@gnu-taler/web-util/browser";
+import { Fragment, VNode, h } from "preact";
+import { useBankCoreApiContext } from "@gnu-taler/web-util/browser";
+import { useSessionState } from "../hooks/session.js";
+import { RouteDefinition } from "@gnu-taler/web-util/browser";
+
+export function ProfileNavigation({
+ current,
+ routeMyAccountCashout,
+ routeMyAccountDelete,
+ routeMyAccountDetails,
+ routeMyAccountPassword,
+ routeConversionConfig,
+}: {
+ current: "details" | "delete" | "credentials" | "cashouts" | "conversion";
+ routeMyAccountDetails: RouteDefinition;
+ routeMyAccountDelete: RouteDefinition;
+ routeMyAccountPassword: RouteDefinition;
+ routeMyAccountCashout: RouteDefinition;
+ routeConversionConfig: RouteDefinition;
+}): VNode {
+ const { i18n } = useTranslationContext();
+ const { config } = useBankCoreApiContext();
+ const { state: credentials } = useSessionState();
+ const isAdminUser =
+ credentials.status !== "loggedIn" ? false : credentials.isUserAdministrator;
+ const nonAdminUser = !isAdminUser;
+
+ const { navigateTo } = useNavigationContext();
+ return (
+ <div>
+ <div class="sm:hidden">
+ <label for="tabs" class="sr-only">
+ <i18n.Translate>Select a section</i18n.Translate>
+ </label>
+ <select
+ id="tabs"
+ name="tabs"
+ class="block w-full rounded-md border-gray-300 focus:border-indigo-500 focus:ring-indigo-500"
+ onChange={(e) => {
+ const op = e.currentTarget.value as typeof current;
+ switch (op) {
+ case "details": {
+ navigateTo(routeMyAccountDetails.url({}));
+ return;
+ }
+ case "delete": {
+ navigateTo(routeMyAccountDelete.url({}));
+ return;
+ }
+ case "credentials": {
+ navigateTo(routeMyAccountPassword.url({}));
+ return;
+ }
+ case "cashouts": {
+ navigateTo(routeMyAccountCashout.url({}));
+ return;
+ }
+ case "conversion": {
+ navigateTo(routeConversionConfig.url({}));
+ return;
+ }
+ default:
+ assertUnreachable(op);
+ }
+ }}
+ >
+ <option value="details" selected={current == "details"}>
+ <i18n.Translate>Details</i18n.Translate>
+ </option>
+ {!config.allow_deletions ? undefined : (
+ <option value="delete" selected={current == "delete"}>
+ <i18n.Translate>Delete</i18n.Translate>
+ </option>
+ )}
+ <option value="credentials" selected={current == "credentials"}>
+ <i18n.Translate>Credentials</i18n.Translate>
+ </option>
+ {config.allow_conversion ? (
+ <Fragment>
+ <option value="cashouts" selected={current == "cashouts"}>
+ <i18n.Translate>Cashouts</i18n.Translate>
+ </option>
+ <option value="conversion" selected={current == "cashouts"}>
+ <i18n.Translate>Conversion</i18n.Translate>
+ </option>
+ </Fragment>
+ ) : undefined}
+ </select>
+ </div>
+ <div class="hidden sm:block">
+ <nav
+ class="isolate flex divide-x divide-gray-200 rounded-lg shadow"
+ aria-label="Tabs"
+ >
+ <a
+ name="my account details"
+ href={routeMyAccountDetails.url({})}
+ data-selected={current == "details"}
+ class="rounded-l-lg text-gray-500 hover:text-gray-700 data-[selected=true]:text-gray-900 group relative min-w-0 flex-1 overflow-hidden bg-white py-4 px-4 text-center text-sm font-medium hover:bg-gray-50 focus:z-10"
+ >
+ <span>
+ <i18n.Translate>Details</i18n.Translate>
+ </span>
+ <span
+ aria-hidden="true"
+ data-selected={current == "details"}
+ class="bg-transparent data-[selected=true]:bg-indigo-500 absolute inset-x-0 bottom-0 h-0.5"
+ ></span>
+ </a>
+ {!config.allow_deletions ? undefined : (
+ <a
+ name="my account delete"
+ href={routeMyAccountDelete.url({})}
+ data-selected={current == "delete"}
+ aria-current="page"
+ class=" text-gray-500 hover:text-gray-700 data-[selected=true]:text-gray-900 group relative min-w-0 flex-1 overflow-hidden bg-white py-4 px-4 text-center text-sm font-medium hover:bg-gray-50 focus:z-10"
+ >
+ <span>
+ <i18n.Translate>Delete</i18n.Translate>
+ </span>
+ <span
+ aria-hidden="true"
+ data-selected={current == "delete"}
+ class="bg-transparent data-[selected=true]:bg-indigo-500 absolute inset-x-0 bottom-0 h-0.5"
+ ></span>
+ </a>
+ )}
+ <a
+ name="my account password"
+ href={routeMyAccountPassword.url({})}
+ data-selected={current == "credentials"}
+ aria-current="page"
+ class=" text-gray-500 hover:text-gray-700 data-[selected=true]:text-gray-900 group relative min-w-0 flex-1 overflow-hidden bg-white py-4 px-4 text-center text-sm font-medium hover:bg-gray-50 focus:z-10"
+ >
+ <span>
+ <i18n.Translate>Credentials</i18n.Translate>
+ </span>
+ <span
+ aria-hidden="true"
+ data-selected={current == "credentials"}
+ class="bg-transparent data-[selected=true]:bg-indigo-500 absolute inset-x-0 bottom-0 h-0.5"
+ ></span>
+ </a>
+ {config.allow_conversion && nonAdminUser ? (
+ <a
+ name="my account cashout"
+ href={routeMyAccountCashout.url({})}
+ data-selected={current == "cashouts"}
+ class="rounded-r-lg text-gray-500 hover:text-gray-700 data-[selected=true]:text-gray-900 group relative min-w-0 flex-1 overflow-hidden bg-white py-4 px-4 text-center text-sm font-medium hover:bg-gray-50 focus:z-10"
+ >
+ <span>
+ <i18n.Translate>Cashouts</i18n.Translate>
+ </span>
+ <span
+ aria-hidden="true"
+ data-selected={current == "cashouts"}
+ class="bg-transparent data-[selected=true]:bg-indigo-500 absolute inset-x-0 bottom-0 h-0.5"
+ ></span>
+ </a>
+ ) : undefined}
+ {config.allow_conversion && isAdminUser ? (
+ <a
+ name="conversion config"
+ href={routeConversionConfig.url({})}
+ data-selected={current == "conversion"}
+ class="rounded-r-lg text-gray-500 hover:text-gray-700 data-[selected=true]:text-gray-900 group relative min-w-0 flex-1 overflow-hidden bg-white py-4 px-4 text-center text-sm font-medium hover:bg-gray-50 focus:z-10"
+ >
+ <span>
+ <i18n.Translate>Conversion</i18n.Translate>
+ </span>
+ <span
+ aria-hidden="true"
+ data-selected={current == "conversion"}
+ class="bg-transparent data-[selected=true]:bg-indigo-500 absolute inset-x-0 bottom-0 h-0.5"
+ ></span>
+ </a>
+ ) : undefined}
+ </nav>
+ </div>
+ </div>
+ );
+}