Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
car-crushers-portal/components/Navigation.tsx
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
203 lines (192 sloc)
5.92 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 << 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"> | |
<Avatar src={getAvatarUrl(data)} /> | |
<Text>{data.username}</Text> | |
<Button | |
onClick={async () => await destroySession()} | |
size="md" | |
variant="ghost" | |
></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="/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> | |
<Avatar display={data.id ? "" : "none"} src={getAvatarUrl(data)} /> | |
<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> | |
</> | |
); | |
} |