diff options
Diffstat (limited to 'packages/bank-ui/src/pages/ProfileNavigation.tsx')
-rw-r--r-- | packages/bank-ui/src/pages/ProfileNavigation.tsx | 202 |
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> + ); +} |