Newer
Older
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";
Box,
Button,
ColorSchemeProvider,
Group,
MediaQuery,
Menu,
import { NotificationsProvider } from "@mantine/notifications";
import { useWindowScroll } from "@mantine/hooks";
import { Icon, ICONS } from "vseth-canine-ui";
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";
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("light");
const toggleColorScheme = (value) =>
setColorScheme(value || (colorScheme === "dark" ? "light" : "dark"));
theme.colorScheme = colorScheme;
const [scroll, scrollTo] = useWindowScroll();
/*
* VSETH Colors: See https://s.aschoch.ch/canine-colors
* theme.colors.vsethMain[7] is #009fe3 (cyan)
*/
theme.colors.vsethMain[7] = "#244471";
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",
];
theme.fontSizes = {
md: 17,
};
// 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("bashGuide"), href: "/bash" },
{ title: t("installGuide"), href: "/install" },
{
title: t("courses"),
href: "https://gitlab.ethz.ch/thealternative/courses",
},
];
const customNav = [
{
title: (
<>
<MediaQuery smallerThan="md" styles={{ display: "none" }}>
<Menu shadow="md" width={200}>
<Menu.Target>
<Group>
<span style={{ color: "#f28a20" }}>{t("guides")}</span>
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
<Icon icon={ICONS.DOWN} color="#f28a20" />
</Group>
</Menu.Target>
<Menu.Dropdown>
<Menu.Item>
<Link style={{ textDecoration: "none" }} href="/bash">
{t("bashGuide")}
</Link>
</Menu.Item>
<Menu.Item>
<Link style={{ textDecoration: "none" }} href="/install">
{t("installGuide")}
</Link>
</Menu.Item>
</Menu.Dropdown>
</Menu>
</MediaQuery>
<MediaQuery largerThan="md" styles={{ display: "none" }}>
<span style={{ color: "white" }}>
<Link style={{ textDecoration: "none" }} href="/bash">
{t("bashGuide")}
</Link>
•
<Link style={{ textDecoration: "none" }} href="/install">
{t("installGuide")}
</Link>
</span>
</MediaQuery>
</>
),
href: "",
},
{
title: (
<a
style={{ textDecoration: "none" }}
target="_blank"
href="https://gitlab.ethz.ch/thealternative/courses"
>
{t("courses")}
</a>
),
href: "",
},
];
<ColorSchemeProvider
colorScheme={colorScheme}
toggleColorScheme={toggleColorScheme}
>
<VSETHThemeProvider theme={theme}>
<Box
sx={(theme) => ({
main: {
backgroundColor:
theme.colorScheme === "dark" ? theme.colors.dark[8] : "white",
},
})}
>
<VSETHExternalApp
selectedLanguage={selectedLanguage}
onLanguageSelect={(lang) => {
setSelectedLanguage(lang);
router.push({ pathname, query }, asPath, { locale: lang });
}}
languages={data?.languages}
title={
<>
<MediaQuery largerThan="md" styles={{ display: "none" }}>
<Link href="/">
<img
style={{ maxWidth: "250px" }}
src={
"https://static.vseth.ethz.ch/assets/vseth-0522-thealt/logo-inv.svg"
}
/>
</Link>
</MediaQuery>
<MediaQuery smallerThan="md" styles={{ display: "none" }}>
<Link href="/">
<img
style={{ maxWidth: "250px" }}
src={
theme.colorScheme === "dark"
? "https://static.vseth.ethz.ch/assets/vseth-0522-thealt/logo-inv.svg"
: "/images/logo.svg"
}
/>
</Link>
</MediaQuery>
</>
}
appNav={customNav}
organizationNav={data.externalNav}
makeWrapper={(url, child) => <span>{child}</span>}
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={"/images/vseth_inv_nobyline.svg"}
loginButton={
<Group>
<ThemeSwitcher />
<LoginButton />
</Group>
}
size="xl"
>
<ApolloProvider client={apolloClient}>
<NotificationsProvider>{props.children}</NotificationsProvider>
</ApolloProvider>
</VSETHExternalApp>
</Box>
<Affix position={{ bottom: 20, right: 20 }}>
<Transition transition="slide-up" mounted={scroll.y > 0}>
{(transitionStyles) => (
<Button
leftIcon={<Icon icon={ICONS.UP} size={20} color="#f28a20" />}
style={{ ...transitionStyles, color: "#f28a20" }}
onClick={() => scrollTo({ y: 0 })}
>
{t("scrollToTop")}
</Button>
)}
</Transition>
</Affix>