sendou.ink/pages/_app.tsx
2020-12-12 16:09:38 +02:00

159 lines
3.8 KiB
TypeScript

import { ChakraProvider, extendTheme } from "@chakra-ui/react";
import { mode } from "@chakra-ui/theme-tools";
import { i18n } from "@lingui/core";
import { I18nProvider } from "@lingui/react";
import Layout from "components/layout";
import { activateLocale } from "lib/i18n";
import { locales } from "lib/lists/locales";
import { Provider as NextAuthProvider } from "next-auth/client";
import GoogleFonts from "next-google-fonts";
import type { AppProps } from "next/app";
import Head from "next/head";
import { Router } from "next/router";
import NProgress from "nprogress";
import { useEffect } from "react";
import { theme } from "theme";
import "./styles.css";
NProgress.configure({ showSpinner: false });
Router.events.on("routeChangeStart", (url) => {
NProgress.start();
});
Router.events.on("routeChangeComplete", () => NProgress.done());
Router.events.on("routeChangeError", () => NProgress.done());
const extendedTheme = extendTheme({
styles: {
global: (props) => ({
body: {
fontFamily: "'Rubik', sans-serif",
color: mode(theme.light.textColor, theme.dark.textColor)(props),
bg: mode(theme.light.bgColor, theme.dark.bgColor)(props),
},
}),
},
// TODO:
// 1) round iconButton (closeButton of modal too)
// 2) table-like lime green input addons
// 3) input styling
// 4) focus color
// 5) form label bolded
// 6) dropdown border + focus colors // especially in light blends in a lot
// 7) disable dark mode <-> light mode transformation time
// 8) divider color (light)
// 9) link color
components: {
Button: {
defaultProps: {
colorScheme: "theme",
},
},
Radio: {
defaultProps: {
colorScheme: "theme",
},
},
Tag: {
defaultProps: {
colorScheme: "theme",
},
},
Badge: {
defaultProps: {
colorScheme: "theme",
},
},
Modal: {
baseStyle: (props) => ({
dialog: {
bg: mode(
theme.light.secondaryBgColor,
theme.dark.secondaryBgColor
)(props),
},
}),
},
Menu: {
baseStyle: (props) => ({
list: {
bg: mode(
theme.light.secondaryBgColor,
theme.dark.secondaryBgColor
)(props),
},
}),
},
Popover: {
variants: {
responsive: {
popper: {
maxWidth: "unset",
width: "unset",
},
},
},
},
},
colors: {
theme: {
50: "#e4ffdf",
100: "#bbffb0",
200: "#92ff7f",
300: "#68ff4d",
400: "#3fff1d",
500: "#27e606",
600: "#1bb300",
700: "#108000",
800: "#054d00",
900: "#001b00",
},
},
});
const getUsersLanguage = () => {
const localeFromLocalStorage = window.localStorage.getItem("locale");
if (localeFromLocalStorage) {
return localeFromLocalStorage;
}
const browserLanguage = navigator.languages
? navigator.languages[0]
: navigator.language;
// Could be either "en" or "en-US" for example - that's why the split
const languageCode = browserLanguage.split("-")[0];
if (locales.includes(languageCode)) return languageCode;
return "en";
};
const setDisplayedLanguage = () => {
activateLocale(getUsersLanguage());
};
const MyApp = (props: AppProps) => {
useEffect(setDisplayedLanguage, []);
return (
<>
<Head>
<link rel="stylesheet" type="text/css" href="/nprogress.css" />
</Head>
<GoogleFonts
href={`https://fonts.googleapis.com/css2?family=Rubik&display=swap`}
/>
<NextAuthProvider session={props.pageProps.session}>
<ChakraProvider theme={extendedTheme}>
<I18nProvider i18n={i18n}>
<Layout {...props} />
</I18nProvider>
</ChakraProvider>
</NextAuthProvider>
</>
);
};
export default MyApp;