feat: 霓虹都市→白日梦境 + 渐变网格→云石纹理 — 两个白色浅色主题登录页重写

This commit is contained in:
logan committed 2026-05-27 21:53:27 +08:00
1 parent b5739ba955
commit 5a61babd33
241 files changed
+58974 -7370

No files matched your search

@@ -0,0 +1,429 @@
import React from 'react';
import { useLogin } from '@/hooks/useLogin';
/* ──────────────── 极光之境 · 登录组件 ──────────────── */
const KEYFRAMES = `
@keyframes aurora-drift-1 {
0% { transform: translate(-30%, -10%) rotate(-12deg) scaleX(1.2); opacity: 0.35; }
25% { transform: translate(-10%, 5%) rotate(-8deg) scaleX(1.5); opacity: 0.5; }
50% { transform: translate(10%, -5%) rotate(-14deg) scaleX(1.3); opacity: 0.4; }
75% { transform: translate(-5%, 10%) rotate(-10deg) scaleX(1.6); opacity: 0.55; }
100% { transform: translate(-30%, -10%) rotate(-12deg) scaleX(1.2); opacity: 0.35; }
}
@keyframes aurora-drift-2 {
0% { transform: translate(20%, 15%) rotate(8deg) scaleX(1.3); opacity: 0.25; }
30% { transform: translate(-10%, -5%) rotate(12deg) scaleX(1.6); opacity: 0.45; }
60% { transform: translate(5%, 10%) rotate(6deg) scaleX(1.4); opacity: 0.35; }
100% { transform: translate(20%, 15%) rotate(8deg) scaleX(1.3); opacity: 0.25; }
}
@keyframes aurora-drift-3 {
0% { transform: translate(-15%, 25%) rotate(-5deg) scaleX(1.5); opacity: 0.3; }
33% { transform: translate(15%, 5%) rotate(-9deg) scaleX(1.8); opacity: 0.5; }
66% { transform: translate(0%, 20%) rotate(-3deg) scaleX(1.4); opacity: 0.4; }
100% { transform: translate(-15%, 25%) rotate(-5deg) scaleX(1.5); opacity: 0.3; }
}
@keyframes aurora-drift-4 {
0% { transform: translate(10%, -15%) rotate(15deg) scaleX(1.4); opacity: 0.2; }
40% { transform: translate(-20%, 0%) rotate(10deg) scaleX(1.7); opacity: 0.4; }
80% { transform: translate(0%, 8%) rotate(18deg) scaleX(1.5); opacity: 0.3; }
100% { transform: translate(10%, -15%) rotate(15deg) scaleX(1.4); opacity: 0.2; }
}
@keyframes twinkle {
0%, 100% { opacity: 0.15; transform: scale(0.8); }
50% { opacity: 0.9; transform: scale(1.2); }
}
@keyframes float-card {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-6px); }
}
@keyframes pulse-glow {
0%, 100% { box-shadow: 0 0 20px rgba(124, 58, 237, 0.15), 0 0 60px rgba(5, 150, 105, 0.08); }
50% { box-shadow: 0 0 30px rgba(124, 58, 237, 0.25), 0 0 80px rgba(5, 150, 105, 0.15); }
}
`;
/* ──────────────── 星星数据 ──────────────── */
const STARS = [
{ left: '8%', top: '5%', size: 2, delay: 0, duration: 3 },
{ left: '18%', top: '15%', size: 1.5, delay: 0.7, duration: 4 },
{ left: '5%', top: '35%', size: 1, delay: 1.2, duration: 2.5 },
{ left: '25%', top: '8%', size: 2.5, delay: 0.3, duration: 3.5 },
{ left: '75%', top: '6%', size: 1.5, delay: 1.5, duration: 4.5 },
{ left: '88%', top: '12%', size: 2, delay: 0.5, duration: 3 },
{ left: '92%', top: '30%', size: 1, delay: 2, duration: 2.8 },
{ left: '82%', top: '45%', size: 1.5, delay: 0.9, duration: 3.8 },
{ left: '68%', top: '18%', size: 1, delay: 1.8, duration: 2.2 },
{ left: '38%', top: '3%', size: 2, delay: 0.2, duration: 4 },
{ left: '55%', top: '10%', size: 1.5, delay: 1.1, duration: 3.2 },
{ left: '45%', top: '22%', size: 1, delay: 0.6, duration: 2.6 },
{ left: '12%', top: '55%', size: 1, delay: 1.6, duration: 3.6 },
{ left: '95%', top: '55%', size: 1.5, delay: 0.4, duration: 2.4 },
{ left: '60%', top: '30%', size: 1, delay: 2.2, duration: 4.2 },
];
export default function AuroraView(): JSX.Element {
const { username, password, loading, error, setUsername, setPassword, handleLogin } = useLogin();
return (
<>
<style>{KEYFRAMES}</style>
{/* ═══════════════ 全屏背景容器 ═══════════════ */}
<div
style={{
position: 'relative',
minHeight: '100vh',
width: '100%',
overflow: 'hidden',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
background: 'linear-gradient(180deg, #050810 0%, #0a0e1a 30%, #0d1425 60%, #080c14 100%)',
}}
>
{/* ────────── 极光光带 1:紫罗兰色 ────────── */}
<div
style={{
position: 'absolute',
top: '15%',
left: '10%',
width: '80%',
height: '35%',
background: 'linear-gradient(135deg, rgba(168, 85, 247, 0.6) 0%, rgba(124, 58, 237, 0.3) 40%, transparent 80%)',
filter: 'blur(60px)',
borderRadius: '50%',
animation: 'aurora-drift-1 18s ease-in-out infinite',
pointerEvents: 'none',
}}
/>
{/* ────────── 极光光带 2:翠绿色 ────────── */}
<div
style={{
position: 'absolute',
top: '25%',
left: '20%',
width: '75%',
height: '30%',
background: 'linear-gradient(120deg, rgba(16, 185, 129, 0.5) 0%, rgba(5, 150, 105, 0.25) 50%, transparent 90%)',
filter: 'blur(70px)',
borderRadius: '50%',
animation: 'aurora-drift-2 22s ease-in-out infinite',
pointerEvents: 'none',
}}
/>
{/* ────────── 极光光带 3:青蓝色 ────────── */}
<div
style={{
position: 'absolute',
top: '35%',
left: '5%',
width: '70%',
height: '28%',
background: 'linear-gradient(145deg, rgba(6, 182, 212, 0.4) 0%, rgba(6, 182, 212, 0.15) 45%, transparent 85%)',
filter: 'blur(55px)',
borderRadius: '50%',
animation: 'aurora-drift-3 20s ease-in-out infinite',
pointerEvents: 'none',
}}
/>
{/* ────────── 极光光带 4:紫绿混合 ────────── */}
<div
style={{
position: 'absolute',
top: '10%',
left: '30%',
width: '65%',
height: '40%',
background: 'linear-gradient(100deg, rgba(124, 58, 237, 0.35) 0%, rgba(16, 185, 129, 0.2) 50%, rgba(6, 182, 212, 0.15) 100%)',
filter: 'blur(75px)',
borderRadius: '50%',
animation: 'aurora-drift-4 25s ease-in-out infinite',
pointerEvents: 'none',
}}
/>
{/* ────────── 星光点缀 ────────── */}
{STARS.map((star, i) => (
<div
key={i}
style={{
position: 'absolute',
left: star.left,
top: star.top,
width: star.size,
height: star.size,
borderRadius: '50%',
background: '#fff',
boxShadow: `0 0 ${star.size * 2}px rgba(255,255,255,0.5)`,
animation: `twinkle ${star.duration}s ease-in-out ${star.delay}s infinite`,
pointerEvents: 'none',
}}
/>
))}
{/* ═══════════════ 登录卡片 ═══════════════ */}
<div
style={{
position: 'relative',
zIndex: 10,
width: '100%',
maxWidth: 400,
margin: '0 20px',
padding: '44px 36px',
borderRadius: 20,
background: 'rgba(8, 12, 25, 0.65)',
backdropFilter: 'blur(24px)',
WebkitBackdropFilter: 'blur(24px)',
border: '1px solid rgba(255,255,255,0.06)',
boxShadow: '0 0 0 1px rgba(255,255,255,0.04), 0 20px 60px rgba(0,0,0,0.4)',
animation: 'float-card 8s ease-in-out infinite, pulse-glow 6s ease-in-out infinite',
}}
>
{/* ──────── 品牌区域 ──────── */}
<div style={{ textAlign: 'center', marginBottom: 32 }}>
{/* Logo */}
<div
style={{
width: 44,
height: 44,
borderRadius: 12,
background: 'linear-gradient(135deg, #7c3aed 0%, #059669 100%)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
margin: '0 auto 16px',
boxShadow: '0 4px 20px rgba(124, 58, 237, 0.3), 0 2px 10px rgba(5, 150, 105, 0.2)',
}}
>
<svg
width={22}
height={22}
viewBox="0 0 24 24"
fill="none"
stroke="#fff"
strokeWidth={2}
strokeLinecap="round"
strokeLinejoin="round"
>
<ellipse cx="12" cy="5" rx="9" ry="3" />
<path d="M21 12c0 1.66-4 3-9 3s-9-1.34-9-3" />
<path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5" />
</svg>
</div>
{/* 标题 */}
<h1
style={{
fontSize: 22,
fontWeight: 600,
color: '#fff',
margin: '0 0 6px',
letterSpacing: 0.5,
}}
>
SQL审核平台
</h1>
{/* 副标题 */}
<p
style={{
fontSize: 14,
color: 'rgba(255,255,255,0.4)',
margin: 0,
letterSpacing: 0.3,
}}
>
企业级数据库审核与合规管理
</p>
</div>
{/* ──────── 表单区域 ──────── */}
<form onSubmit={handleLogin} noValidate>
{/* 错误提示 */}
{error && (
<div
style={{
marginBottom: 16,
padding: '10px 14px',
borderRadius: 10,
background: 'rgba(239, 68, 68, 0.12)',
border: '1px solid rgba(239, 68, 68, 0.2)',
color: '#f87171',
fontSize: 13,
textAlign: 'center',
}}
>
{error}
</div>
)}
{/* 用户名输入框 */}
<div style={{ marginBottom: 14 }}>
<input
type="text"
placeholder="用户名"
value={username}
onChange={(e) => setUsername(e.target.value)}
disabled={loading}
autoComplete="username"
style={{
width: '100%',
height: 46,
padding: '0 16px',
borderRadius: 10,
background: 'rgba(255,255,255,0.05)',
border: '1px solid rgba(255,255,255,0.08)',
color: '#fff',
fontSize: 14,
outline: 'none',
boxSizing: 'border-box',
transition: 'border-color 0.25s ease, box-shadow 0.25s ease',
fontFamily: 'inherit',
}}
onFocus={(e) => {
e.currentTarget.style.borderColor = 'rgba(124, 58, 237, 0.4)';
e.currentTarget.style.boxShadow = '0 0 0 3px rgba(124, 58, 237, 0.08)';
}}
onBlur={(e) => {
e.currentTarget.style.borderColor = 'rgba(255,255,255,0.08)';
e.currentTarget.style.boxShadow = 'none';
}}
/>
</div>
{/* 密码输入框 */}
<div style={{ marginBottom: 20 }}>
<input
type="password"
placeholder="密码"
value={password}
onChange={(e) => setPassword(e.target.value)}
disabled={loading}
autoComplete="current-password"
style={{
width: '100%',
height: 46,
padding: '0 16px',
borderRadius: 10,
background: 'rgba(255,255,255,0.05)',
border: '1px solid rgba(255,255,255,0.08)',
color: '#fff',
fontSize: 14,
outline: 'none',
boxSizing: 'border-box',
transition: 'border-color 0.25s ease, box-shadow 0.25s ease',
fontFamily: 'inherit',
}}
onFocus={(e) => {
e.currentTarget.style.borderColor = 'rgba(124, 58, 237, 0.4)';
e.currentTarget.style.boxShadow = '0 0 0 3px rgba(124, 58, 237, 0.08)';
}}
onBlur={(e) => {
e.currentTarget.style.borderColor = 'rgba(255,255,255,0.08)';
e.currentTarget.style.boxShadow = 'none';
}}
/>
</div>
{/* 登录按钮 */}
<button
type="submit"
disabled={!username || !password || loading}
style={{
width: '100%',
height: 46,
borderRadius: 12,
border: 'none',
background: 'linear-gradient(135deg, #7c3aed 0%, #059669 100%)',
color: '#fff',
fontSize: 15,
fontWeight: 500,
cursor: !username || !password || loading ? 'not-allowed' : 'pointer',
opacity: !username || !password ? 0.55 : 1,
transition: 'all 0.3s ease',
fontFamily: 'inherit',
letterSpacing: 0.5,
position: 'relative',
overflow: 'hidden',
}}
onMouseEnter={(e) => {
if (username && password && !loading) {
e.currentTarget.style.transform = 'translateY(-2px)';
e.currentTarget.style.boxShadow = '0 8px 30px rgba(124, 58, 237, 0.35), 0 4px 15px rgba(5, 150, 105, 0.25)';
}
}}
onMouseLeave={(e) => {
e.currentTarget.style.transform = 'translateY(0)';
e.currentTarget.style.boxShadow = 'none';
}}
>
{loading ? (
<span style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8 }}>
<span
style={{
display: 'inline-block',
width: 16,
height: 16,
border: '2px solid rgba(255,255,255,0.3)',
borderTopColor: '#fff',
borderRadius: '50%',
animation: 'spin 0.8s linear infinite',
}}
/>
登录中...
</span>
) : (
'登 录'
)}
</button>
</form>
{/* ──────── 版权信息 ──────── */}
<div
style={{
marginTop: 28,
textAlign: 'center',
fontSize: 12,
color: 'rgba(255,255,255,0.2)',
letterSpacing: 0.3,
}}
>
© 2025 SQL审核平台
</div>
</div>
{/* ──────── 底部辉光装饰 ──────── */}
<div
style={{
position: 'absolute',
bottom: '-20%',
left: '50%',
transform: 'translateX(-50%)',
width: '120%',
height: '50%',
background: 'radial-gradient(ellipse at center, rgba(124, 58, 237, 0.08) 0%, rgba(5, 150, 105, 0.05) 30%, transparent 70%)',
pointerEvents: 'none',
}}
/>
</div>
{/* 全局旋转动画 */}
<style>{`
@keyframes spin {
to { transform: rotate(360deg); }
}
`}</style>
</>
);
}