first commit
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
import { AuthView } from "../components/AuthView";
|
||||
import { AppShell } from "../components/AppShell";
|
||||
import { EmptyState, LoadingState } from "../components/StateViews";
|
||||
import type { PageId, PageParams } from "../contracts/page";
|
||||
import { pageRegistry } from "../pages/pageRegistry";
|
||||
import { canAccessRoute, defaultPageForUser, hashForPage, navigationRoutesForUser } from "../routes/routes";
|
||||
import { initialNavigationState, type NavigationState } from "../stores/navigation";
|
||||
import { useOperationTracker } from "../stores/operations";
|
||||
import { useSession } from "../stores/session";
|
||||
|
||||
export function App() {
|
||||
const session = useSession();
|
||||
const user = session.user;
|
||||
const [navigation, setNavigation] = useState<NavigationState | undefined>();
|
||||
const operations = useOperationTracker();
|
||||
|
||||
useEffect(() => {
|
||||
if (session.loaded && user) {
|
||||
const nextNavigation = initialNavigationState(user);
|
||||
setNavigation(nextNavigation);
|
||||
if (typeof window !== "undefined") {
|
||||
const nextHash = hashForPage(nextNavigation.pageId, nextNavigation.params);
|
||||
if (window.location.hash !== nextHash) {
|
||||
window.history.replaceState(null, "", nextHash);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [session.loaded, user]);
|
||||
|
||||
useEffect(() => {
|
||||
function syncPageFromHash() {
|
||||
if (user) {
|
||||
setNavigation(initialNavigationState(user));
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("hashchange", syncPageFromHash);
|
||||
window.addEventListener("popstate", syncPageFromHash);
|
||||
return () => {
|
||||
window.removeEventListener("hashchange", syncPageFromHash);
|
||||
window.removeEventListener("popstate", syncPageFromHash);
|
||||
};
|
||||
}, [user]);
|
||||
|
||||
function handleNavigate(pageId: PageId, params: PageParams = {}) {
|
||||
if (!user) {
|
||||
return;
|
||||
}
|
||||
const target: NavigationState = canAccessRoute(user, pageId) ? { pageId, params } : { pageId: defaultPageForUser(user), params: {} };
|
||||
setNavigation(target);
|
||||
if (typeof window !== "undefined") {
|
||||
window.history.replaceState(null, "", hashForPage(target.pageId, target.params));
|
||||
}
|
||||
}
|
||||
|
||||
if (!session.loaded) {
|
||||
return (
|
||||
<main className="auth-shell">
|
||||
<LoadingState label="正在加载身份状态…" />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
if (!user || !navigation) {
|
||||
return <AuthView session={session} />;
|
||||
}
|
||||
|
||||
const navRoutes = navigationRoutesForUser(user);
|
||||
const ActivePage = pageRegistry[navigation.pageId];
|
||||
const allowed = canAccessRoute(user, navigation.pageId);
|
||||
|
||||
return (
|
||||
<AppShell
|
||||
routes={navRoutes}
|
||||
currentPage={navigation.pageId}
|
||||
session={user}
|
||||
onNavigate={handleNavigate}
|
||||
>
|
||||
{allowed ? (
|
||||
<ActivePage
|
||||
session={user}
|
||||
params={navigation.params}
|
||||
operations={operations}
|
||||
onNavigate={handleNavigate}
|
||||
onLogout={session.logout}
|
||||
onProfileSave={session.updateProfile}
|
||||
onThemePreferenceSave={session.updateThemePreference}
|
||||
/>
|
||||
) : (
|
||||
<EmptyState
|
||||
title="没有访问权限"
|
||||
description="当前账号无权访问该区域。请返回你的默认工作台,或联系平台管理员调整权限。"
|
||||
actionLabel="返回工作台"
|
||||
onAction={() => handleNavigate(defaultPageForUser(user))}
|
||||
/>
|
||||
)}
|
||||
</AppShell>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user