Skip to content
Snippets Groups Projects
navbar.jsx 5.35 KiB
import React, { ReactNode, useState, useEffect } from "react";
import Link from "next/link";
import { useRouter } from "next/router";

import { useTranslation } from "next-i18next";
import { useSession } from "next-auth/react";

import { ColorSchemeProvider, Group, MediaQuery } from "@mantine/core";
import { NotificationsProvider } from "@mantine/notifications";

import { ApolloProvider } from "@apollo/client";
import apolloClient from "../lib/apollo";

import {
  makeVsethTheme,
  useConfig,
  VSETHExternalApp,
  VSETHThemeProvider,
} from "vseth-canine-ui";

import hasAccess from "../utilities/hasAccess";

import LoginButton from "../components/loginButton";
import ThemeSwitcher from "../components/themeSwitcher";

export default function Navbar(props) {
  const router = useRouter();
  const { locale, pathname, asPath, query } = router;
  const { t } = useTranslation("common");
  const { data: session } = useSession();

  const theme = makeVsethTheme();
  const [selectedLanguage, setSelectedLanguage] = React.useState(locale);

  const [colorScheme, setColorScheme] = useState("dark");
  const toggleColorScheme = (value) =>
    setColorScheme(value || (colorScheme === "dark" ? "light" : "dark"));
  theme.colorScheme = colorScheme;

  /*
   * VSETH Colors: See https://s.aschoch.ch/canine-colors
   * theme.colors.vsethMain[7] is #009fe3 (cyan)
   */
  theme.colors.vsethMain[7] = "#244471";
  theme.colors.vsethMain[0] = "#dee5ef"; // light color
  theme.colors.vsethMain[1] = "#b7cae5"; // light color
  theme.colors.vsethMain[8] = "#4f6d96"; // light color

  theme.colors.orange = [
    "#f28a20",
    "#f28a20",
    "#f28a20",
    "#f28a20",
    "#f28a20",
    "#f28a20",
    "#f28a20",
    "#f28a20",
    "#f28a20",
    "#f28a20",
  ];

  // NOTE: This is a hack, as colors are hardcoded in vseth-canine
  useEffect(() => {
    const footerDiv = document.querySelector("footer>div");
    const footerLogo = document.querySelector("footer img");
    const selectItems = document.querySelector("header a");

    if (colorScheme == "dark") {
      footerDiv.classList.add("vseth-footer-dark");
      footerLogo.classList.add("vseth-logo-dark");
      if (selectItems) selectItems.classList.add("vseth-text-dark");
    } else {
      footerDiv.classList.remove("vseth-footer-dark");
      footerLogo.classList.remove("vseth-logo-dark");
      if (selectItems) selectItems.classList.remove("vseth-text-dark");
    }
  }, [colorScheme]);

  const { data } = useConfig(
    "https://static.vseth.ethz.ch/assets/vseth-0522-thealt/config.json"
  );

  const customDemoNav = [
    { title: t("main"), href: "/" },
    { title: t("bashGuide"), href: "/bash" },
    { title: t("installGuide"), href: "/install" },
    {
      title: t("courses"),
      href: "https://gitlab.ethz.ch/thealternative/courses",
    },
  ];

  // if (hasAccess(session, true)) {
  //   customDemoNav.push({ title: t("menu"), href: "/menu" });
  //   customDemoNav.push({ title: t("graveyard"), href: "/graveyard" });
  // }

  return (
    <React.StrictMode>
      <ColorSchemeProvider
        colorScheme={colorScheme}
        toggleColorScheme={toggleColorScheme}
      >
        <VSETHThemeProvider theme={theme}>
          <VSETHExternalApp
            selectedLanguage={selectedLanguage}
            onLanguageSelect={(lang) => {
              setSelectedLanguage(lang);
              router.push({ pathname, query }, asPath, { locale: lang });
            }}
            languages={data?.languages}
            title={"TheAlternative"}
            appNav={customDemoNav}
            organizationNav={data.externalNav}
            makeWrapper={(url, child) => (
              <>
                <MediaQuery smallerThan="md" styles={{ display: "none" }}>
                  <Link
                    href={url}
                    style={{
                      textDecoration: "none",
                      color:
                        theme.colorScheme == "light" ? "#333333b3" : "#C1C2C5",
                    }}
                  >
                    {child}
                  </Link>
                </MediaQuery>
                <MediaQuery largerThan="md" styles={{ display: "none" }}>
                  <Link
                    href={url}
                    style={{
                      textDecoration: "none",
                      color: "#C1C2C5",
                    }}
                  >
                    {child}
                  </Link>
                </MediaQuery>
              </>
            )}
            privacyPolicy={data?.privacy}
            disclaimer={data?.copyright}
            //activeHref is the current active url path. Required to style the active page in the Nav
            activeHref={"/"}
            socialMedia={data?.socialMedia}
            logo={
              "https://static.vseth.ethz.ch/assets/vseth-0522-thealt/logo-inv.svg"
            }
            loginButton={
              <Group>
                <ThemeSwitcher />
                <LoginButton />
              </Group>
            }
            signet={
              "https://static.vseth.ethz.ch/assets/vseth-0522-thealt/signet-inv.svg"
            }
            size="xl"
          >
            <ApolloProvider client={apolloClient}>
              <NotificationsProvider>{props.children}</NotificationsProvider>
            </ApolloProvider>
          </VSETHExternalApp>
        </VSETHThemeProvider>
      </ColorSchemeProvider>
    </React.StrictMode>
  );
}