import { useEffect } from "react";
import { Links, Meta, Outlet, Scripts, ScrollRestoration, isRouteErrorResponse, useLocation, Form, Link } from "react-router";
import type { LinksFunction } from "react-router";
import type { Route } from "./+types/root";
import * as Sentry from "@sentry/react";
import { useTranslation } from "react-i18next";
import { initI18n } from "@trails-cool/i18n";
import { getSessionUser } from "~/lib/auth.server";
import stylesheet from "@trails-cool/ui/styles.css?url";
initI18n();
export const links: LinksFunction = () => [{ rel: "stylesheet", href: stylesheet }];
export function Layout({ children }: { children: React.ReactNode }) {
return (
{children}
);
}
export async function loader({ request }: Route.LoaderArgs) {
const user = await getSessionUser(request);
return { user: user ? { id: user.id, username: user.username } : null };
}
function NavBar({ user }: { user: { id: string; username: string } | null }) {
const { t } = useTranslation("journal");
const location = useLocation();
const isActive = (path: string) =>
location.pathname === path || location.pathname.startsWith(path + "/");
const linkClass = (path: string) =>
`text-sm font-medium ${
isActive(path)
? "text-blue-600"
: "text-gray-600 hover:text-gray-900"
}`;
return (
);
}
export default function App({ loaderData }: Route.ComponentProps) {
const user = loaderData?.user;
useEffect(() => {
if (user) {
Sentry.setUser({ id: user.id, username: user.username });
} else {
Sentry.setUser(null);
}
}, [user]);
return (
<>
>
);
}
export function ErrorBoundary({ error }: Route.ErrorBoundaryProps) {
Sentry.captureException(error);
const { t } = useTranslation();
if (isRouteErrorResponse(error)) {
return (
{error.status}
{error.status === 404 && t("pageNotFound")}
{error.status === 503 && t("serviceUnavailable")}
{error.status !== 404 && error.status !== 503 && (error.statusText || t("error"))}
{t("goHome")}
);
}
return (
{t("error")}
{error instanceof Error ? error.message : t("error")}
{t("goHome")}
);
}