import { useState, useEffect } from 'react'; import SplitView from '@/components/login/SplitView'; import CenteredCard from '@/components/login/CenteredCard'; import SidePanel from '@/components/login/SidePanel'; import FullImage from '@/components/login/FullImage'; import MinimalDark from '@/components/login/MinimalDark'; export type LoginStyle = 'split' | 'centered' | 'sidepanel' | 'fullimage' | 'minimal'; const LOGIN_STYLES: Record = { split: SplitView, centered: CenteredCard, sidepanel: SidePanel, fullimage: FullImage, minimal: MinimalDark, }; export const LOGIN_STYLE_OPTIONS: { id: LoginStyle; name: string; desc: string }[] = [ { id: 'split', name: '经典分屏', desc: '左右分屏布局,功能特性展示' }, { id: 'centered', name: '居中卡片', desc: '渐变背景,居中登录卡片' }, { id: 'sidepanel', name: '侧边面板', desc: '左侧品牌面板 + 右侧表单' }, { id: 'fullimage', name: '全屏背景', desc: '科技背景,毛玻璃卡片' }, { id: 'minimal', name: '极简暗色', desc: '极致简约,纯暗色风格' }, ]; export default function LoginPage() { const [style, setStyle] = useState('split'); const [ready, setReady] = useState(false); useEffect(() => { // Try backend first (cross-browser), fallback to localStorage fetch('/api/v1/public/login-style') .then(r => r.json()) .then(data => { const s = data?.login_style as LoginStyle; if (s && s in LOGIN_STYLES) { setStyle(s); } else { const stored = localStorage.getItem('login-style') as LoginStyle | null; if (stored && stored in LOGIN_STYLES) setStyle(stored); } }) .catch(() => { const stored = localStorage.getItem('login-style') as LoginStyle | null; if (stored && stored in LOGIN_STYLES) setStyle(stored); }) .finally(() => setReady(true)); }, []); if (!ready) return null; // avoid flash const Component = LOGIN_STYLES[style] || SplitView; return ; }