2023-10-19 16:49:19 -04:00

179 lines
5.1 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import {
ChakraProvider,
Container,
cookieStorageManagerSSR,
Heading,
Link,
Text,
} from "@chakra-ui/react";
import { ClientStyleContext, ServerStyleContext } from "./context.js";
import fontStyle from "@fontsource/plus-jakarta-sans/index.css";
import Forbidden from "../components/Forbidden.js";
import globalStyles from "../index.css";
import { HelmetProvider } from "react-helmet-async";
import {
Links,
LiveReload,
Outlet,
Scripts,
useCatch,
useLoaderData,
} from "@remix-run/react";
import { LinksFunction } from "@remix-run/cloudflare";
import Login from "../components/Login.js";
import Navigation from "../components/Navigation.js";
import { type ReactNode, StrictMode, useContext, useEffect } from "react";
import theme from "../theme.js";
import { withEmotionCache } from "@emotion/react";
export function CatchBoundary() {
const { status } = useCatch();
switch (status) {
case 303:
return "";
case 401:
return getMarkup({ hide: true }, <Login />);
case 403:
return getMarkup({ hide: true }, <Forbidden />);
case 404:
return getMarkup(
{ hide: true },
<Container maxW="container.lg" pt="8vh" textAlign="left">
<Heading size="4xl">404</Heading>
<br />
<Text fontSize="xl">There is nothing to find here.</Text>
<br />
<br />
<br />
<Link color="#646cff" onClick={() => history.go(-1)}>
Go back
</Link>
</Container>
);
default:
return getMarkup(
{ hide: true },
<Container maxW="container.lg" pt="8vh" textAlign="left">
<Heading size="4xl">500</Heading>
<br />
<Text fontSize="xl">S̶̡͈̠̗̠͖͙̭o̶̶͕͚̥͍̪̤m̸̨͏͈͔̖͚̖̰̱͞e҉̵͖͚͇̀t̕͟͠͏͎̺̯̲̱̣̤̠̟͙̠̙̫̬ḩ̸̭͓̬͎̙̀į̞̮͉͖̰̥̹͚̫̙̪̗̜̳̕ͅn҉͔̯̪̗̝̝͖̲͇͍͎̲̲̤̖̫͈̪͡g̴̰̻̙̝͉̭͇̖̰̝̙͕̼͙͘͜ ̵̶̫̥̳̲̘̻̗͈͕̭̲͇̘̜̺̟̥̖̥b̴̙̭̹͕̞͠r̞͎̠̩͈̖̰̞̯̯͢͢͠ͅo̝̯̗̹̳͍̰͉͕̘̰̠̺̥̰͔̕ͅk̵̸̻̠͕̺̦̦͖̲̺̦̞̝̞͞͡e̶͏̤̼̼͔̘̰̰̭͈̀͞͡</Text>
<br />
<br />
<br />
<Link color="#646cff" onClick={() => location.reload()}>
Reload
</Link>
</Container>
);
}
}
export const links: LinksFunction = () => {
return [
{ href: "/favicon.ico", rel: "icon" },
{ href: "/files/logo192.png", rel: "apple-touch-icon", type: "image/png" },
{ href: fontStyle, rel: "stylesheet " },
{ href: globalStyles, rel: "stylesheet" },
];
};
export async function loader({
context,
}: {
context: RequestContext;
}): Promise<{ [k: string]: any }> {
let data: { [k: string]: string } = {};
if (context.data.current_user) data = { ...context.data.current_user };
if (context.env.DSN) data.dsn = context.env.DSN;
if (context.data.theme) data.theme = context.data.theme;
return data;
}
function getMarkup(
loaderData: { [k: string]: any },
child: ReactNode
): JSX.Element {
const Document = withEmotionCache(
({ children }: { children: ReactNode }, emotionCache) => {
const serverStyleData = useContext(ServerStyleContext);
const clientStyleData = useContext(ClientStyleContext);
useEffect(() => {
emotionCache.sheet.container = document.head;
const tags = emotionCache.sheet.tags;
emotionCache.sheet.flush();
tags.forEach((tag) => {
(emotionCache.sheet as any)._insertTag(tag);
});
clientStyleData?.reset();
}, []);
const helmetContext: { [k: string]: any } = {};
const body = (
<StrictMode>
<ChakraProvider
colorModeManager={cookieStorageManagerSSR(
typeof document === "undefined" ? "" : document.cookie
)}
theme={theme}
>
<HelmetProvider>
<div className="App">
<Navigation {...loaderData} />
{children}
<Scripts />
<LiveReload />
</div>
</HelmetProvider>
</ChakraProvider>
</StrictMode>
);
const { helmet } = helmetContext;
return (
<html lang="en-US">
<head>
<Links />
{serverStyleData?.map(({ key, ids, css }) => (
<style
key={key}
data-emotion={`${key} ${ids.join(" ")}`}
dangerouslySetInnerHTML={{ __html: css }}
/>
))}
<meta charSet="UTF-8" />
{loaderData.dsn ? (
<meta name="dsn" content={loaderData.dsn} />
) : null}
<meta name="theme-color" content="#00a8f8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
{helmet?.meta?.toString()}
{helmet?.title?.toString() ?? <title>Car Crushers</title>}
</head>
<body>{body}</body>
</html>
);
}
);
return <Document>{child}</Document>;
}
export default function () {
const loaderData = useLoaderData<typeof loader>();
return getMarkup(loaderData, <Outlet />);
}