feat: 5种专业登录页风格 + 外观设置 + 文档全面更新

- 新增 5 种登录页组件: SplitView/CenteredCard/SidePanel/FullImage/MinimalDark
- 提取 useLogin hook 共享登录逻辑
- LoginPage 改为风格分发器, localStorage(login-style) 控制渲染
- SettingsPage 新增外观设置 tab: 主题切换 + 登录风格选择器(含缩略图预览)
- AppearanceSettings 组件: 5 种风格卡片式切换
- 文档全面更新为 Go/Gin 架构:
  - ARCHITECTURE.md: Go 项目结构/handler/GORM 模型/中间件/LDAP/驱动矩阵
  - FEATURES.md: v0.3.1 功能清单含登录主题系统
  - ROADMAP.md: Python→Go 迁移历史 + Sprint 计划
This commit is contained in:
logan committed 2026-05-26 21:16:36 +08:00
1 parent f2e93a09c0
commit 14e394fb09
12 files changed
+1147 -639

No files matched your search

@@ -0,0 +1,74 @@
import { useLogin } from '@/hooks/useLogin';
import { useTheme } from '@/hooks/useTheme';
import { Sun, Moon, Database } from 'lucide-react';
export default function SidePanel() {
const { username, password, loading, error, setUsername, setPassword, handleLogin } = useLogin();
const { toggleTheme, isDark } = useTheme();
return (
<div style={{ display: 'flex', minHeight: '100vh', background: 'var(--dg-bg-primary)', color: 'var(--dg-text-primary)' }}>
<button
onClick={toggleTheme}
style={{ position: 'fixed', top: 20, right: 20, zIndex: 50, background: 'var(--dg-bg-tertiary)', border: 'none', borderRadius: 8, padding: 8, cursor: 'pointer', color: 'var(--dg-text-secondary)' }}
>
{isDark ? <Sun size={18} /> : <Moon size={18} />}
</button>
{/* Left Panel — 40% */}
<div
className="dg-gradient-br"
style={{ width: '40%', display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center', padding: 48, position: 'relative', overflow: 'hidden' }}
>
{/* Decorative circles */}
<div style={{ position: 'absolute', top: '15%', left: '10%', width: 80, height: 80, borderRadius: '50%', background: 'rgba(255,255,255,0.06)' }} />
<div style={{ position: 'absolute', bottom: '20%', right: '15%', width: 120, height: 120, borderRadius: '50%', background: 'rgba(255,255,255,0.04)' }} />
<div style={{ position: 'absolute', top: '55%', left: '60%', width: 40, height: 40, borderRadius: '50%', background: 'rgba(255,255,255,0.07)' }} />
<div style={{ position: 'absolute', top: '30%', right: '30%', width: 12, height: 12, borderRadius: '50%', background: 'rgba(255,255,255,0.12)' }} />
<div style={{ position: 'absolute', bottom: '40%', left: '25%', width: 8, height: 8, borderRadius: '50%', background: 'rgba(255,255,255,0.10)' }} />
<div style={{ position: 'relative', zIndex: 2, textAlign: 'center', maxWidth: 320 }}>
<Database size={40} style={{ color: '#fff', marginBottom: 20 }} />
<h1 style={{ fontSize: 26, fontWeight: 700, color: '#fff', marginBottom: 12 }}>SQL Audit Platform</h1>
<p style={{ color: 'rgba(255,255,255,0.7)', fontSize: 14, lineHeight: 1.6 }}>
Empowering teams with intelligent SQL auditing, real-time compliance monitoring, and actionable insights for database security.
</p>
</div>
</div>
{/* Right Panel — Login Form */}
<div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 48 }}>
<form onSubmit={handleLogin} style={{ width: '100%', maxWidth: 360, display: 'flex', flexDirection: 'column', gap: 20 }}>
<h2 style={{ fontSize: 22, fontWeight: 600, marginBottom: 4 }}>Welcome back</h2>
<p style={{ color: 'var(--dg-text-muted)', fontSize: 14, marginBottom: 8 }}>Sign in to access your dashboard</p>
{error && <div style={{ color: '#f87171', fontSize: 13 }}>{error}</div>}
<input
type="text"
placeholder="Username"
value={username}
onChange={(e) => setUsername(e.target.value)}
style={{ padding: '10px 14px', borderRadius: 8, background: 'var(--dg-bg-tertiary)', border: '1px solid var(--dg-border)', color: 'var(--dg-text-primary)', fontSize: 14, outline: 'none' }}
/>
<input
type="password"
placeholder="Password"
value={password}
onChange={(e) => setPassword(e.target.value)}
style={{ padding: '10px 14px', borderRadius: 8, background: 'var(--dg-bg-tertiary)', border: '1px solid var(--dg-border)', color: 'var(--dg-text-primary)', fontSize: 14, outline: 'none' }}
/>
<button
type="submit"
disabled={loading || !username || !password}
className="dg-gradient-bg"
style={{ padding: '10px 14px', borderRadius: 8, border: 'none', color: '#fff', fontWeight: 600, fontSize: 14, cursor: loading || !username || !password ? 'not-allowed' : 'pointer', opacity: loading || !username || !password ? 0.6 : 1 }}
>
{loading ? 'Signing in…' : 'Sign in'}
</button>
</form>
</div>
</div>
);
}