diff --git a/frontend/src/components/login/CenteredCard.tsx b/frontend/src/components/login/CenteredCard.tsx index dc5d6c3..e0706c5 100644 --- a/frontend/src/components/login/CenteredCard.tsx +++ b/frontend/src/components/login/CenteredCard.tsx @@ -3,6 +3,54 @@ import { useLogin } from '@/hooks/useLogin'; export default function CenteredCard() { const { username, password, loading, error, setUsername, setPassword, handleLogin } = useLogin(); + // Light rays: 10 beams fanning out from bottom center + const rays = [ + { angle: -55, height: 70, opacity: 0.12, duration: 8 }, + { angle: -42, height: 85, opacity: 0.08, duration: 7 }, + { angle: -28, height: 60, opacity: 0.15, duration: 9 }, + { angle: -14, height: 90, opacity: 0.06, duration: 6 }, + { angle: -4, height: 75, opacity: 0.10, duration: 10 }, + { angle: 5, height: 80, opacity: 0.09, duration: 7 }, + { angle: 16, height: 65, opacity: 0.13, duration: 9 }, + { angle: 30, height: 88, opacity: 0.07, duration: 8 }, + { angle: 44, height: 72, opacity: 0.11, duration: 6 }, + { angle: 56, height: 55, opacity: 0.14, duration: 10 }, + ]; + + // Fading stars at the top + const stars = [ + { top: '6%', left: '15%', size: 2, opacity: 0.2, duration: 5 }, + { top: '10%', left: '72%', size: 3, opacity: 0.15, duration: 6 }, + { top: '3%', left: '45%', size: 2, opacity: 0.25, duration: 4.5 }, + { top: '14%', left: '30%', size: 2, opacity: 0.1, duration: 5.5 }, + { top: '8%', left: '88%', size: 3, opacity: 0.18, duration: 7 }, + { top: '5%', left: '60%', size: 2, opacity: 0.3, duration: 4 }, + ]; + + const inputStyle = { + padding: '14px 18px', + borderRadius: 10, + background: 'rgba(255,255,255,0.04)', + border: '1px solid rgba(251,191,36,0.06)', + color: '#fef3c7', + fontSize: 14, + outline: 'none' as const, + width: '100%', + transition: 'border-color 0.3s, background 0.3s, box-shadow 0.3s', + }; + + const handleFocus = (e: React.FocusEvent) => { + e.target.style.borderColor = 'rgba(251,191,36,0.3)'; + e.target.style.background = 'rgba(255,255,255,0.06)'; + e.target.style.boxShadow = '0 0 0 3px rgba(251,191,36,0.08)'; + }; + + const handleBlur = (e: React.FocusEvent) => { + e.target.style.borderColor = 'rgba(251,191,36,0.06)'; + e.target.style.background = 'rgba(255,255,255,0.04)'; + e.target.style.boxShadow = 'none'; + }; + return (
- {/* Aurora band 1 — Emerald green */} + {/* Dawn light rays */} + {rays.map((ray, i) => ( +
+ ))} + + {/* Horizon glow */}
- {/* Aurora band 2 — Indigo */} -
- - {/* Aurora band 3 — Purple */} -
+ {/* Stars — fading remnants of night */} + {stars.map((star, i) => ( +
+ ))} {/* Glassmorphism card */}
- {/* Logo — 44x44 gradient rounded square with database icon */} + {/* Logo — 44x44 golden gradient with sunrise SVG icon */}
- - - - + + + + + + + + + +
-

+

SQL审核平台

-

- 登录您的工作区 +

+ 守护每一次数据变更

@@ -123,26 +183,9 @@ export default function CenteredCard() { value={username} onChange={(e) => setUsername(e.target.value)} className="w-full" - style={{ - padding: '14px 18px', - borderRadius: 12, - background: 'rgba(255,255,255,0.06)', - border: '1px solid rgba(255,255,255,0.08)', - color: '#fff', - fontSize: 14, - outline: 'none', - transition: 'border-color 0.3s, background 0.3s, box-shadow 0.3s', - }} - onFocus={(e) => { - e.target.style.borderColor = 'rgba(99,102,241,0.4)'; - e.target.style.background = 'rgba(255,255,255,0.08)'; - e.target.style.boxShadow = '0 0 0 3px rgba(99,102,241,0.1)'; - }} - onBlur={(e) => { - e.target.style.borderColor = 'rgba(255,255,255,0.08)'; - e.target.style.background = 'rgba(255,255,255,0.06)'; - e.target.style.boxShadow = 'none'; - }} + style={inputStyle} + onFocus={handleFocus} + onBlur={handleBlur} /> setPassword(e.target.value)} className="w-full" - style={{ - padding: '14px 18px', - borderRadius: 12, - background: 'rgba(255,255,255,0.06)', - border: '1px solid rgba(255,255,255,0.08)', - color: '#fff', - fontSize: 14, - outline: 'none', - transition: 'border-color 0.3s, background 0.3s, box-shadow 0.3s', - }} - onFocus={(e) => { - e.target.style.borderColor = 'rgba(99,102,241,0.4)'; - e.target.style.background = 'rgba(255,255,255,0.08)'; - e.target.style.boxShadow = '0 0 0 3px rgba(99,102,241,0.1)'; - }} - onBlur={(e) => { - e.target.style.borderColor = 'rgba(255,255,255,0.08)'; - e.target.style.background = 'rgba(255,255,255,0.06)'; - e.target.style.boxShadow = 'none'; - }} + style={inputStyle} + onFocus={handleFocus} + onBlur={handleBlur} />
- {/* Aurora keyframe animations */} + {/* Dawn keyframe animations */}
diff --git a/frontend/src/components/login/SidePanel.tsx b/frontend/src/components/login/SidePanel.tsx index 53d8bb4..c1a4a3d 100644 --- a/frontend/src/components/login/SidePanel.tsx +++ b/frontend/src/components/login/SidePanel.tsx @@ -3,262 +3,238 @@ import { useLogin } from '@/hooks/useLogin'; export default function SidePanel() { const { username, password, loading, error, setUsername, setPassword, handleLogin } = useLogin(); - /* 6 orbit light-points evenly spaced at 60° intervals on a 300px ring (radius 150px) */ - const orbitDots = [ - { angle: 0, size: 8, opacity: 0.9 }, - { angle: 60, size: 6, opacity: 0.6 }, - { angle: 120, size: 7, opacity: 0.75 }, - { angle: 180, size: 6, opacity: 0.5 }, - { angle: 240, size: 8, opacity: 0.8 }, - { angle: 300, size: 6, opacity: 0.55 }, + /* 15 bioluminescent particles scattered across the deep-sea scene */ + const biolumParticles = [ + { top: '8%', left: '20%', size: 4, color: 'rgba(6,182,212,0.4)', delay: '0s', dur: '4s' }, + { top: '15%', left: '65%', size: 5, color: 'rgba(20,184,166,0.3)', delay: '1.2s', dur: '5s' }, + { top: '22%', left: '40%', size: 3, color: 'rgba(34,211,238,0.5)', delay: '0.5s', dur: '3.5s' }, + { top: '28%', left: '12%', size: 6, color: 'rgba(6,182,212,0.4)', delay: '2.8s', dur: '4.5s' }, + { top: '35%', left: '78%', size: 4, color: 'rgba(6,182,212,0.4)', delay: '3.5s', dur: '3s' }, + { top: '42%', left: '30%', size: 7, color: 'rgba(20,184,166,0.3)', delay: '1s', dur: '5.5s' }, + { top: '48%', left: '55%', size: 3, color: 'rgba(34,211,238,0.5)', delay: '4.2s', dur: '4s' }, + { top: '55%', left: '18%', size: 5, color: 'rgba(6,182,212,0.4)', delay: '0.8s', dur: '6s' }, + { top: '60%', left: '70%', size: 4, color: 'rgba(6,182,212,0.4)', delay: '5s', dur: '3.5s' }, + { top: '67%', left: '45%', size: 8, color: 'rgba(20,184,166,0.3)', delay: '2s', dur: '4.5s' }, + { top: '73%', left: '25%', size: 3, color: 'rgba(6,182,212,0.4)', delay: '6s', dur: '5s' }, + { top: '78%', left: '85%', size: 5, color: 'rgba(34,211,238,0.5)', delay: '1.5s', dur: '3s' }, + { top: '83%', left: '50%', size: 4, color: 'rgba(6,182,212,0.4)', delay: '7s', dur: '4.5s' }, + { top: '88%', left: '15%', size: 6, color: 'rgba(6,182,212,0.4)', delay: '3s', dur: '5.5s' }, + { top: '92%', left: '60%', size: 3, color: 'rgba(20,184,166,0.3)', delay: '8s', dur: '3.5s' }, ]; - /* Scattered twinkling stars */ - const stars = [ - { top: '6%', left: '12%', size: 3, delay: '0s', dur: '3s' }, - { top: '14%', left: '72%', size: 2, delay: '1.2s', dur: '4s' }, - { top: '25%', left: '38%', size: 4, delay: '0.5s', dur: '3.5s' }, - { top: '18%', left: '55%', size: 2, delay: '2s', dur: '5s' }, - { top: '60%', left: '15%', size: 3, delay: '1s', dur: '4.5s' }, - { top: '70%', left: '80%', size: 2, delay: '0.3s', dur: '3.2s' }, - { top: '82%', left: '30%', size: 4, delay: '1.8s', dur: '3.8s' }, - { top: '45%', left: '8%', size: 2, delay: '2.5s', dur: '4.2s' }, - { top: '35%', left: '88%', size: 3, delay: '0.8s', dur: '3.6s' }, - { top: '90%', left: '65%', size: 2, delay: '1.5s', dur: '5.2s' }, + /* 5 ocean wave layers */ + const waveLayers = [ + { top: '20%', height: 80, border: 'border-bottom', borderColor: 'rgba(6,182,212,0.06)', anim: 'ocean-wave-1 12s ease-in-out infinite' }, + { top: '30%', height: 100, border: 'border-bottom', borderColor: 'rgba(20,184,166,0.08)', anim: 'ocean-wave-2 15s ease-in-out infinite' }, + { top: '45%', height: 120, border: 'border-top', borderColor: 'rgba(6,182,212,0.10)', anim: 'ocean-wave-3 18s ease-in-out infinite' }, + { top: '60%', height: 90, border: 'border-bottom', borderColor: 'rgba(20,184,166,0.06)', anim: 'ocean-wave-4 14s ease-in-out infinite' }, + { top: '75%', height: 70, border: 'border-top', borderColor: 'rgba(6,182,212,0.04)', anim: 'ocean-wave-5 20s ease-in-out infinite' }, ]; + /* Feature pills */ + const featurePills = ['安全审核', '变更管控', '权限隔离']; + return ( -
- {/* ========== Left Panel — 40% Celestial Animation ========== */} +
+ {/* ========== Left 40% — Deep Sea Scene ========== */}
- {/* --- Core Celestial Orb (200px, centered-upper) --- */} + {/* --- Deep-sea light shafts --- */}
- {/* Main orb */} -
-
- - {/* --- Orbit Ring (300px, dashed) with 6 light dots --- */} -
- {orbitDots.map((dot, i) => { - const rad = (dot.angle * Math.PI) / 180; - const r = 150; // radius of the 300px ring - const x = 150 + r * Math.cos(rad) - dot.size / 2; - const y = 150 + r * Math.sin(rad) - dot.size / 2; - return ( -
- ); - })} -
- - {/* --- 3 Meteors --- */} - {/* Meteor 1 */} -
- {/* Meteor 2 */}
- {/* Meteor 3 */}
- {/* --- Scattered Twinkling Stars --- */} - {stars.map((s, i) => ( + {/* --- 5 Wave layers --- */} + {waveLayers.map((wave, i) => (
))} - {/* --- Bottom-left brand text --- */} -
-
+ {/* --- 15 Bioluminescent particles --- */} + {biolumParticles.map((p, i) => ( +
+ ))} + + {/* --- Brand content (left-aligned, bottom section) --- */} +
+ {/* Main title */} +
SQL审核平台
-
- 企业级数据库审核与合规管理 + {/* Subtitle */} +
+ 让数据安全如深海般沉静 +
+ {/* Feature pills */} +
+ {featurePills.map((pill) => ( + + {pill} + + ))}
- {/* --- Keyframes --- */} + {/* --- Keyframes (ocean- prefix) --- */}
- {/* ========== Right Panel — 60% Login Form ========== */} + {/* ========== Right 60% — Login Form ========== */}
-

+ {/* Form title */} +

欢迎回来

-

- 登录以继续 +

+ 登录你的工作空间

+ {/* Error message */} {error && ( -
+
{error}
)} - {/* Username */} + {/* Username field */}
-
- {/* Password */} + {/* Password field */}
-
- {/* Submit */} + {/* Submit button */}