233 lines
7.1 KiB
TypeScript

import {
Avatar,
Box,
Button,
CloseButton,
Container,
Drawer,
DrawerContent,
DrawerOverlay,
Flex,
HStack,
Link,
Spacer,
Text,
useDisclosure,
} from "@chakra-ui/react";
async function destroySession() {
await fetch("/api/auth/session", {
method: "DELETE",
}).catch(() => {});
location.assign("/");
}
function getAvatarUrl(userData: { [k: string]: any }): string {
const BASE = "https://cdn.discordapp.com/";
if (userData.avatar)
return BASE + `avatars/${userData.id}/${userData.avatar}`;
if (!userData.id || typeof window["BigInt"] === "undefined") return "";
return BASE + `embed/avatars/${(BigInt(userData.id) >> 22n) % 6n}.png`;
}
export default function (props: {
avatar?: string;
email?: string;
hide?: boolean;
id?: string;
permissions?: number;
username?: string;
}) {
let data = { ...props };
const { isOpen, onClose, onOpen } = useDisclosure();
function hasMod(): boolean {
const { permissions } = props;
if (typeof permissions === "undefined") return false;
return Boolean(
[
1 << 0,
1 << 2,
1 << 3,
1 << 4,
1 << 5,
1 << 6,
1 << 7,
1 << 8,
1 << 9,
1 << 10,
1 << 11,
].find((int) => permissions & int),
);
}
return (
<>
<Box as="section" pb={{ base: "6" }}>
<Box as="nav" boxSizing="unset">
<Container display="grid" maxW="container.xl" py={{ base: "6" }}>
<Flex
alignSelf="center"
gap="0.5rem"
gridColumn="1"
gridRow="1"
justifyContent="space-between"
p="0"
textAlign="center"
>
<a href="/">
<img
alt="Car Crushers Logo"
height="36"
src="/files/logo192.png"
width="36"
/>
</a>
<Spacer />
<Spacer />
<HStack
alignItems="center"
gap="3rem"
whiteSpace="nowrap"
className="nav-links"
>
<Link href="/about" size="lg">
About Us
</Link>
<Link href="/team" size="lg">
Our Team
</Link>
<Link href="/support" size="lg">
Support
</Link>
<Link href="https://ccdiscussion.com" size="lg">
Community
</Link>
<Link
display={hasMod() ? undefined : "none"}
href="/mod-queue"
size="lg"
>
Moderation
</Link>
</HStack>
<Spacer />
<Spacer />
<div className="nav-links">
{data.hide ? null : data.id ? (
<HStack spacing="3">
<a href="/me">
<Avatar src={getAvatarUrl(data)} />
</a>
<Text>{data.username}</Text>
<Button
onClick={async () => await destroySession()}
size="md"
variant="ghost"
>
<svg
cursor="pointer"
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
viewBox="0 0 16 16"
>
<path
fillRule="evenodd"
d="M10 12.5a.5.5 0 0 1-.5.5h-8a.5.5 0 0 1-.5-.5v-9a.5.5 0 0 1 .5-.5h8a.5.5 0 0 1 .5.5v2a.5.5 0 0 0 1 0v-2A1.5 1.5 0 0 0 9.5 2h-8A1.5 1.5 0 0 0 0 3.5v9A1.5 1.5 0 0 0 1.5 14h8a1.5 1.5 0 0 0 1.5-1.5v-2a.5.5 0 0 0-1 0v2z"
/>
<path
fillRule="evenodd"
d="M15.854 8.354a.5.5 0 0 0 0-.708l-3-3a.5.5 0 0 0-.708.708L14.293 7.5H5.5a.5.5 0 0 0 0 1h8.793l-2.147 2.146a.5.5 0 0 0 .708.708l3-3z"
/>
</svg>
</Button>
</HStack>
) : (
<Button as="a" colorScheme="blue" href="/api/auth/oauth">
Log In
</Button>
)}
</div>
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
fill="currentColor"
viewBox="0 0 16 16"
cursor="pointer"
onClick={onOpen}
id="nav-menu"
>
<path
fillRule="evenodd"
d="M2.5 12a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5z"
/>
</svg>
</Flex>
</Container>
</Box>
</Box>
<Drawer isOpen={isOpen} onClose={onClose} placement="left">
<DrawerOverlay />
<DrawerContent gap="1.5vh" p="1.5vh">
<CloseButton onClick={onClose} />
<hr />
<Link href="/about">About Us</Link>
<Link href="/team">Our Team</Link>
<Link href="/support">Support</Link>
<Link href="https://ccdiscussion.com">Community</Link>
<Link href="/mod-queue" display={hasMod() ? undefined : "none"}>
Moderation
</Link>
<hr />
<Flex alignItems="center" gap="1rem">
<Link display={data.id ? "none" : ""} href="/api/auth/oauth">
Log In
</Link>
<a href="/me">
<Avatar
display={data.id ? "" : "none"}
height={64}
src={getAvatarUrl(data)}
width={64}
/>
</a>
<Text align="center" style={{ overflowWrap: "anywhere" }}>
{data.id ? data.username : ""}
</Text>
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
fill="currentColor"
viewBox="0 0 16 16"
style={{
cursor: "pointer",
display: data.id ? "block" : "none",
}}
onClick={async () => destroySession()}
>
<path
fillRule="evenodd"
d="M10 12.5a.5.5 0 0 1-.5.5h-8a.5.5 0 0 1-.5-.5v-9a.5.5 0 0 1 .5-.5h8a.5.5 0 0 1 .5.5v2a.5.5 0 0 0 1 0v-2A1.5 1.5 0 0 0 9.5 2h-8A1.5 1.5 0 0 0 0 3.5v9A1.5 1.5 0 0 0 1.5 14h8a1.5 1.5 0 0 0 1.5-1.5v-2a.5.5 0 0 0-1 0v2z"
/>
<path
fillRule="evenodd"
d="M15.854 8.354a.5.5 0 0 0 0-.708l-3-3a.5.5 0 0 0-.708.708L14.293 7.5H5.5a.5.5 0 0 0 0 1h8.793l-2.147 2.146a.5.5 0 0 0 .708.708l3-3z"
/>
</svg>
</Flex>
</DrawerContent>
</Drawer>
</>
);
}