feat: modernize login page with dark theme and breathing logo animation

- Dark gradient background (slate-950/blue-950) with ambient blur effects
- Circular logo centered with dual-ring frosted glass design
- Heartbeat breathing animation (3s cycle) with glow pulse on outer ring
- Gradient sign-in button with hover shadow effects
- Removed "first user" warning, replaced with subtle "authorized personnel" note
- Closes #5 and #6

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-08 07:58:04 +01:00
parent a4d360aae9
commit 806b67954e
2 changed files with 52 additions and 18 deletions

View File

@@ -1,7 +1,7 @@
import { useEffect } from 'react'; import { useEffect } from 'react';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { useAuth } from '@/contexts/AuthContext'; import { useAuth } from '@/contexts/AuthContext';
import { Plane } from 'lucide-react'; import { Plane, LogIn, Shield } from 'lucide-react';
export function Login() { export function Login() {
const { isAuthenticated, loginWithRedirect } = useAuth(); const { isAuthenticated, loginWithRedirect } = useAuth();
@@ -14,30 +14,51 @@ export function Login() {
}, [isAuthenticated, navigate]); }, [isAuthenticated, navigate]);
return ( return (
<div className="min-h-screen flex items-center justify-center bg-gradient-to-br from-primary/5 via-background to-primary/10"> <div className="min-h-screen flex items-center justify-center relative overflow-hidden bg-gradient-to-br from-slate-950 via-slate-900 to-blue-950">
<div className="max-w-md w-full bg-card border border-border rounded-lg shadow-xl p-8"> {/* Background ambient effects */}
<div className="text-center mb-8"> <div className="absolute inset-0 overflow-hidden">
<div className="inline-block p-3 bg-primary/10 rounded-full mb-4"> <div className="absolute -top-1/2 -left-1/2 w-full h-full bg-gradient-radial from-blue-500/10 to-transparent rounded-full blur-3xl" />
<Plane className="h-12 w-12 text-primary" /> <div className="absolute -bottom-1/2 -right-1/2 w-full h-full bg-gradient-radial from-indigo-500/8 to-transparent rounded-full blur-3xl" />
<div className="absolute top-1/4 right-1/4 w-96 h-96 bg-blue-500/5 rounded-full blur-3xl" />
</div> </div>
<h1 className="text-3xl font-bold text-foreground mb-2">
{/* Content */}
<div className="relative z-10 flex flex-col items-center gap-10 px-4 w-full max-w-sm">
{/* Breathing logo circle */}
<div className="animate-heartbeat">
<div className="relative w-36 h-36 rounded-full bg-gradient-to-br from-blue-500/20 to-indigo-600/20 backdrop-blur-sm border border-white/10 flex items-center justify-center animate-glow-pulse">
{/* Inner circle */}
<div className="w-28 h-28 rounded-full bg-gradient-to-br from-blue-500/30 to-indigo-600/30 border border-white/10 flex items-center justify-center shadow-2xl">
<Plane className="h-14 w-14 text-blue-400 drop-shadow-lg" />
</div>
</div>
</div>
{/* Title */}
<div className="text-center">
<h1 className="text-4xl font-bold text-white tracking-tight mb-2">
VIP Coordinator VIP Coordinator
</h1> </h1>
<p className="text-muted-foreground"> <p className="text-blue-200/60 text-sm tracking-wide">
Transportation logistics and event coordination Transportation logistics & event coordination
</p> </p>
</div> </div>
{/* Sign in card */}
<div className="w-full">
<button <button
onClick={() => loginWithRedirect()} onClick={() => loginWithRedirect()}
className="w-full bg-primary text-primary-foreground py-3 px-4 rounded-lg font-medium hover:bg-primary/90 transition-colors" className="w-full group relative flex items-center justify-center gap-3 bg-gradient-to-r from-blue-600 to-indigo-600 text-white py-4 px-6 rounded-2xl font-semibold text-lg shadow-lg shadow-blue-500/25 hover:shadow-blue-500/40 hover:from-blue-500 hover:to-indigo-500 active:scale-[0.98] transition-all duration-200"
> >
Sign In with Auth0 <LogIn className="h-5 w-5 transition-transform group-hover:-translate-x-0.5" />
Sign In
</button> </button>
</div>
<div className="mt-6 text-center text-sm text-muted-foreground"> {/* Footer note */}
<p>First user becomes administrator</p> <div className="flex items-center gap-2 text-blue-300/40 text-xs">
<p>Subsequent users require admin approval</p> <Shield className="h-3.5 w-3.5" />
<span>Authorized personnel only</span>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -66,12 +66,25 @@ export default {
}, },
animation: { animation: {
'bounce-subtle': 'bounce-subtle 2s ease-in-out infinite', 'bounce-subtle': 'bounce-subtle 2s ease-in-out infinite',
'heartbeat': 'heartbeat 3s ease-in-out infinite',
'glow-pulse': 'glow-pulse 3s ease-in-out infinite',
}, },
keyframes: { keyframes: {
'bounce-subtle': { 'bounce-subtle': {
'0%, 100%': { transform: 'translateY(0)' }, '0%, 100%': { transform: 'translateY(0)' },
'50%': { transform: 'translateY(-2px)' }, '50%': { transform: 'translateY(-2px)' },
}, },
'heartbeat': {
'0%, 100%': { transform: 'scale(1)' },
'15%': { transform: 'scale(1.08)' },
'30%': { transform: 'scale(1)' },
'45%': { transform: 'scale(1.05)' },
'60%': { transform: 'scale(1)' },
},
'glow-pulse': {
'0%, 100%': { boxShadow: '0 0 20px rgba(59, 130, 246, 0.15), 0 0 60px rgba(59, 130, 246, 0.05)' },
'50%': { boxShadow: '0 0 30px rgba(59, 130, 246, 0.3), 0 0 80px rgba(59, 130, 246, 0.1)' },
},
}, },
}, },
}, },