37 lines
1.2 KiB
TypeScript
37 lines
1.2 KiB
TypeScript
import { useEffect } from 'react'
|
|
import { Navigate, Outlet, useLocation } from 'react-router-dom'
|
|
|
|
import { PageLoading } from '@/components/PageLoading'
|
|
import { getAdminBasePath, getAdminLoginPath } from '@/shared/api/adminClient'
|
|
import { useAdminSessionStore } from '@/stores/adminSession'
|
|
|
|
export function AdminGuard() {
|
|
const location = useLocation()
|
|
const admin = useAdminSessionStore(state => state.admin)
|
|
const loaded = useAdminSessionStore(state => state.loaded)
|
|
const loading = useAdminSessionStore(state => state.loading)
|
|
const loadMe = useAdminSessionStore(state => state.loadMe)
|
|
|
|
useEffect(() => {
|
|
if (!loaded && !loading) {
|
|
void loadMe()
|
|
}
|
|
}, [loaded, loading, loadMe])
|
|
|
|
if (!loaded || loading) {
|
|
return <PageLoading tip="正在核对后台会话…" />
|
|
}
|
|
|
|
if (!admin) {
|
|
const redirect = encodeURIComponent(location.pathname + location.search)
|
|
return <Navigate to={`${getAdminLoginPath()}?redirect=${redirect}`} replace />
|
|
}
|
|
|
|
const changePasswordPath = `${getAdminBasePath()}/change-password`
|
|
if (admin.password_must_change && location.pathname !== changePasswordPath) {
|
|
return <Navigate to={changePasswordPath} replace />
|
|
}
|
|
|
|
return <Outlet />
|
|
}
|