22
33import { useState , useEffect } from 'react' ;
44import { useRouter } from 'next/navigation' ;
5- import { LogIn , Eye , EyeOff , AlertCircle } from 'lucide-react' ;
5+ import { LogIn , Eye , EyeOff , AlertCircle , GitBranch , Activity , Zap } from 'lucide-react' ;
66import axios from 'axios' ;
77
88export default function LoginPage ( ) {
@@ -12,6 +12,12 @@ export default function LoginPage() {
1212 const [ showPassword , setShowPassword ] = useState ( false ) ;
1313 const [ error , setError ] = useState ( '' ) ;
1414 const [ loading , setLoading ] = useState ( false ) ;
15+ const [ mounted , setMounted ] = useState ( false ) ;
16+
17+ // Mounting animation
18+ useEffect ( ( ) => {
19+ setMounted ( true ) ;
20+ } , [ ] ) ;
1521
1622 // Check if already logged in
1723 useEffect ( ( ) => {
@@ -55,31 +61,49 @@ export default function LoginPage() {
5561 } ;
5662
5763 return (
58- < div className = "min-h-screen bg-gradient-to-br from-zinc-950 via-zinc-900 to-orange-950 flex items-center justify-center p-4" >
59- < div className = "w-full max-w-md" >
64+ < div className = "min-h-screen bg-gradient-to-br from-zinc-950 via-zinc-900 to-orange-950 flex items-center justify-center p-4 relative overflow-hidden" >
65+ { /* Animated Background Elements */ }
66+ < div className = "absolute inset-0 overflow-hidden pointer-events-none" >
67+ < div className = "absolute top-1/4 -left-20 w-72 h-72 bg-orange-500/10 rounded-full blur-3xl animate-pulse" style = { { animationDuration : '4s' } } />
68+ < div className = "absolute bottom-1/4 -right-20 w-96 h-96 bg-blue-500/10 rounded-full blur-3xl animate-pulse" style = { { animationDuration : '6s' , animationDelay : '1s' } } />
69+ < div className = "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[600px] h-[600px] bg-purple-500/5 rounded-full blur-3xl animate-pulse" style = { { animationDuration : '8s' , animationDelay : '2s' } } />
70+ </ div >
71+
72+ { /* Floating Icons */ }
73+ < div className = "absolute inset-0 overflow-hidden pointer-events-none opacity-20" >
74+ < GitBranch className = "absolute top-20 left-20 w-8 h-8 text-orange-400 animate-float" style = { { animationDelay : '0s' , animationDuration : '6s' } } />
75+ < Activity className = "absolute top-40 right-32 w-10 h-10 text-blue-400 animate-float" style = { { animationDelay : '1s' , animationDuration : '7s' } } />
76+ < Zap className = "absolute bottom-32 left-32 w-6 h-6 text-purple-400 animate-float" style = { { animationDelay : '2s' , animationDuration : '5s' } } />
77+ < GitBranch className = "absolute bottom-20 right-20 w-7 h-7 text-orange-400 animate-float" style = { { animationDelay : '3s' , animationDuration : '8s' } } />
78+ </ div >
79+
80+ < div className = { `w-full max-w-md relative z-10 transition-all duration-1000 ${ mounted ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-8' } ` } >
6081 { /* Logo & Title */ }
61- < div className = "text-center mb-8" >
62- < div className = "inline-flex items-center justify-center w-16 h-16 bg-orange-500 rounded-2xl mb-4 shadow-lg shadow-orange-500/20" >
63- < LogIn className = "w-8 h-8 text-white" />
82+ < div className = { `text-center mb-8 transition-all duration-700 delay-100 ${ mounted ? 'opacity-100 translate-y-0' : 'opacity-0 -translate-y-4' } ` } >
83+ < div className = "inline-flex items-center justify-center w-20 h-20 bg-gradient-to-br from-orange-500 to-orange-600 rounded-3xl mb-6 shadow-2xl shadow-orange-500/30 relative group hover:scale-110 transition-transform duration-300" >
84+ < div className = "absolute inset-0 bg-gradient-to-br from-orange-400 to-orange-600 rounded-3xl blur-xl opacity-50 group-hover:opacity-75 transition-opacity" />
85+ < LogIn className = "w-10 h-10 text-white relative z-10 group-hover:rotate-12 transition-transform duration-300" />
6486 </ div >
65- < h1 className = "text-3xl font-bold text-white mb-2" > GitLab CI/CD Dashboard</ h1 >
66- < p className = "text-zinc-400" > Sign in to your account</ p >
87+ < h1 className = "text-4xl font-bold text-white mb-3 bg-gradient-to-r from-white to-zinc-300 bg-clip-text text-transparent" >
88+ GitLab CI/CD Dashboard
89+ </ h1 >
90+ < p className = "text-zinc-400 text-lg" > Sign in to your account</ p >
6791 </ div >
6892
6993 { /* Login Form */ }
70- < div className = " bg-zinc-900 rounded-2xl shadow-xl border border-zinc-800 p-8" >
94+ < div className = { ` bg-zinc-900/80 backdrop-blur-xl rounded-3xl shadow-2xl border border-zinc-800/50 p-8 transition-all duration-700 delay-200 hover:border-zinc-700/50 ${ mounted ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-4' } ` } >
7195 < form onSubmit = { handleLogin } className = "space-y-6" >
7296 { /* Error Message */ }
7397 { error && (
74- < div className = "bg-red-950 border border-red-900 rounded-lg p-4 flex items-center gap-3" >
75- < AlertCircle className = "w-5 h-5 text-red-400 flex-shrink-0" />
98+ < div className = "bg-red-950/50 backdrop-blur-sm border border-red-900/50 rounded-xl p-4 flex items-center gap-3 animate-shake " >
99+ < AlertCircle className = "w-5 h-5 text-red-400 flex-shrink-0 animate-pulse " />
76100 < p className = "text-sm text-red-400" > { error } </ p >
77101 </ div >
78102 ) }
79103
80104 { /* Username */ }
81- < div >
82- < label htmlFor = "username" className = "block text-sm font-medium text-zinc-300 mb-2" >
105+ < div className = "group" >
106+ < label htmlFor = "username" className = "block text-sm font-medium text-zinc-300 mb-2 group-focus-within:text-orange-400 transition-colors " >
83107 Username
84108 </ label >
85109 < input
@@ -89,13 +113,13 @@ export default function LoginPage() {
89113 onChange = { ( e ) => setUsername ( e . target . value ) }
90114 placeholder = "Enter your username"
91115 required
92- className = "w-full px-4 py-3 bg-zinc-800 border border-zinc-700 rounded-lg text-white placeholder-zinc-500 focus:outline-none focus:ring-2 focus:ring-orange-500 focus:border-transparent transition-all"
116+ className = "w-full px-4 py-3.5 bg-zinc-800/50 backdrop-blur-sm border border-zinc-700/50 rounded-xl text-white placeholder-zinc-500 focus:outline-none focus:ring-2 focus:ring-orange-500 focus:border-transparent focus:bg-zinc-800 transition-all duration-300 hover:border-zinc-600 "
93117 />
94118 </ div >
95119
96120 { /* Password */ }
97- < div >
98- < label htmlFor = "password" className = "block text-sm font-medium text-zinc-300 mb-2" >
121+ < div className = "group" >
122+ < label htmlFor = "password" className = "block text-sm font-medium text-zinc-300 mb-2 group-focus-within:text-orange-400 transition-colors " >
99123 Password
100124 </ label >
101125 < div className = "relative" >
@@ -106,12 +130,12 @@ export default function LoginPage() {
106130 onChange = { ( e ) => setPassword ( e . target . value ) }
107131 placeholder = "Enter your password"
108132 required
109- className = "w-full px-4 py-3 pr-12 bg-zinc-800 border border-zinc-700 rounded-lg text-white placeholder-zinc-500 focus:outline-none focus:ring-2 focus:ring-orange-500 focus:border-transparent transition-all"
133+ className = "w-full px-4 py-3.5 pr-12 bg-zinc-800/50 backdrop-blur-sm border border-zinc-700/50 rounded-xl text-white placeholder-zinc-500 focus:outline-none focus:ring-2 focus:ring-orange-500 focus:border-transparent focus:bg-zinc-800 transition-all duration-300 hover:border-zinc-600 "
110134 />
111135 < button
112136 type = "button"
113137 onClick = { ( ) => setShowPassword ( ! showPassword ) }
114- className = "absolute right-3 top-1/2 -translate-y-1/2 text-zinc-500 hover:text-white transition-colors "
138+ className = "absolute right-4 top-1/2 -translate-y-1/2 text-zinc-500 hover:text-orange-400 transition-all duration-200 hover:scale-110 "
115139 >
116140 { showPassword ? < EyeOff className = "w-5 h-5" /> : < Eye className = "w-5 h-5" /> }
117141 </ button >
@@ -122,27 +146,77 @@ export default function LoginPage() {
122146 < button
123147 type = "submit"
124148 disabled = { loading || ! username || ! password }
125- className = "w-full bg-orange-500 hover:bg -orange-600 text-white font-semibold py-3 rounded-lg transition-all disabled:opacity-50 disabled:cursor-not-allowed shadow-lg shadow-orange-500/20 hover:shadow-orange-500/40 "
149+ className = "group relative w-full bg-gradient-to-r from- orange-500 to-orange-600 hover:from -orange-600 hover:to-orange-700 text-white font-semibold py-3.5 rounded-xl transition-all duration-300 disabled:opacity-50 disabled:cursor-not-allowed shadow-lg shadow-orange-500/30 hover:shadow-orange-500/50 hover:scale-[1.02] active:scale-[0.98] overflow-hidden "
126150 >
127- { loading ? 'Signing in...' : 'Sign In' }
151+ < div className = "absolute inset-0 bg-gradient-to-r from-orange-400 to-orange-500 opacity-0 group-hover:opacity-100 transition-opacity duration-300" />
152+ < div className = "relative flex items-center justify-center gap-2" >
153+ { loading ? (
154+ < >
155+ < div className = "w-5 h-5 border-2 border-white/30 border-t-white rounded-full animate-spin" />
156+ < span > Signing in...</ span >
157+ </ >
158+ ) : (
159+ < >
160+ < LogIn className = "w-5 h-5 group-hover:translate-x-1 transition-transform" />
161+ < span > Sign In</ span >
162+ </ >
163+ ) }
164+ </ div >
128165 </ button >
129166 </ form >
130167
131168 { /* Info */ }
132- < div className = "mt-6 pt-6 border-t border-zinc-800" >
169+ < div className = "mt-6 pt-6 border-t border-zinc-800/50 " >
133170 < p className = "text-sm text-zinc-500 text-center" >
134171 Default credentials are set in your environment variables
135172 </ p >
136173 </ div >
137174 </ div >
138175
139176 { /* Footer */ }
140- < div className = " mt-8 text-center" >
177+ < div className = { ` mt-8 text-center transition-all duration-700 delay-300 ${ mounted ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-4' } ` } >
141178 < p className = "text-sm text-zinc-600" >
142179 Built with ❤️ using Next.js & TypeScript
143180 </ p >
144181 </ div >
145182 </ div >
183+
184+ < style jsx > { `
185+ @keyframes float {
186+ 0%, 100% {
187+ transform: translateY(0px) translateX(0px);
188+ }
189+ 25% {
190+ transform: translateY(-20px) translateX(10px);
191+ }
192+ 50% {
193+ transform: translateY(-10px) translateX(-10px);
194+ }
195+ 75% {
196+ transform: translateY(-30px) translateX(5px);
197+ }
198+ }
199+
200+ @keyframes shake {
201+ 0%, 100% {
202+ transform: translateX(0);
203+ }
204+ 10%, 30%, 50%, 70%, 90% {
205+ transform: translateX(-4px);
206+ }
207+ 20%, 40%, 60%, 80% {
208+ transform: translateX(4px);
209+ }
210+ }
211+
212+ .animate-float {
213+ animation: float 6s ease-in-out infinite;
214+ }
215+
216+ .animate-shake {
217+ animation: shake 0.5s ease-in-out;
218+ }
219+ ` } </ style >
146220 </ div >
147221 ) ;
148222}
0 commit comments