rendering layout
1579
lib/useMockT.ts
Normal file
54
lib/useMyTheme.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import { useColorMode } from "@chakra-ui/core";
|
||||
|
||||
/*
|
||||
const theme = {
|
||||
light: {
|
||||
colorMode: "light",
|
||||
bgColor: "#eff0f3",
|
||||
darkerBgColor: "#FFFAFA",
|
||||
textColor: "blackAlpha.900",
|
||||
borderStyle: "1px solid rgba(0, 0, 0, .2)",
|
||||
themeColorWithShade: `${themeColor}.500`,
|
||||
grayWithShade: "gray.600",
|
||||
themeColorHex: chakraTheme.colors[themeColor]["500"],
|
||||
themeColorHexLighter: chakraTheme.colors[themeColor]["200"],
|
||||
themeColor,
|
||||
} as Theme,
|
||||
dark: {
|
||||
colorMode: "dark",
|
||||
bgColor: "#031e3e",
|
||||
darkerBgColor: "#0e2a56",
|
||||
textColor: "whiteAlpha.900",
|
||||
borderStyle: "1px solid rgba(255, 255, 255, .2)",
|
||||
themeColorWithShade: `${themeColor}.200`,
|
||||
grayWithShade: "gray.300",
|
||||
themeColorHex: chakraTheme.colors[themeColor]["500"],
|
||||
themeColorHexLighter: chakraTheme.colors[themeColor]["200"],
|
||||
themeColor,
|
||||
} as Theme,
|
||||
}; */
|
||||
|
||||
const theme = {
|
||||
light: {
|
||||
themeColor: "#79ff61", // light lime green
|
||||
bgColor: "#eff0f3",
|
||||
secondaryBgColor: "#FFFAFA",
|
||||
// FIXME
|
||||
textColor: "blackAlpha.900",
|
||||
gray: "gray.600",
|
||||
},
|
||||
dark: {
|
||||
themeColor: "#79ff61", // light lime green
|
||||
bgColor: "#031e3e",
|
||||
secondaryBgColor: "#0e2a56",
|
||||
textColor: "whiteAlpha.900",
|
||||
gray: "gray.300",
|
||||
},
|
||||
} as const
|
||||
|
||||
export const useMyTheme = () => {
|
||||
const { colorMode } = useColorMode()
|
||||
|
||||
return theme[colorMode]
|
||||
}
|
||||
|
||||
2
next.config.js
Normal file
@@ -0,0 +1,2 @@
|
||||
const withImages = require('next-images')
|
||||
module.exports = withImages()
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useContext } from "react";
|
||||
import MyThemeContext from "../../themeContext";
|
||||
|
||||
export const FooterWaves = () => {
|
||||
const FooterWaves = () => {
|
||||
const { themeColorHex, themeColorHexLighter, colorMode } = useContext(
|
||||
MyThemeContext
|
||||
);
|
||||
@@ -15,3 +15,5 @@ export const FooterWaves = () => {
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default FooterWaves;
|
||||
|
||||
1254
package-lock.json
generated
@@ -13,14 +13,17 @@
|
||||
"seed": "ts-node prisma/seed.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@chakra-ui/core": "^1.0.0-rc.5",
|
||||
"@nexus/schema": "0.15.0",
|
||||
"@prisma/client": "2.8.1",
|
||||
"apollo-server-micro": "^2.17.0",
|
||||
"graphql": "14.6.0",
|
||||
"next": "^9.5.5",
|
||||
"next-images": "^1.6.0",
|
||||
"nexus-plugin-prisma": "^0.21.0",
|
||||
"react": "16.13.1",
|
||||
"react-dom": "16.13.1"
|
||||
"react-dom": "16.13.1",
|
||||
"react-icons": "^3.11.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@prisma/cli": "^2.8.0",
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
const MyApp = ({ Component, pageProps }) => {
|
||||
return <Component {...pageProps} />
|
||||
}
|
||||
import { ChakraProvider } from "@chakra-ui/core";
|
||||
import type { AppProps } from "next/app";
|
||||
import Layout from "scenes/Layout";
|
||||
|
||||
export default MyApp
|
||||
const MyApp = (props: AppProps) => {
|
||||
return (
|
||||
<ChakraProvider>
|
||||
<Layout {...props} />
|
||||
</ChakraProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export default MyApp;
|
||||
|
||||
31
pages/_document.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
import { ColorModeScript } from "@chakra-ui/core";
|
||||
import Document, {
|
||||
DocumentContext,
|
||||
Head,
|
||||
Html,
|
||||
Main,
|
||||
NextScript,
|
||||
} from "next/document";
|
||||
|
||||
class MyDocument extends Document {
|
||||
static async getInitialProps(ctx: DocumentContext) {
|
||||
const initialProps = await Document.getInitialProps(ctx);
|
||||
|
||||
return initialProps;
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Html>
|
||||
<Head />
|
||||
<body>
|
||||
<ColorModeScript />
|
||||
<Main />
|
||||
<NextScript />
|
||||
</body>
|
||||
</Html>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default MyDocument;
|
||||
BIN
public/navIcons/builds.png
Executable file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
public/navIcons/calendar.png
Executable file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
public/navIcons/freeagents.png
Executable file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
public/navIcons/plans.png
Executable file
|
After Width: | Height: | Size: 5.0 KiB |
BIN
public/navIcons/plus.png
Executable file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
public/navIcons/sr.png
Executable file
|
After Width: | Height: | Size: 5.1 KiB |
BIN
public/navIcons/teams.png
Executable file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
public/navIcons/tournaments.png
Executable file
|
After Width: | Height: | Size: 4.7 KiB |
BIN
public/navIcons/xsearch.png
Executable file
|
After Width: | Height: | Size: 3.7 KiB |
40
scenes/Layout/components/Footer.tsx
Normal file
@@ -0,0 +1,40 @@
|
||||
import { Box, Image, useColorModeValue } from "@chakra-ui/core";
|
||||
import footerOctoDark from "assets/b8ing_dark.png";
|
||||
import footerOctoLight from "assets/b8ing_light.png";
|
||||
import footerSquidDark from "assets/boing_dark.png";
|
||||
import footerSquidLight from "assets/boing_light.png";
|
||||
import { useMyTheme } from "lib/useMyTheme";
|
||||
import { useState } from "react";
|
||||
import FooterContent from "./FooterContent";
|
||||
import FooterWaves from "./FooterWaves";
|
||||
|
||||
const Footer: React.FC = () => {
|
||||
const [species] = useState<"octo" | "squid">(
|
||||
Math.random() > 0.5 ? "octo" : "squid"
|
||||
);
|
||||
const { themeColor } = useMyTheme();
|
||||
const footerImageSrc = useColorModeValue(
|
||||
{ octo: footerOctoLight, squid: footerSquidLight },
|
||||
{ octo: footerOctoDark, squid: footerSquidDark }
|
||||
)[species];
|
||||
|
||||
return (
|
||||
<Box mt="auto">
|
||||
<Image
|
||||
src={footerImageSrc}
|
||||
bg={themeColor}
|
||||
w="80px"
|
||||
ml="auto"
|
||||
mr="35%"
|
||||
mb="-5.1%"
|
||||
mt="5rem"
|
||||
userSelect="none"
|
||||
loading="lazy"
|
||||
/>
|
||||
<FooterWaves />
|
||||
<FooterContent />
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default Footer;
|
||||
41
scenes/Layout/components/FooterContent.tsx
Normal file
@@ -0,0 +1,41 @@
|
||||
import { Box, Flex } from "@chakra-ui/core";
|
||||
import { DiscordIcon } from "assets/icons";
|
||||
import { useTranslation } from "lib/useMockT";
|
||||
import { useMyTheme } from "lib/useMyTheme";
|
||||
import Link from "next/link";
|
||||
import { FaGithub } from "react-icons/fa";
|
||||
|
||||
const FooterContent: React.FC = () => {
|
||||
const { t } = useTranslation();
|
||||
const { themeColor } = useMyTheme();
|
||||
return (
|
||||
<Flex
|
||||
pb="50px"
|
||||
flexShrink={0}
|
||||
alignItems="center"
|
||||
fontWeight="bold"
|
||||
letterSpacing="1px"
|
||||
flexWrap="wrap"
|
||||
justifyContent="space-evenly"
|
||||
bg={themeColor}
|
||||
color="black"
|
||||
>
|
||||
<Flex flexDirection="column" fontSize="1.2rem">
|
||||
<Box my="1em">
|
||||
<Link href="/about">{t("footer;About")}</Link>
|
||||
</Box>
|
||||
<Link href="/links">{t("footer;External links")}</Link>
|
||||
</Flex>
|
||||
<Flex alignItems="center" flexWrap="wrap" justifyContent="center">
|
||||
<a href="https://discord.gg/sendou">
|
||||
<DiscordIcon h="30px" w="30px" m="1em" />
|
||||
</a>
|
||||
<a href="https://github.com/Sendouc/sendou.ink">
|
||||
<Box as={FaGithub} size="30px" m="1em" />
|
||||
</a>
|
||||
</Flex>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
export default FooterContent;
|
||||
17
scenes/Layout/components/FooterWaves.tsx
Normal file
@@ -0,0 +1,17 @@
|
||||
import { useMyTheme } from "lib/useMyTheme";
|
||||
import React from "react";
|
||||
|
||||
const FooterWaves = () => {
|
||||
const { themeColor } = useMyTheme();
|
||||
return (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 225">
|
||||
<path
|
||||
fill={themeColor}
|
||||
fillOpacity="1"
|
||||
d="M0,128L60,138.7C120,149,240,171,360,160C480,149,600,107,720,85.3C840,64,960,64,1080,90.7C1200,117,1320,171,1380,197.3L1440,224L1440,320L1380,320C1320,320,1200,320,1080,320C960,320,840,320,720,320C600,320,480,320,360,320C240,320,120,320,60,320L0,320Z"
|
||||
></path>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default FooterWaves;
|
||||
203
scenes/Layout/components/IconNavBar.tsx
Normal file
@@ -0,0 +1,203 @@
|
||||
import {
|
||||
Box,
|
||||
Flex,
|
||||
Image,
|
||||
Menu,
|
||||
MenuButton,
|
||||
MenuGroup,
|
||||
MenuItem,
|
||||
MenuList,
|
||||
} from "@chakra-ui/core";
|
||||
import { useTranslation } from "lib/useMockT";
|
||||
import { useMyTheme } from "lib/useMyTheme";
|
||||
import { useRouter } from "next/dist/client/router";
|
||||
import Link from "next/link";
|
||||
|
||||
const getFirstFridayDate = () => {
|
||||
const today = new Date();
|
||||
const month =
|
||||
today.getDate() - ((1 + today.getDay()) % 7) <= 0
|
||||
? today.getMonth()
|
||||
: today.getMonth() + 1;
|
||||
|
||||
let day = 1;
|
||||
while (day <= 7) {
|
||||
const dateOfVoting = new Date(
|
||||
Date.UTC(today.getFullYear(), month, day, 15, 0, 0)
|
||||
);
|
||||
|
||||
if (dateOfVoting.getDay() === 5) return dateOfVoting;
|
||||
|
||||
day++;
|
||||
}
|
||||
|
||||
console.error("Couldn't resolve first friday of the month for voting");
|
||||
return new Date(2000, 1, 1);
|
||||
};
|
||||
|
||||
export const navIcons: {
|
||||
code: string;
|
||||
displayName: string;
|
||||
menuItems: {
|
||||
code: string;
|
||||
displayName: string;
|
||||
toAppend?: string;
|
||||
}[];
|
||||
}[] = [
|
||||
{
|
||||
code: "xsearch",
|
||||
displayName: "Top 500",
|
||||
menuItems: [
|
||||
{ code: "xsearch", displayName: "Browser" },
|
||||
{ code: "xtrends", displayName: "Trends" },
|
||||
{ code: "xleaderboards", displayName: "Leaderboards" },
|
||||
],
|
||||
},
|
||||
//{ code: "sr", displayName: "Salmon Run", menuItems: [] },
|
||||
{
|
||||
code: "builds",
|
||||
displayName: "Builds",
|
||||
menuItems: [
|
||||
{ code: "builds", displayName: "Browser" },
|
||||
{ code: "analyzer", displayName: "Analyzer" },
|
||||
],
|
||||
},
|
||||
{ code: "calendar", displayName: "Calendar", menuItems: [] },
|
||||
{ code: "freeagents", displayName: "Free Agents", menuItems: [] },
|
||||
//{ name: "teams", displayName: "Teams" },
|
||||
{ code: "plans", displayName: "Map Planner", menuItems: [] },
|
||||
{ code: "tournaments", displayName: "Tournaments", menuItems: [] },
|
||||
{
|
||||
code: "plus",
|
||||
displayName: "Plus Server",
|
||||
menuItems: [
|
||||
{
|
||||
code: "plus/voting",
|
||||
displayName: "Voting",
|
||||
toAppend:
|
||||
": " +
|
||||
getFirstFridayDate().toLocaleString("default", {
|
||||
month: "short",
|
||||
day: "numeric",
|
||||
}),
|
||||
},
|
||||
{ code: "plus", displayName: "Suggested and vouched players" },
|
||||
{ code: "plus/history", displayName: "Voting history" },
|
||||
{ code: "draft", displayName: "Draft Cup" },
|
||||
{ code: "plus/faq", displayName: "FAQ" },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const IconNavBar = () => {
|
||||
const { t } = useTranslation();
|
||||
const { secondaryBgColor, textColor, themeColor, gray } = useMyTheme();
|
||||
const pathname = useRouter().pathname;
|
||||
|
||||
// FIXME
|
||||
//const isVoting = !!plusInfoData?.plusInfo?.voting_ends;
|
||||
const isVoting = false;
|
||||
|
||||
return (
|
||||
<Flex bg={secondaryBgColor} py={2} justifyContent="center" flexWrap="wrap">
|
||||
{navIcons.map(({ displayName, code, menuItems }) => {
|
||||
const codesTogether =
|
||||
"/" +
|
||||
code +
|
||||
menuItems.reduce((acc, { code }) => acc + "/" + code, "");
|
||||
|
||||
const isActive = pathname !== "/" && codesTogether.includes(pathname);
|
||||
const MenuNavIcon = () => (
|
||||
<Flex
|
||||
flexDirection="column"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
m="5px 15px"
|
||||
>
|
||||
<Box color={isActive ? themeColor : gray} fontSize="0.75em">
|
||||
{t(`navigation;${displayName}`)}
|
||||
</Box>
|
||||
<Image
|
||||
src={`navIcons/${code}.png`}
|
||||
h={12}
|
||||
w={12}
|
||||
alt={code}
|
||||
cursor="pointer"
|
||||
userSelect="none"
|
||||
ignoreFallback
|
||||
/>
|
||||
{menuItems.length > 0 && (
|
||||
<Box ml="0.1rem" lineHeight="0.5rem">
|
||||
▾
|
||||
</Box>
|
||||
)}
|
||||
</Flex>
|
||||
);
|
||||
if (!menuItems.length) {
|
||||
return (
|
||||
<Link key={code} href={code}>
|
||||
<MenuNavIcon />
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Menu key={code}>
|
||||
<MenuButton>
|
||||
<MenuNavIcon />
|
||||
</MenuButton>
|
||||
<MenuList bg={secondaryBgColor} color={textColor}>
|
||||
<MenuGroup title={t(`navigation;${displayName}`)}>
|
||||
{menuItems.map((item) => (
|
||||
<Link key={item.code} href={item.code}>
|
||||
<MenuItem
|
||||
disabled={item.displayName === "Voting" && !isVoting}
|
||||
>
|
||||
{pathname === "/" + item.code ? (
|
||||
<Box
|
||||
h="7px"
|
||||
w="7px"
|
||||
mb={1}
|
||||
bgColor={themeColor}
|
||||
borderRadius="50%"
|
||||
lineHeight="0.5rem"
|
||||
mr="7px"
|
||||
mt="4px"
|
||||
/>
|
||||
) : (
|
||||
<Box
|
||||
h="7px"
|
||||
w="7px"
|
||||
mb={1}
|
||||
borderRadius="50%"
|
||||
lineHeight="0.5rem"
|
||||
mr="7px"
|
||||
mt="4px"
|
||||
opacity={1}
|
||||
/>
|
||||
)}
|
||||
<Box>
|
||||
{t(
|
||||
`navigation;${
|
||||
item.displayName !== "Voting"
|
||||
? item.displayName
|
||||
: isVoting
|
||||
? "Voting"
|
||||
: "Next voting"
|
||||
}`
|
||||
)}
|
||||
{!isVoting && item.toAppend}
|
||||
</Box>
|
||||
</MenuItem>
|
||||
</Link>
|
||||
))}
|
||||
</MenuGroup>
|
||||
</MenuList>
|
||||
</Menu>
|
||||
);
|
||||
})}
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
export default IconNavBar;
|
||||
67
scenes/Layout/components/LanguageSelector.tsx
Normal file
@@ -0,0 +1,67 @@
|
||||
import {
|
||||
IconButton,
|
||||
Menu,
|
||||
MenuButton,
|
||||
MenuItemOption,
|
||||
MenuList,
|
||||
MenuOptionGroup,
|
||||
} from "@chakra-ui/core";
|
||||
import { useTranslation } from "lib/useMockT";
|
||||
import { useMyTheme } from "lib/useMyTheme";
|
||||
import React from "react";
|
||||
import { FiGlobe } from "react-icons/fi";
|
||||
|
||||
export const languages = [
|
||||
{ code: "de", name: "Deutsch" },
|
||||
{ code: "en", name: "English" },
|
||||
{ code: "es-ES", name: "Español" },
|
||||
{ code: "fr", name: "Français" },
|
||||
{ code: "it", name: "Italiano" },
|
||||
{ code: "nl", name: "Nederlands" },
|
||||
{ code: "pt-BR", name: "Português" },
|
||||
{ code: "sv", name: "Svenska" },
|
||||
{ code: "el", name: "Ελληνικά" },
|
||||
{ code: "ru", name: "Русский" },
|
||||
{ code: "ja", name: "日本語" },
|
||||
{ code: "ko", name: "한국어" },
|
||||
{ code: "zh-TW", name: "繁體中文" },
|
||||
] as const;
|
||||
|
||||
export const LanguageSelector = () => {
|
||||
const { t } = useTranslation();
|
||||
const { secondaryBgColor, textColor } = useMyTheme();
|
||||
|
||||
return (
|
||||
<Menu>
|
||||
<MenuButton
|
||||
as={IconButton}
|
||||
aria-label="Switch language"
|
||||
variant="ghost"
|
||||
fontSize="20px"
|
||||
icon={<FiGlobe />}
|
||||
borderRadius="50%"
|
||||
color={textColor}
|
||||
/>
|
||||
<MenuList bg={secondaryBgColor} color={textColor}>
|
||||
<MenuOptionGroup
|
||||
title={t("navigation;Choose language")}
|
||||
// FIXME
|
||||
//value={i18n.language}
|
||||
value="en"
|
||||
>
|
||||
{languages.map((lang) => (
|
||||
<MenuItemOption
|
||||
key={lang.code}
|
||||
value={lang.code}
|
||||
// FIXME
|
||||
//onClick={() => i18n.changeLanguage(lang.code)}
|
||||
onClick={() => console.log(lang.code)}
|
||||
>
|
||||
{lang.name}
|
||||
</MenuItemOption>
|
||||
))}
|
||||
</MenuOptionGroup>
|
||||
</MenuList>
|
||||
</Menu>
|
||||
);
|
||||
};
|
||||
107
scenes/Layout/components/TopNav.tsx
Normal file
@@ -0,0 +1,107 @@
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Flex,
|
||||
Grid,
|
||||
IconButton,
|
||||
useColorMode,
|
||||
} from "@chakra-ui/core";
|
||||
import { DiscordIcon } from "assets/icons";
|
||||
import { useTranslation } from "lib/useMockT";
|
||||
import { useMyTheme } from "lib/useMyTheme";
|
||||
import Link from "next/link";
|
||||
import { FiMoon, FiSun } from "react-icons/fi";
|
||||
import { LanguageSelector } from "./LanguageSelector";
|
||||
|
||||
const TopNav = () => {
|
||||
const { bgColor } = useMyTheme();
|
||||
const { colorMode, toggleColorMode } = useColorMode();
|
||||
|
||||
const UserItem = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
// FIXME
|
||||
return (
|
||||
<a href="/auth/discord">
|
||||
<Button leftIcon={<DiscordIcon />} variant="ghost" size="sm">
|
||||
{t("navigation;Log in via Discord")}
|
||||
</Button>
|
||||
</a>
|
||||
);
|
||||
/*if (loading) return <Box />;
|
||||
if (!data?.user)
|
||||
return (
|
||||
<a href="/auth/discord">
|
||||
<Button leftIcon={<DiscordIcon />} variant="ghost" size="sm">
|
||||
{t("navigation;Log in via Discord")}
|
||||
</Button>
|
||||
</a>
|
||||
);
|
||||
<Link to={`/u/${data.user.discord_id}`}>
|
||||
return (
|
||||
<Menu>
|
||||
<MenuButton>
|
||||
<UserAvatar
|
||||
src={data.user.avatar}
|
||||
name={data.user.username}
|
||||
size="sm"
|
||||
m={1}
|
||||
cursor="pointer"
|
||||
/>
|
||||
</MenuButton>
|
||||
<MenuList bg={darkerBgColor} color={textColor}>
|
||||
<MenuGroup title={data.user.username}>
|
||||
<Link to={`/u/${data.user.discord_id}`}>
|
||||
<MenuItem>{t("navigation;Profile")}</MenuItem>
|
||||
</Link>
|
||||
<a href="/logout">
|
||||
<MenuItem>{t("navigation;Log out")}</MenuItem>
|
||||
</a>
|
||||
</MenuGroup>
|
||||
</MenuList>
|
||||
</Menu>
|
||||
);*/
|
||||
};
|
||||
|
||||
return (
|
||||
<Grid
|
||||
templateColumns={["1fr 1fr", null, "1fr 1fr 1fr"]}
|
||||
bg={bgColor}
|
||||
w="100%"
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
p={1}
|
||||
>
|
||||
<Flex alignItems="center">
|
||||
<IconButton
|
||||
aria-label={`Switch to ${
|
||||
colorMode === "light" ? "dark" : "light"
|
||||
} mode`}
|
||||
variant="ghost"
|
||||
color="current"
|
||||
fontSize="20px"
|
||||
onClick={toggleColorMode}
|
||||
icon={colorMode === "light" ? <FiSun /> : <FiMoon />}
|
||||
borderRadius="50%"
|
||||
/>
|
||||
<LanguageSelector />
|
||||
</Flex>
|
||||
<Box
|
||||
justifySelf="center"
|
||||
fontFamily="Rubik, sans-serif"
|
||||
color="gray.600"
|
||||
fontWeight="bold"
|
||||
letterSpacing={1}
|
||||
display={["none", null, "block"]}
|
||||
>
|
||||
{" "}
|
||||
<Link href="/">sendou.ink </Link>
|
||||
</Box>
|
||||
<Box justifySelf="flex-end">
|
||||
<UserItem />
|
||||
</Box>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
export default TopNav;
|
||||
45
scenes/Layout/index.tsx
Normal file
@@ -0,0 +1,45 @@
|
||||
import { Container, Flex } from "@chakra-ui/core";
|
||||
import { useMyTheme } from "lib/useMyTheme";
|
||||
import { AppProps } from "next/app";
|
||||
import { useRouter } from "next/dist/client/router";
|
||||
import { useEffect } from "react";
|
||||
import Footer from "./components/Footer";
|
||||
import IconNavBar from "./components/IconNavBar";
|
||||
import TopNav from "./components/TopNav";
|
||||
|
||||
const PAGES_WITH_WIDE_CONTAINER = [
|
||||
"/analyzer",
|
||||
"/xsearch",
|
||||
"/builds",
|
||||
"/plans",
|
||||
"/xleaderboards",
|
||||
];
|
||||
|
||||
const Layout = ({ Component, pageProps }: AppProps) => {
|
||||
const { bgColor, textColor } = useMyTheme();
|
||||
const pathname = useRouter().pathname;
|
||||
|
||||
// FIXME
|
||||
useEffect(() => {
|
||||
document.body.style.backgroundColor = bgColor;
|
||||
}, [bgColor]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<TopNav />
|
||||
<IconNavBar />
|
||||
<Flex flexDirection="column" color={textColor} minH="100vh" pt="1rem">
|
||||
<Container
|
||||
maxWidth={
|
||||
PAGES_WITH_WIDE_CONTAINER.includes(pathname) ? "120ch" : "70ch"
|
||||
}
|
||||
>
|
||||
<Component {...pageProps} />
|
||||
</Container>
|
||||
<Footer />
|
||||
</Flex>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Layout;
|
||||