1- import { useState } from 'react' ;
2- import { useAuth } from '../../contexts/AuthContext' ;
3- import { useNavigate , Link } from 'react-router-dom' ;
4- import { Button } from '../ui/button' ;
5- import { Input } from '../ui/input' ;
6- import { Label } from '../ui/label' ;
7- import { Alert , AlertDescription } from '../ui/alert' ;
8-
9- // Icons
10- const CodeIntelLogo = ( ) => (
11- < div className = "w-10 h-10 rounded-xl bg-gradient-to-br from-blue-500 to-blue-600 flex items-center justify-center" >
12- < span className = "text-white font-bold text-lg" > CI</ span >
13- </ div >
14- )
15-
16- const GitHubIcon = ( ) => (
17- < svg className = "w-5 h-5" fill = "currentColor" viewBox = "0 0 24 24" >
18- < path fillRule = "evenodd" d = "M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" clipRule = "evenodd" />
19- </ svg >
20- )
21-
22- const SparklesIcon = ( ) => (
23- < svg className = "w-4 h-4" fill = "none" stroke = "currentColor" viewBox = "0 0 24 24" >
24- < path strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = { 2 } d = "M5 3v4M3 5h4M6 17v4m-2-2h4m5-16l2.286 6.857L21 12l-5.714 2.143L13 21l-2.286-6.857L5 12l5.714-2.143L13 3z" />
25- </ svg >
26- )
1+ import { useState } from 'react'
2+ import { useAuth } from '@/contexts/AuthContext'
3+ import { useNavigate , Link } from 'react-router-dom'
4+ import { motion } from 'framer-motion'
5+ import { Button } from '@/components/ui/button'
6+ import { Input } from '@/components/ui/input'
7+ import { Label } from '@/components/ui/label'
8+ import { Alert , AlertDescription } from '@/components/ui/alert'
9+ import { Navbar } from '@/components/landing'
10+ import { Sparkles , Github , Loader2 , Mail , Lock } from 'lucide-react'
2711
2812export function LoginForm ( ) {
29- const [ email , setEmail ] = useState ( '' ) ;
30- const [ password , setPassword ] = useState ( '' ) ;
31- const [ error , setError ] = useState ( '' ) ;
32- const [ loading , setLoading ] = useState ( false ) ;
33- const { signIn } = useAuth ( ) ;
34- const navigate = useNavigate ( ) ;
13+ const [ email , setEmail ] = useState ( '' )
14+ const [ password , setPassword ] = useState ( '' )
15+ const [ error , setError ] = useState ( '' )
16+ const [ loading , setLoading ] = useState ( false )
17+ const { signIn } = useAuth ( )
18+ const navigate = useNavigate ( )
3519
3620 const handleSubmit = async ( e : React . FormEvent ) => {
37- e . preventDefault ( ) ;
38- setError ( '' ) ;
39- setLoading ( true ) ;
21+ e . preventDefault ( )
22+ setError ( '' )
23+ setLoading ( true )
4024
4125 try {
42- await signIn ( email , password ) ;
43- navigate ( '/dashboard' ) ;
26+ await signIn ( email , password )
27+ navigate ( '/dashboard' )
4428 } catch ( err : any ) {
45- setError ( err . message || 'Login failed' ) ;
29+ setError ( err . message || 'Login failed' )
4630 } finally {
47- setLoading ( false ) ;
31+ setLoading ( false )
4832 }
49- } ;
33+ }
5034
5135 return (
52- < div className = "min-h-screen bg-[#09090b] flex flex-col" >
53- { /* Navigation */ }
54- < nav className = "border-b border-white/5 bg-[#09090b]/80 backdrop-blur-xl" >
55- < div className = "max-w-6xl mx-auto px-6 h-16 flex items-center justify-between" >
56- < Link to = "/" className = "flex items-center gap-3" >
57- < CodeIntelLogo />
58- < span className = "font-semibold text-white" > CodeIntel</ span >
59- </ Link >
60- < a
61- href = "https://github.com/opencodeintel/opencodeintel"
62- target = "_blank"
63- rel = "noopener noreferrer"
64- className = "text-gray-400 hover:text-white transition-colors"
65- >
66- < GitHubIcon />
67- </ a >
68- </ div >
69- </ nav >
36+ < div className = "min-h-screen bg-background flex flex-col" >
37+ < Navbar />
38+
39+ { /* Background effects */ }
40+ < div className = "fixed inset-0 overflow-hidden pointer-events-none" >
41+ < div className = "absolute inset-0 bg-[linear-gradient(rgba(255,255,255,0.02)_1px,transparent_1px),linear-gradient(90deg,rgba(255,255,255,0.02)_1px,transparent_1px)] dark:bg-[linear-gradient(rgba(255,255,255,0.02)_1px,transparent_1px),linear-gradient(90deg,rgba(255,255,255,0.02)_1px,transparent_1px)] bg-[size:64px_64px] [mask-image:radial-gradient(ellipse_50%_50%_at_50%_50%,black_40%,transparent_100%)]" />
42+ < motion . div
43+ className = "absolute top-1/4 left-1/4 w-[500px] h-[500px] rounded-full"
44+ style = { { background : 'radial-gradient(circle, rgba(99,102,241,0.15) 0%, transparent 60%)' } }
45+ animate = { { x : [ 0 , 30 , 0 ] , y : [ 0 , - 20 , 0 ] } }
46+ transition = { { duration : 10 , repeat : Infinity , ease : 'easeInOut' } }
47+ />
48+ < motion . div
49+ className = "absolute bottom-1/4 right-1/4 w-[400px] h-[400px] rounded-full"
50+ style = { { background : 'radial-gradient(circle, rgba(139,92,246,0.1) 0%, transparent 60%)' } }
51+ animate = { { x : [ 0 , - 25 , 0 ] , y : [ 0 , 25 , 0 ] } }
52+ transition = { { duration : 12 , repeat : Infinity , ease : 'easeInOut' } }
53+ />
54+ </ div >
7055
71- { /* Main Content */ }
72- < div className = "flex-1 flex items-center justify-center px-6 py-12" >
73- < div className = "w-full max-w-md" >
56+ { /* Main content */ }
57+ < div className = "flex-1 flex items-center justify-center px-6 py-12 relative z-10" >
58+ < motion . div
59+ className = "w-full max-w-md"
60+ initial = { { opacity : 0 , y : 20 } }
61+ animate = { { opacity : 1 , y : 0 } }
62+ transition = { { duration : 0.5 } }
63+ >
7464 { /* Header */ }
7565 < div className = "text-center mb-8" >
76- < div className = "inline-flex items-center gap-2 px-3 py-1 rounded-full bg-blue-500/10 border border-blue-500/20 mb-6" >
77- < SparklesIcon />
78- < span className = "text-sm text-blue-400" > Welcome back</ span >
79- </ div >
80- < h1 className = "text-3xl font-bold text-white mb-2" >
66+ < motion . div
67+ className = "inline-flex items-center gap-2 px-3 py-1.5 rounded-full border border-accent/30 bg-accent/5 text-sm mb-6"
68+ initial = { { opacity : 0 , scale : 0.9 } }
69+ animate = { { opacity : 1 , scale : 1 } }
70+ transition = { { delay : 0.1 } }
71+ >
72+ < Sparkles className = "w-3.5 h-3.5 text-accent" />
73+ < span className = "text-accent font-medium" > Welcome back</ span >
74+ </ motion . div >
75+ < h1 className = "text-3xl font-bold text-foreground mb-2" >
8176 Sign in to CodeIntel
8277 </ h1 >
83- < p className = "text-gray-400 " >
84- Continue your AI-powered code exploration
78+ < p className = "text-muted-foreground " >
79+ Continue your code exploration
8580 </ p >
8681 </ div >
8782
88- { /* Login Card */ }
89- < div className = "relative" >
90- < div className = "absolute inset-0 bg-gradient-to-r from-blue-500/10 to-cyan-500/10 rounded-2xl blur-xl opacity-50" />
91- < div className = "relative bg-[#111113] rounded-2xl border border-white/10 p-8" >
92- < form onSubmit = { handleSubmit } className = "space-y-6" >
83+ { /* Login card */ }
84+ < motion . div
85+ className = "relative"
86+ initial = { { opacity : 0 , y : 20 } }
87+ animate = { { opacity : 1 , y : 0 } }
88+ transition = { { delay : 0.2 } }
89+ >
90+ < div className = "absolute inset-0 bg-gradient-to-r from-accent/10 to-violet-500/10 rounded-2xl blur-xl opacity-50" />
91+ < div className = "relative bg-card/50 backdrop-blur-sm rounded-2xl border border-border p-8" >
92+ < form onSubmit = { handleSubmit } className = "space-y-5" >
9393 { error && (
94- < Alert variant = "destructive" className = "bg-red-500 /10 border-red-500 /20 text-red-400 " >
94+ < Alert variant = "destructive" className = "bg-destructive /10 border-destructive /20" >
9595 < AlertDescription > { error } </ AlertDescription >
9696 </ Alert >
9797 ) }
9898
9999 < div className = "space-y-2" >
100- < Label htmlFor = "email" className = "text-gray-300" > Email</ Label >
101- < Input
102- id = "email"
103- type = "email"
104- placeholder = "you@example.com"
105- value = { email }
106- onChange = { ( e ) => setEmail ( e . target . value ) }
107- required
108- disabled = { loading }
109- className = "bg-white/5 border-white/10 text-white placeholder:text-gray-500 focus:border-blue-500/50 focus:ring-blue-500/20 h-12 rounded-xl"
110- />
100+ < Label htmlFor = "email" className = "text-foreground" > Email</ Label >
101+ < div className = "relative" >
102+ < Mail className = "absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground" />
103+ < Input
104+ id = "email"
105+ type = "email"
106+ placeholder = "you@example.com"
107+ value = { email }
108+ onChange = { ( e ) => setEmail ( e . target . value ) }
109+ required
110+ disabled = { loading }
111+ className = "pl-10 h-12 bg-background/50 border-border focus:border-accent"
112+ />
113+ </ div >
111114 </ div >
112115
113116 < div className = "space-y-2" >
114117 < div className = "flex items-center justify-between" >
115- < Label htmlFor = "password" className = "text-gray-300" > Password</ Label >
116- < button type = "button" className = "text-sm text-blue-400 hover:text-blue-300 transition-colors" >
118+ < Label htmlFor = "password" className = "text-foreground" > Password</ Label >
119+ < button
120+ type = "button"
121+ className = "text-sm text-accent hover:text-accent/80 transition-colors"
122+ >
117123 Forgot password?
118124 </ button >
119125 </ div >
120- < Input
121- id = "password"
122- type = "password"
123- placeholder = "••••••••"
124- value = { password }
125- onChange = { ( e ) => setPassword ( e . target . value ) }
126- required
127- minLength = { 6 }
128- disabled = { loading }
129- className = "bg-white/5 border-white/10 text-white placeholder:text-gray-500 focus:border-blue-500/50 focus:ring-blue-500/20 h-12 rounded-xl"
130- />
126+ < div className = "relative" >
127+ < Lock className = "absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground" />
128+ < Input
129+ id = "password"
130+ type = "password"
131+ placeholder = "••••••••"
132+ value = { password }
133+ onChange = { ( e ) => setPassword ( e . target . value ) }
134+ required
135+ minLength = { 6 }
136+ disabled = { loading }
137+ className = "pl-10 h-12 bg-background/50 border-border focus:border-accent"
138+ />
139+ </ div >
131140 </ div >
132141
133142 < Button
134143 type = "submit"
135144 disabled = { loading }
136- className = "w-full h-12 bg-gradient-to-r from-blue-500 to-blue-600 hover:from-blue-600 hover:to-blue-700 text-white font-medium rounded-xl transition-all disabled:opacity-50 "
145+ className = "w-full h-12 bg-accent hover:bg-accent/90 text-white font-medium"
137146 >
138147 { loading ? (
139- < div className = "flex items-center gap-2" >
140- < div className = "w-4 h-4 border-2 border-white/30 border-t-white rounded-full animate-spin" />
141- < span > Signing in...</ span >
142- </ div >
148+ < span className = "flex items-center gap-2" >
149+ < Loader2 className = "w-4 h-4 animate-spin" />
150+ Signing in...
151+ </ span >
143152 ) : (
144153 'Sign in'
145154 ) }
@@ -149,36 +158,36 @@ export function LoginForm() {
149158 { /* Divider */ }
150159 < div className = "relative my-6" >
151160 < div className = "absolute inset-0 flex items-center" >
152- < div className = "w-full border-t border-white/10" > </ div >
161+ < div className = "w-full border-t border-border" / >
153162 </ div >
154163 < div className = "relative flex justify-center text-sm" >
155- < span className = "px-4 bg-[#111113] text-gray-500 " > or continue with</ span >
164+ < span className = "px-4 bg-card/50 text-muted-foreground " > or continue with</ span >
156165 </ div >
157166 </ div >
158167
159- { /* Social Login */ }
168+ { /* GitHub OAuth placeholder */ }
160169 < Button
161170 type = "button"
162171 variant = "outline"
163- className = "w-full h-12 bg-white/5 border-white/10 text-white hover:bg-white/10 rounded-xl "
172+ className = "w-full h-12 border-border hover:bg-muted/50 "
164173 disabled
165174 >
166- < GitHubIcon />
175+ < Github className = "w-5 h-5" />
167176 < span className = "ml-2" > GitHub</ span >
168- < span className = "ml-2 text-xs text-gray-500 " > (Coming soon)</ span >
177+ < span className = "ml-2 text-xs text-muted-foreground " > (Coming soon)</ span >
169178 </ Button >
170179 </ div >
171- </ div >
180+ </ motion . div >
172181
173182 { /* Sign up link */ }
174- < p className = "text-center text-gray-400 mt-6" >
183+ < p className = "text-center text-muted-foreground mt-6" >
175184 Don't have an account?{ ' ' }
176- < Link to = "/signup" className = "text-blue-400 hover:text-blue-300 font-medium transition-colors" >
185+ < Link to = "/signup" className = "text-accent hover:text-accent/80 font-medium transition-colors" >
177186 Sign up for free
178187 </ Link >
179188 </ p >
180- </ div >
189+ </ motion . div >
181190 </ div >
182191 </ div >
183- ) ;
192+ )
184193}
0 commit comments