72 lines
3.8 KiB
TypeScript
72 lines
3.8 KiB
TypeScript
import { StrictMode, type ReactNode } from "react";
|
|
import { createRoot } from "react-dom/client";
|
|
|
|
import { registerPublicAssetServiceWorker } from "./public-asset-cache.js";
|
|
import { AdminAuthPage } from "./admin-auth.js";
|
|
import { UserAuthPage } from "./user-auth.js";
|
|
import { AccountSettingsPage } from "./account-settings.js";
|
|
import { AdminUsersPage } from "./admin-users.js";
|
|
import { AdminModelsPage } from "./admin-models.js";
|
|
import { CreditsPage } from "./credits-page.js";
|
|
import { ProjectDetailPage, ProjectsPage, WorkspacePage } from "./project-pages.js";
|
|
import { EditorPage } from "./editor-page.js";
|
|
import { AdminOverviewPage, AdminPlaceholderPage, AdminProtectedRoute } from "./admin-shell.js";
|
|
|
|
const root = document.getElementById("root");
|
|
|
|
if (!root) {
|
|
throw new Error("Dada web root element is missing.");
|
|
}
|
|
|
|
// Cache failure leaves public assets network-backed and must not create alternate persistence.
|
|
void registerPublicAssetServiceWorker().catch(() => undefined);
|
|
|
|
const appRoot = createRoot(root);
|
|
let authRevision = 0;
|
|
|
|
function renderAuthenticationEntry() {
|
|
authRevision += 1;
|
|
const editorProject = window.location.pathname.match(/^\/app\/projects\/([0-9a-f-]{36})\/editor$/i);
|
|
const projectDetail = window.location.pathname.match(/^\/app\/projects\/([0-9a-f-]{36})$/i);
|
|
let authenticationPage;
|
|
if (window.location.pathname === "/app/settings") authenticationPage = <AccountSettingsPage key={authRevision} />;
|
|
else if (window.location.pathname === "/app/credits") authenticationPage = <CreditsPage key={authRevision} />;
|
|
else if (editorProject?.[1]) authenticationPage = <EditorPage key={authRevision} projectId={editorProject[1]} />;
|
|
else if (projectDetail?.[1]) authenticationPage = <ProjectDetailPage key={authRevision} projectId={projectDetail[1]} />;
|
|
else if (window.location.pathname === "/app/projects") authenticationPage = <ProjectsPage key={authRevision} />;
|
|
else if (window.location.pathname === "/app") authenticationPage = <WorkspacePage key={authRevision} />;
|
|
else if (window.location.pathname === "/admin/login") authenticationPage = <AdminAuthPage key={authRevision} />;
|
|
else if (window.location.pathname.startsWith("/admin")) {
|
|
const adminPages: Record<string, { content: ReactNode; title: string }> = {
|
|
"/admin": { content: <AdminOverviewPage />, title: "运营总览" },
|
|
"/admin/assets": { content: <AdminPlaceholderPage title="素材" />, title: "素材" },
|
|
"/admin/audit": { content: <AdminPlaceholderPage title="审计" />, title: "审计" },
|
|
"/admin/generations": { content: <AdminPlaceholderPage title="生成记录" />, title: "生成记录" },
|
|
"/admin/invites": { content: <AdminPlaceholderPage title="邀请码" />, title: "邀请码" },
|
|
"/admin/models": { content: <AdminModelsPage />, title: "模型" },
|
|
"/admin/preview": { content: <AdminPlaceholderPage title="内部预览" />, title: "内部预览" },
|
|
"/admin/services-storage": { content: <AdminPlaceholderPage title="服务与存储" />, title: "服务与存储" },
|
|
"/admin/users": { content: <AdminUsersPage />, title: "用户与点数" },
|
|
};
|
|
const page = adminPages[window.location.pathname] ?? adminPages["/admin"]!;
|
|
authenticationPage = (
|
|
<AdminProtectedRoute currentPath={window.location.pathname} key={authRevision} title={page.title}>
|
|
{page.content}
|
|
</AdminProtectedRoute>
|
|
);
|
|
}
|
|
else authenticationPage = <UserAuthPage key={authRevision} />;
|
|
appRoot.render(
|
|
<StrictMode>
|
|
{authenticationPage}
|
|
</StrictMode>,
|
|
);
|
|
}
|
|
|
|
// Any authenticated surface can dispatch this after a revoked/invalid session response.
|
|
window.addEventListener("dada:session-invalid", () => {
|
|
if (window.location.pathname.startsWith("/app")) window.history.replaceState(null, "", "/");
|
|
renderAuthenticationEntry();
|
|
});
|
|
renderAuthenticationEntry();
|