61 lines
2.3 KiB
TypeScript
61 lines
2.3 KiB
TypeScript
import { useEffect } from "react";
|
|
import { LoaderFunctionArgs, redirect } from "react-router";
|
|
import { Outlet } from "react-router";
|
|
import AppLayout from "~/components/app/AppLayout";
|
|
import UrlUtils from "~/utils/app/UrlUtils";
|
|
import { adminPath } from "~/utils/app/CanonicalUrlUtils";
|
|
import { loadAdminData } from "~/utils/data/.server/adminData";
|
|
import ServerError from "~/components/ui/errors/ServerError";
|
|
import { withMetrics } from "~/lib/metrics/ssr";
|
|
import { createMetrics } from "~/modules/metrics/services/.server/MetricTracker";
|
|
import { getTranslations } from "~/locale/i18next.server";
|
|
import { getHostRoutingContextFromRequest } from "~/utils/app/HostRouting.server";
|
|
import { loadRequiredWebConfig } from "@toolctrl/config";
|
|
import { absoluteAdminPath } from "~/utils/app/CrossHostUrls";
|
|
|
|
export function isAdminRootPath(pathname: string) {
|
|
const strippedPathname = UrlUtils.stripTrailingSlash(pathname);
|
|
return strippedPathname === "" || strippedPathname === adminPath(undefined, { mode: "host-aware" });
|
|
}
|
|
|
|
export function adminRootRedirectTarget() {
|
|
return adminPath("dashboard", { mode: "host-aware" });
|
|
}
|
|
|
|
export const loader = withMetrics("admin-root", async ({ request, params }: LoaderFunctionArgs) => {
|
|
const { time, getServerTimingHeader } = await createMetrics({ request, params }, "admin");
|
|
const url = new URL(request.url);
|
|
const hostContext = getHostRoutingContextFromRequest(request);
|
|
if (hostContext !== "admin" && hostContext !== "unknown") {
|
|
const routing = loadRequiredWebConfig().routing;
|
|
throw redirect(absoluteAdminPath(routing, `${url.pathname}${url.search}${url.hash}`), { headers: getServerTimingHeader() });
|
|
}
|
|
if (isAdminRootPath(url.pathname)) {
|
|
throw redirect(adminRootRedirectTarget(), { headers: getServerTimingHeader() });
|
|
}
|
|
const { t } = await getTranslations(request);
|
|
const data = await loadAdminData({ request, t }, time);
|
|
return Response.json(data, { headers: getServerTimingHeader() });
|
|
});
|
|
|
|
export default function AdminRoute() {
|
|
useEffect(() => {
|
|
try {
|
|
// @ts-ignore
|
|
$crisp.push(["do", "chat:hide"]);
|
|
} catch {
|
|
// ignore
|
|
}
|
|
}, []);
|
|
|
|
return (
|
|
<AppLayout layout="admin">
|
|
<Outlet />
|
|
</AppLayout>
|
|
);
|
|
}
|
|
|
|
export function ErrorBoundary() {
|
|
return <ServerError />;
|
|
}
|