feat: 霓虹都市→白日梦境 + 渐变网格→云石纹理 — 两个白色浅色主题登录页重写
This commit is contained in:
1 parent
b5739ba955
commit
5a61babd33
241 files changed
+58974
-7370
No files matched your search
@@ -0,0 +1,267 @@
|
||||
import { useLogin } from '@/hooks/useLogin';
|
||||
|
||||
/* ---------- Flowing curve configs ---------- */
|
||||
const CURVES = [
|
||||
{
|
||||
// Curve 1: Wide pink-to-purple ribbon, top area
|
||||
width: '140%', height: 320, top: '-5%', left: '-20%',
|
||||
background: 'linear-gradient(135deg, #ec4899 0%, #a855f7 40%, #6366f1 100%)',
|
||||
opacity: 0.12, blur: 60, rotate: -12,
|
||||
animation: 'curve-flow-1 20s ease-in-out infinite',
|
||||
},
|
||||
{
|
||||
// Curve 2: Thin bright pink ribbon, mid-upper
|
||||
width: '120%', height: 180, top: '15%', left: '-10%',
|
||||
background: 'linear-gradient(90deg, transparent 0%, #f472b6 30%, #c084fc 60%, transparent 100%)',
|
||||
opacity: 0.18, blur: 40, rotate: -8,
|
||||
animation: 'curve-flow-2 16s ease-in-out infinite',
|
||||
},
|
||||
{
|
||||
// Curve 3: Deep purple band, center
|
||||
width: '160%', height: 240, top: '35%', left: '-30%',
|
||||
background: 'linear-gradient(135deg, #7c3aed 0%, #4f46e5 50%, #2563eb 100%)',
|
||||
opacity: 0.10, blur: 70, rotate: 5,
|
||||
animation: 'curve-flow-3 24s ease-in-out infinite',
|
||||
},
|
||||
{
|
||||
// Curve 4: Bright cyan-pink accent, lower-mid
|
||||
width: '110%', height: 120, top: '55%', left: '-5%',
|
||||
background: 'linear-gradient(90deg, transparent 10%, #06b6d4 35%, #a855f7 65%, transparent 90%)',
|
||||
opacity: 0.15, blur: 35, rotate: -15,
|
||||
animation: 'curve-flow-4 14s ease-in-out infinite',
|
||||
},
|
||||
{
|
||||
// Curve 5: Soft pink glow, bottom
|
||||
width: '130%', height: 200, top: '70%', left: '-15%',
|
||||
background: 'linear-gradient(135deg, #db2777 0%, #9333ea 60%, #4f46e5 100%)',
|
||||
opacity: 0.08, blur: 80, rotate: 10,
|
||||
animation: 'curve-flow-5 22s ease-in-out infinite',
|
||||
},
|
||||
{
|
||||
// Curve 6: Thin bright line accent
|
||||
width: '100%', height: 3, top: '40%', left: '0%',
|
||||
background: 'linear-gradient(90deg, transparent 0%, #f472b6 20%, #c084fc 50%, #818cf8 80%, transparent 100%)',
|
||||
opacity: 0.35, blur: 8, rotate: -5,
|
||||
animation: 'curve-line-float 18s ease-in-out infinite',
|
||||
},
|
||||
{
|
||||
// Curve 7: Another thin accent line
|
||||
width: '90%', height: 2, top: '65%', left: '5%',
|
||||
background: 'linear-gradient(90deg, transparent 5%, #818cf8 30%, #e879f9 70%, transparent 95%)',
|
||||
opacity: 0.25, blur: 6, rotate: 8,
|
||||
animation: 'curve-line-float 15s ease-in-out infinite reverse',
|
||||
},
|
||||
];
|
||||
|
||||
const KEYFRAMES = `
|
||||
@keyframes curve-flow-1 {
|
||||
0%, 100% { transform: rotate(-12deg) translateX(0) scaleY(1); }
|
||||
33% { transform: rotate(-10deg) translateX(30px) scaleY(1.05); }
|
||||
66% { transform: rotate(-14deg) translateX(-20px) scaleY(0.95); }
|
||||
}
|
||||
@keyframes curve-flow-2 {
|
||||
0%, 100% { transform: rotate(-8deg) translateX(0); }
|
||||
50% { transform: rotate(-6deg) translateX(40px); }
|
||||
}
|
||||
@keyframes curve-flow-3 {
|
||||
0%, 100% { transform: rotate(5deg) translateX(0) scaleX(1); }
|
||||
40% { transform: rotate(3deg) translateX(-30px) scaleX(1.02); }
|
||||
70% { transform: rotate(7deg) translateX(20px) scaleX(0.98); }
|
||||
}
|
||||
@keyframes curve-flow-4 {
|
||||
0%, 100% { transform: rotate(-15deg) translateX(0); }
|
||||
50% { transform: rotate(-13deg) translateX(50px); }
|
||||
}
|
||||
@keyframes curve-flow-5 {
|
||||
0%, 100% { transform: rotate(10deg) translateX(0); }
|
||||
50% { transform: rotate(8deg) translateX(-40px); }
|
||||
}
|
||||
@keyframes curve-line-float {
|
||||
0%, 100% { transform: rotate(-5deg) translateX(0); opacity: 0.3; }
|
||||
25% { opacity: 0.5; }
|
||||
50% { transform: rotate(-3deg) translateX(30px); opacity: 0.35; }
|
||||
75% { opacity: 0.5; }
|
||||
}
|
||||
@keyframes curve-dot-pulse {
|
||||
0%, 100% { opacity: 0.15; transform: scale(1); }
|
||||
50% { opacity: 0.35; transform: scale(1.5); }
|
||||
}
|
||||
`;
|
||||
|
||||
/* ---------- Decorative dots ---------- */
|
||||
const DOTS = [
|
||||
{ top: '18%', left: '75%', size: 4, color: '#f472b6', delay: '0s' },
|
||||
{ top: '30%', left: '20%', size: 3, color: '#818cf8', delay: '2s' },
|
||||
{ top: '72%', left: '80%', size: 5, color: '#c084fc', delay: '1s' },
|
||||
{ top: '85%', left: '30%', size: 3, color: '#ec4899', delay: '3s' },
|
||||
{ top: '45%', left: '90%', size: 4, color: '#a855f7', delay: '1.5s' },
|
||||
];
|
||||
|
||||
export default function MinimalDark() {
|
||||
const { username, password, loading, error, setUsername, setPassword, handleLogin } = useLogin();
|
||||
|
||||
return (
|
||||
<>
|
||||
<style>{KEYFRAMES}</style>
|
||||
|
||||
<div
|
||||
style={{
|
||||
position: 'relative',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
minHeight: '100vh',
|
||||
padding: 24,
|
||||
background: 'linear-gradient(160deg, #0a0a1a 0%, #0f0a2a 30%, #150825 60%, #0a0a1a 100%)',
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
>
|
||||
{/* -------- Background glow orbs -------- */}
|
||||
<div
|
||||
style={{
|
||||
position: 'fixed', top: '-20%', right: '-10%', width: 500, height: 500,
|
||||
borderRadius: '50%', background: 'radial-gradient(circle, rgba(168,85,247,0.08), transparent 70%)',
|
||||
filter: 'blur(40px)', pointerEvents: 'none',
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
position: 'fixed', bottom: '-15%', left: '-5%', width: 400, height: 400,
|
||||
borderRadius: '50%', background: 'radial-gradient(circle, rgba(236,72,153,0.06), transparent 70%)',
|
||||
filter: 'blur(40px)', pointerEvents: 'none',
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* -------- Flowing curves -------- */}
|
||||
{CURVES.map((c, i) => (
|
||||
<div
|
||||
key={`curve-${i}`}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: c.top, left: c.left,
|
||||
width: c.width, height: c.height,
|
||||
background: c.background,
|
||||
opacity: c.opacity,
|
||||
filter: `blur(${c.blur}px)`,
|
||||
borderRadius: '50%',
|
||||
animation: c.animation,
|
||||
pointerEvents: 'none',
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
|
||||
{/* -------- Decorative dots -------- */}
|
||||
{DOTS.map((d, i) => (
|
||||
<div
|
||||
key={`dot-${i}`}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: d.top, left: d.left,
|
||||
width: d.size, height: d.size,
|
||||
borderRadius: '50%',
|
||||
background: d.color,
|
||||
animation: `curve-dot-pulse ${3 + i * 0.5}s ${d.delay} ease-in-out infinite`,
|
||||
pointerEvents: 'none',
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
|
||||
{/* -------- Central content -------- */}
|
||||
<div
|
||||
style={{
|
||||
width: '100%', maxWidth: 400, textAlign: 'center',
|
||||
position: 'relative', zIndex: 10,
|
||||
background: 'rgba(255,255,255,0.03)',
|
||||
backdropFilter: 'blur(20px)', WebkitBackdropFilter: 'blur(20px)',
|
||||
borderRadius: 24, padding: '48px 36px',
|
||||
boxShadow: '0 0 0 1px rgba(255,255,255,0.05), 0 8px 40px rgba(0,0,0,0.3)',
|
||||
}}
|
||||
>
|
||||
{/* Brand logo */}
|
||||
<div
|
||||
style={{
|
||||
width: 44, height: 44, borderRadius: 12,
|
||||
background: 'linear-gradient(135deg, #ec4899, #a855f7)',
|
||||
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
||||
margin: '0 auto 24px',
|
||||
boxShadow: '0 4px 20px rgba(168,85,247,0.3)',
|
||||
}}
|
||||
>
|
||||
<svg width="20" height="20" 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>
|
||||
|
||||
{/* Brand name */}
|
||||
<h1 style={{ fontSize: 22, fontWeight: 600, color: '#fff', marginBottom: 6, letterSpacing: '-0.3px' }}>
|
||||
SQL审核平台
|
||||
</h1>
|
||||
<p style={{ color: 'rgba(255,255,255,0.4)', fontSize: 14, marginBottom: 36 }}>
|
||||
企业级数据库审核与合规管理
|
||||
</p>
|
||||
|
||||
{/* Form */}
|
||||
<form onSubmit={handleLogin} style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
|
||||
{error && (
|
||||
<div style={{ color: '#f87171', fontSize: 13, textAlign: 'center', padding: '10px 14px', background: 'rgba(248,113,113,0.08)', borderRadius: 8 }}>
|
||||
{error}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<input
|
||||
type="text"
|
||||
placeholder="用户名"
|
||||
value={username}
|
||||
onChange={(e) => setUsername(e.target.value)}
|
||||
className="w-full"
|
||||
style={{
|
||||
padding: '13px 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',
|
||||
transition: 'border-color 0.2s, background 0.2s',
|
||||
}}
|
||||
onFocus={(e) => { e.target.style.borderColor = 'rgba(168,85,247,0.4)'; e.target.style.background = 'rgba(255,255,255,0.08)'; }}
|
||||
onBlur={(e) => { e.target.style.borderColor = 'rgba(255,255,255,0.08)'; e.target.style.background = 'rgba(255,255,255,0.05)'; }}
|
||||
/>
|
||||
<input
|
||||
type="password"
|
||||
placeholder="密码"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
className="w-full"
|
||||
style={{
|
||||
padding: '13px 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',
|
||||
transition: 'border-color 0.2s, background 0.2s',
|
||||
}}
|
||||
onFocus={(e) => { e.target.style.borderColor = 'rgba(168,85,247,0.4)'; e.target.style.background = 'rgba(255,255,255,0.08)'; }}
|
||||
onBlur={(e) => { e.target.style.borderColor = 'rgba(255,255,255,0.08)'; e.target.style.background = 'rgba(255,255,255,0.05)'; }}
|
||||
/>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
disabled={loading || !username || !password}
|
||||
className="dg-gradient-bg w-full"
|
||||
style={{
|
||||
padding: '13px 20px', borderRadius: 10,
|
||||
border: 'none', color: '#fff', fontWeight: 600, fontSize: 15,
|
||||
cursor: loading || !username || !password ? 'not-allowed' : 'pointer',
|
||||
opacity: loading || !username || !password ? 0.5 : 1,
|
||||
marginTop: 4,
|
||||
transition: 'opacity 0.2s, transform 0.1s',
|
||||
boxShadow: '0 4px 20px rgba(168,85,247,0.25)',
|
||||
}}
|
||||
>
|
||||
{loading ? '登录中…' : '登录'}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user