2022-02-14 17:05:17 +01:00
|
|
|
import {
|
|
|
|
|
LinksFunction,
|
|
|
|
|
LoaderFunction,
|
|
|
|
|
MetaFunction,
|
|
|
|
|
useLoaderData,
|
|
|
|
|
} from "remix";
|
|
|
|
|
import type { User, Team } from "@prisma/client";
|
2022-02-10 10:44:44 +01:00
|
|
|
import { Links, LiveReload, Outlet, useCatch, Meta, Scripts } from "remix";
|
2022-02-14 17:05:17 +01:00
|
|
|
import { getUser } from "./utils/session.server";
|
2022-02-10 10:44:44 +01:00
|
|
|
|
|
|
|
|
import styles from "./tailwind.css";
|
2022-02-14 13:23:06 +01:00
|
|
|
import headerStyles from "./styles/header.css";
|
2022-02-10 10:44:44 +01:00
|
|
|
|
|
|
|
|
export const links: LinksFunction = () => {
|
2022-02-14 13:23:06 +01:00
|
|
|
return [
|
|
|
|
|
{ rel: "stylesheet", href: styles },
|
|
|
|
|
{ rel: "stylesheet", href: headerStyles },
|
|
|
|
|
];
|
2022-02-10 10:44:44 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const meta: MetaFunction = () => {
|
|
|
|
|
const description = `Track and split shared expenses with friends and family.`;
|
|
|
|
|
return {
|
|
|
|
|
description,
|
|
|
|
|
keywords:
|
|
|
|
|
"Explit,expenses,split,flatmate,friends,family,payments,debts,money",
|
|
|
|
|
"twitter:creator": "@rawmaterial_it",
|
|
|
|
|
"twitter:site": "@rawmaterial_it",
|
|
|
|
|
"twitter:title": "Explit",
|
|
|
|
|
"twitter:description": description,
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
2022-02-14 17:05:17 +01:00
|
|
|
type LoaderData = {
|
|
|
|
|
user: (User & { team: Team & { members: User[] } }) | null;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const loader: LoaderFunction = async ({ request }) => {
|
|
|
|
|
const user = await getUser(request);
|
|
|
|
|
|
|
|
|
|
const data: LoaderData = {
|
|
|
|
|
user,
|
|
|
|
|
};
|
|
|
|
|
return data;
|
|
|
|
|
};
|
|
|
|
|
|
2022-02-10 10:44:44 +01:00
|
|
|
function Document({
|
|
|
|
|
children,
|
|
|
|
|
title = `Explit`,
|
|
|
|
|
}: {
|
|
|
|
|
children: React.ReactNode;
|
|
|
|
|
title?: string;
|
|
|
|
|
}) {
|
2022-02-14 17:05:17 +01:00
|
|
|
const data = useLoaderData<LoaderData>();
|
|
|
|
|
|
2022-02-10 10:44:44 +01:00
|
|
|
return (
|
2022-02-14 17:05:17 +01:00
|
|
|
<html lang="en" data-theme={data?.user?.theme ?? "dark"}>
|
2022-02-10 10:44:44 +01:00
|
|
|
<head>
|
|
|
|
|
<meta charSet="utf-8" />
|
2022-02-14 11:47:47 +01:00
|
|
|
<meta
|
|
|
|
|
name="viewport"
|
|
|
|
|
content="width=device-width, initial-scale=1"
|
|
|
|
|
></meta>
|
2022-02-10 10:44:44 +01:00
|
|
|
<Meta />
|
|
|
|
|
<title>{title}</title>
|
|
|
|
|
<Links />
|
|
|
|
|
</head>
|
2022-02-14 13:23:06 +01:00
|
|
|
<body className="bg-base-300 m-0 min-h-screen p-3">
|
2022-02-10 10:44:44 +01:00
|
|
|
{children}
|
|
|
|
|
<Scripts />
|
|
|
|
|
{process.env.NODE_ENV === "development" ? <LiveReload /> : null}
|
|
|
|
|
</body>
|
|
|
|
|
</html>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default function App() {
|
|
|
|
|
return (
|
|
|
|
|
<Document>
|
|
|
|
|
<Outlet />
|
|
|
|
|
</Document>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function CatchBoundary() {
|
|
|
|
|
const caught = useCatch();
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Document title={`${caught.status} ${caught.statusText}`}>
|
|
|
|
|
<div className="error-container">
|
|
|
|
|
<h1>
|
|
|
|
|
{caught.status} {caught.statusText}
|
|
|
|
|
</h1>
|
|
|
|
|
</div>
|
|
|
|
|
</Document>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function ErrorBoundary({ error }: { error: Error }) {
|
|
|
|
|
console.error(error);
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Document title="Uh-oh!">
|
|
|
|
|
<div className="error-container">
|
|
|
|
|
<h1>App Error</h1>
|
|
|
|
|
<pre>{error.message}</pre>
|
|
|
|
|
</div>
|
|
|
|
|
</Document>
|
|
|
|
|
);
|
|
|
|
|
}
|