fix: 侧边面板恢复 commit 35a014e 原始设计 — 左品牌+6功能卡片,右登录表单,白色主题友好

This commit is contained in:
logan committed 2026-05-27 18:15:18 +08:00
1 parent b4fa60bc68
commit f8b2266542
3 files changed
+115 -72

No files matched your search

+91 -53
View File
@@ -1,73 +1,111 @@
import { useLogin } from '@/hooks/useLogin';
import { useTheme } from '@/hooks/useTheme';
import { Sun, Moon, Database } from 'lucide-react';
import { Shield, Database, Code, GitBranch, Bell, History, UserCog, Sparkles, Sun, Moon } from 'lucide-react';
export default function SidePanel() {
const { username, password, loading, error, setUsername, setPassword, handleLogin } = useLogin();
const { toggleTheme, isDark } = useTheme();
const { theme, toggleTheme } = useTheme();
const features = [
{ icon: Database, title: '多数据库支持', desc: 'MySQL、PostgreSQL、Redis、MongoDB' },
{ icon: Code, title: '智能 SQL 审核', desc: '语法检查、规则校验、影响分析、自动评分' },
{ icon: GitBranch, title: '多级审批流程', desc: '会签、或签、条件审批灵活配置' },
{ icon: Bell, title: '多渠道通知', desc: '飞书、钉钉、企微、TG 即时推送' },
{ icon: History, title: '完整审计追踪', desc: '所有操作可追溯,支持 SQL 回滚' },
{ icon: UserCog, title: '细粒度权限', desc: 'RBAC 角色权限,字段级/行级访问控制' },
];
return (
<div style={{ display: 'flex', minHeight: '100vh', background: 'var(--dg-bg-primary)', color: 'var(--dg-text-primary)' }}>
<div className="min-h-screen flex bg-[var(--dg-bg-primary)] relative overflow-hidden">
{/* 背景装饰 */}
<div className="absolute inset-0 pointer-events-none">
<div className="absolute top-0 left-0 w-full h-full bg-[radial-gradient(ellipse_at_20%_20%,rgba(88,166,255,0.08)_0%,transparent_50%),radial-gradient(ellipse_at_80%_80%,rgba(137,87,229,0.08)_0%,transparent_50%)]" />
</div>
{/* 主题切换 */}
<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)' }}
className="absolute top-5 right-5 z-20 w-10 h-10 rounded-xl bg-[var(--dg-bg-tertiary)] border border-[var(--dg-border)] flex items-center justify-center text-[var(--dg-text-secondary)] hover:text-[var(--dg-text-primary)] hover:bg-[var(--dg-bg-hover)] transition-colors"
>
{isDark ? <Sun size={18} /> : <Moon size={18} />}
{theme === 'dark' ? <Sun className="w-5 h-5" /> : <Moon className="w-5 h-5" />}
</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审核平台</h1>
<p style={{ color: 'rgba(255,255,255,0.7)', fontSize: 14, lineHeight: 1.6 }}>
为团队提供智能 SQL 审核、实时合规监控与数据库安全保障。
{/* 左侧 */}
<div className="flex-1 flex flex-col justify-center px-16 relative z-10">
<div className="mb-10">
<div className="flex items-center gap-3 mb-6">
<div className="w-12 h-12 rounded-xl dg-gradient-br flex items-center justify-center">
<Shield className="w-7 h-7 text-white" />
</div>
<h1 className="text-5xl font-bold dg-gradient-text">
SQL-Platform
</h1>
</div>
<p className="text-lg text-[var(--dg-text-secondary)] leading-relaxed">
企业级数据审核与变更管理平台<br />
支持多数据库类型,提供完善的 SQL 审核、审批流程和审计追踪
</p>
</div>
<div className="grid grid-cols-2 gap-4">
{features.map((f, i) => (
<div key={i} className="flex items-start gap-3 p-4 rounded-xl bg-[var(--dg-bg-secondary)]/60 border border-[var(--dg-border)] hover:border-blue-500/50 hover:bg-[var(--dg-bg-secondary)] transition-all group">
<f.icon className="w-6 h-6 text-blue-400 mt-0.5 flex-shrink-0 group-hover:scale-110 transition-transform" />
<div>
<h4 className="text-sm font-semibold mb-1">{f.title}</h4>
<p className="text-xs text-[var(--dg-text-secondary)]">{f.desc}</p>
</div>
</div>
))}
</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 }}>欢迎回来</h2>
<p style={{ color: 'var(--dg-text-muted)', fontSize: 14, marginBottom: 8 }}>登录以访问控制台</p>
{/* 右侧 */}
<div className="w-[480px] flex flex-col justify-center px-16 bg-[var(--dg-bg-secondary)]/80 backdrop-blur-xl border-l border-[var(--dg-border)] relative z-10">
<div className="w-full max-w-sm mx-auto">
<div className="flex items-center gap-2 mb-2">
<Sparkles className="w-5 h-5 text-blue-400" />
<h2 className="text-2xl font-bold">欢迎回来</h2>
</div>
<p className="text-sm text-[var(--dg-text-secondary)] mb-8">请登录您的账户以继续</p>
{error && <div style={{ color: '#f87171', fontSize: 13 }}>{error}</div>}
<input
type="text"
placeholder="用户名"
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="密码"
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 ? '登录中…' : '登录'}
</button>
</form>
<form onSubmit={handleLogin} className="space-y-4">
<div>
<label className="block text-sm font-medium mb-2">用户名</label>
<div className="relative">
<UserCog className="absolute left-3.5 top-1/2 -translate-y-1/2 w-4 h-4 text-[var(--dg-text-muted)]" />
<input
className="w-full pl-10 pr-4 py-3 bg-[var(--dg-bg-tertiary)] border border-[var(--dg-border)] rounded-lg text-sm focus:border-blue-400 focus:outline-none focus:ring-1 focus:ring-blue-400/20 transition-all"
placeholder="请输入用户名"
value={username}
onChange={e => setUsername(e.target.value)}
/>
</div>
</div>
<div>
<label className="block text-sm font-medium mb-2">密码</label>
<div className="relative">
<Shield className="absolute left-3.5 top-1/2 -translate-y-1/2 w-4 h-4 text-[var(--dg-text-muted)]" />
<input
type="password"
className="w-full pl-10 pr-4 py-3 bg-[var(--dg-bg-tertiary)] border border-[var(--dg-border)] rounded-lg text-sm focus:border-blue-400 focus:outline-none focus:ring-1 focus:ring-blue-400/20 transition-all"
placeholder="请输入密码"
value={password}
onChange={e => setPassword(e.target.value)}
/>
</div>
</div>
<button
type="submit"
disabled={loading || !username || !password}
className="w-full py-3 dg-gradient-bg rounded-lg text-sm font-semibold text-white hover:opacity-90 disabled:opacity-50 disabled:cursor-not-allowed transition-all flex items-center justify-center gap-2"
>
{loading ? (
<div className="w-5 h-5 border-2 border-white/30 border-t-white rounded-full animate-spin" />
) : '登录'}
</button>
{error && <p className="text-xs text-red-400 text-center mt-2">{error}</p>}
</form>
</div>
</div>
</div>
);
+23 -18
View File
@@ -9,7 +9,7 @@ import { toast } from '@/hooks/useToast';
const LOGIN_PREVIEW_COLORS: Record<LoginStyle, { bg: string; accent: string; label: string }> = {
split: { bg: 'linear-gradient(135deg, #080c14 0%, #0c1420 100%)', accent: '#00d4aa', label: '晶格科技' },
centered: { bg: 'linear-gradient(180deg, #0a0a1a 0%, #1a1035 50%, #2d1810 100%)', accent: '#fbbf24', label: '晨曦微光' },
sidepanel: { bg: 'linear-gradient(180deg, #111827 0%, #1f2937 100%)', accent: '#6366f1', label: '经典侧边' },
sidepanel: { bg: 'linear-gradient(135deg, rgba(88,166,255,0.08), rgba(137,87,229,0.08))', accent: '#3b82f6', label: '功能展示' },
fullimage: { bg: '#0d1117', accent: '#6366f1', label: 'GitHub/AWS' },
minimal: { bg: 'linear-gradient(160deg, #0a0a1a 0%, #0f0a2a 40%, #150825 70%, #0a0a1a 100%)', accent: '#ec4899', label: 'Premium Dark' },
aurora: { bg: 'linear-gradient(180deg, #050810 0%, #0a0e1a 30%, #0d1425 60%, #080c14 100%)', accent: '#10b981', label: '极光之境' },
@@ -177,23 +177,28 @@ export default function AppearanceSettings() {
</div>
)}
{opt.id === 'sidepanel' && (
<div className="absolute inset-0 flex">
<div className="w-[40%] relative overflow-hidden flex flex-col items-center justify-center" style={{ background: 'linear-gradient(135deg, #111827, #1f2937)' }}>
{/* Decorative circles */}
<div className="absolute" style={{ top: '15%', left: '10%', width: 16, height: 16, borderRadius: '50%', background: 'rgba(255,255,255,0.06)' }} />
<div className="absolute" style={{ bottom: '20%', right: '10%', width: 24, height: 24, borderRadius: '50%', background: 'rgba(255,255,255,0.04)' }} />
<div className="absolute" style={{ top: '55%', left: '55%', width: 8, height: 8, borderRadius: '50%', background: 'rgba(255,255,255,0.07)' }} />
{/* Logo + text */}
<div className="w-3 h-3 rounded-sm mb-1" style={{ background: '#6366f1' }} />
<div className="w-8 h-0.5 rounded-sm" style={{ background: 'rgba(255,255,255,0.7)' }} />
<div className="w-12 h-0.5 rounded-sm mt-0.5" style={{ background: 'rgba(255,255,255,0.3)' }} />
</div>
<div className="flex-1 p-2 flex flex-col justify-center gap-0.5" style={{ background: 'var(--dg-bg-primary, #0a0a1a)' }}>
<div className="w-4 h-0.5 rounded-sm" style={{ background: 'rgba(255,255,255,0.3)' }} />
<div className="w-8 h-0.5 rounded-sm" style={{ background: 'rgba(255,255,255,0.1)' }} />
<div className="w-full h-0.5 rounded-sm" style={{ background: 'rgba(255,255,255,0.08)' }} />
<div className="w-full h-0.5 rounded-sm" style={{ background: 'rgba(255,255,255,0.08)' }} />
<div className="w-full h-1 rounded-sm mt-0.5" style={{ background: '#6366f1', opacity: 0.5 }} />
<div className="absolute inset-0">
<div className="absolute inset-0" style={{ background: 'radial-gradient(ellipse at 20% 20%, rgba(88,166,255,0.08), transparent 50%), radial-gradient(ellipse at 80% 80%, rgba(137,87,229,0.08), transparent 50%)' }} />
<div className="absolute inset-0 flex">
{/* Left: brand + feature cards */}
<div className="flex-1 p-1.5 flex flex-col justify-center gap-0.5">
<div className="flex items-center gap-0.5 mb-0.5">
<div className="w-2 h-2 rounded-sm" style={{ background: 'linear-gradient(135deg, #3b82f6, #8b5cf6)' }} />
<div className="w-6 h-0.5 rounded-sm" style={{ background: 'var(--dg-text-secondary, rgba(255,255,255,0.5))' }} />
</div>
<div className="grid grid-cols-2 gap-0.5">
{[0,1,2,3].map(i => (
<div key={i} className="h-2 rounded-sm" style={{ background: 'var(--dg-bg-tertiary, rgba(255,255,255,0.05))' }} />
))}
</div>
</div>
{/* Right: login form */}
<div className="w-[35%] p-1 flex flex-col justify-center gap-0.5" style={{ background: 'var(--dg-bg-secondary, rgba(255,255,255,0.03))' }}>
<div className="w-3 h-0.5 rounded-sm" style={{ background: 'rgba(255,255,255,0.3)' }} />
<div className="w-full h-0.5 rounded-sm" style={{ background: 'var(--dg-bg-tertiary, rgba(255,255,255,0.08))' }} />
<div className="w-full h-0.5 rounded-sm" style={{ background: 'var(--dg-bg-tertiary, rgba(255,255,255,0.08))' }} />
<div className="w-full h-0.5 rounded-sm mt-0.5" style={{ background: '#3b82f6', opacity: 0.5 }} />
</div>
</div>
</div>
)}
+1 -1
View File
@@ -28,7 +28,7 @@ const LOGIN_STYLES: Record<LoginStyle, React.ComponentType> = {
export const LOGIN_STYLE_OPTIONS: { id: LoginStyle; name: string; desc: string }[] = [
{ id: 'split', name: '经典分屏', desc: '左黑右白,晶格科技感' },
{ id: 'centered', name: '居中卡片', desc: '黎明光柱,金色晨曦氛围' },
{ id: 'sidepanel', name: '侧边面板', desc: '左品牌右登录,渐变装饰圆圈' },
{ id: 'sidepanel', name: '侧边面板', desc: '左品牌+功能卡片,右登录表单' },
{ id: 'fullimage', name: '全屏背景', desc: '科技背景,毛玻璃卡片' },
{ id: 'minimal', name: '深蓝紫曲线', desc: '优雅暗黑,粉紫流动曲线' },
{ id: 'aurora', name: '极光之境', desc: '北极光动态渐变,紫绿流光' },