前端重构实现
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
import { useEffect } from 'react';
|
||||
import { BrowserRouter, Routes, Route, Navigate, useNavigate, useLocation } from 'react-router-dom';
|
||||
import { AnimatePresence, motion } from 'framer-motion';
|
||||
import { Background } from './components/layout';
|
||||
import Loader from './components/Loader';
|
||||
import LoginPage from './pages/LoginPage';
|
||||
import OnboardingPage from './pages/OnboardingPage';
|
||||
import DashboardPage from './pages/DashboardPage';
|
||||
import useStore from './store/useStore';
|
||||
|
||||
/**
|
||||
* 路由守卫组件
|
||||
* 根据登录状态和注册完成状态进行路由重定向
|
||||
*/
|
||||
const ProtectedRoute = ({ children, requireAuth = false, requireOnboarding = false }) => {
|
||||
const { isLoggedIn, registrationData } = useStore();
|
||||
const navigate = useNavigate();
|
||||
|
||||
// 检查是否完成入站流程
|
||||
const hasCompletedOnboarding = registrationData.nickname && registrationData.future?.vision;
|
||||
|
||||
useEffect(() => {
|
||||
if (requireAuth && !isLoggedIn) {
|
||||
navigate('/', { replace: true });
|
||||
} else if (requireOnboarding && !hasCompletedOnboarding) {
|
||||
navigate('/onboarding', { replace: true });
|
||||
}
|
||||
}, [isLoggedIn, hasCompletedOnboarding, requireAuth, requireOnboarding, navigate]);
|
||||
|
||||
if (requireAuth && !isLoggedIn) {
|
||||
return <Loader text="正在验证身份..." />;
|
||||
}
|
||||
|
||||
if (requireOnboarding && !hasCompletedOnboarding) {
|
||||
return <Loader text="正在加载..." />;
|
||||
}
|
||||
|
||||
return children;
|
||||
};
|
||||
|
||||
/**
|
||||
* 页面过渡动画包装器
|
||||
*/
|
||||
const PageTransition = ({ children }) => {
|
||||
return (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0, y: -20 }}
|
||||
transition={{
|
||||
duration: 0.4,
|
||||
ease: [0.25, 0.46, 0.45, 0.94]
|
||||
}}
|
||||
className="w-full h-full"
|
||||
>
|
||||
{children}
|
||||
</motion.div>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* 动画路由组件
|
||||
*/
|
||||
const AnimatedRoutes = () => {
|
||||
const location = useLocation();
|
||||
const { isLoggedIn, registrationData } = useStore();
|
||||
|
||||
// 检查是否完成入站流程
|
||||
const hasCompletedOnboarding = registrationData.nickname && registrationData.future?.vision;
|
||||
|
||||
return (
|
||||
<AnimatePresence mode="wait">
|
||||
<Routes location={location} key={location.pathname}>
|
||||
{/* 登录页 */}
|
||||
<Route
|
||||
path="/"
|
||||
element={
|
||||
isLoggedIn ? (
|
||||
hasCompletedOnboarding ? (
|
||||
<Navigate to="/dashboard" replace />
|
||||
) : (
|
||||
<Navigate to="/onboarding" replace />
|
||||
)
|
||||
) : (
|
||||
<PageTransition>
|
||||
<LoginPage />
|
||||
</PageTransition>
|
||||
)
|
||||
}
|
||||
/>
|
||||
|
||||
{/* 入站流程页 */}
|
||||
<Route
|
||||
path="/onboarding"
|
||||
element={
|
||||
<ProtectedRoute requireAuth>
|
||||
<PageTransition>
|
||||
<OnboardingPage />
|
||||
</PageTransition>
|
||||
</ProtectedRoute>
|
||||
}
|
||||
/>
|
||||
|
||||
{/* 仪表盘页 */}
|
||||
<Route
|
||||
path="/dashboard"
|
||||
element={
|
||||
<ProtectedRoute requireAuth requireOnboarding>
|
||||
<PageTransition>
|
||||
<DashboardPage />
|
||||
</PageTransition>
|
||||
</ProtectedRoute>
|
||||
}
|
||||
/>
|
||||
|
||||
{/* 404 重定向 */}
|
||||
<Route path="*" element={<Navigate to="/" replace />} />
|
||||
</Routes>
|
||||
</AnimatePresence>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* App 主组件
|
||||
*/
|
||||
function App() {
|
||||
return (
|
||||
<BrowserRouter>
|
||||
{/* 动态背景 */}
|
||||
<Background />
|
||||
|
||||
{/* 主容器 */}
|
||||
<main className="relative z-10 min-h-screen flex flex-col items-center justify-center p-4 md:p-8">
|
||||
<AnimatedRoutes />
|
||||
</main>
|
||||
</BrowserRouter>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
Reference in New Issue
Block a user