Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
217 changes: 90 additions & 127 deletions frontend/src/components/auth/LoginForm.tsx
Original file line number Diff line number Diff line change
@@ -1,103 +1,63 @@
import { useState } from 'react';
import { useAuth } from '../../contexts/AuthContext';
import { useNavigate, Link } from 'react-router-dom';
import { Button } from '../ui/button';
import { Input } from '../ui/input';
import { Label } from '../ui/label';
import { Alert, AlertDescription } from '../ui/alert';

// Icons
const CodeIntelLogo = () => (
<div className="w-10 h-10 rounded-xl bg-gradient-to-br from-blue-500 to-blue-600 flex items-center justify-center">
<span className="text-white font-bold text-lg">CI</span>
</div>
)

const GitHubIcon = () => (
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
<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" />
</svg>
)

const SparklesIcon = () => (
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 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" />
</svg>
)
import { useState } from 'react'
import { useAuth } from '@/contexts/AuthContext'
import { useNavigate, Link } from 'react-router-dom'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Alert, AlertDescription } from '@/components/ui/alert'
import { Navbar } from '@/components/landing'
import { Github, Loader2, Mail, Lock } from 'lucide-react'

export function LoginForm() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [error, setError] = useState('');
const [loading, setLoading] = useState(false);
const { signIn } = useAuth();
const navigate = useNavigate();
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const [error, setError] = useState('')
const [loading, setLoading] = useState(false)
const { signIn } = useAuth()
const navigate = useNavigate()

const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setError('');
setLoading(true);
e.preventDefault()
setError('')
setLoading(true)

try {
await signIn(email, password);
navigate('/dashboard');
await signIn(email, password)
navigate('/dashboard')
} catch (err: any) {
setError(err.message || 'Login failed');
setError(err.message || 'Login failed')
} finally {
setLoading(false);
setLoading(false)
}
};
}

return (
<div className="min-h-screen bg-[#09090b] flex flex-col">
{/* Navigation */}
<nav className="border-b border-white/5 bg-[#09090b]/80 backdrop-blur-xl">
<div className="max-w-6xl mx-auto px-6 h-16 flex items-center justify-between">
<Link to="/" className="flex items-center gap-3">
<CodeIntelLogo />
<span className="font-semibold text-white">CodeIntel</span>
</Link>
<a
href="https://github.com/opencodeintel/opencodeintel"
target="_blank"
rel="noopener noreferrer"
className="text-gray-400 hover:text-white transition-colors"
>
<GitHubIcon />
</a>
</div>
</nav>
<div className="min-h-screen bg-background flex flex-col">
<Navbar />

{/* Main Content */}
<div className="flex-1 flex items-center justify-center px-6 py-12">
<div className="w-full max-w-md">
{/* Header */}
<div className="w-full max-w-sm">
<div className="text-center mb-8">
<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">
<SparklesIcon />
<span className="text-sm text-blue-400">Welcome back</span>
</div>
<h1 className="text-3xl font-bold text-white mb-2">
<h1 className="text-2xl font-semibold text-foreground mb-2">
Sign in to CodeIntel
</h1>
<p className="text-gray-400">
Continue your AI-powered code exploration
<p className="text-sm text-muted-foreground">
Enter your credentials to continue
</p>
</div>

{/* Login Card */}
<div className="relative">
<div className="absolute inset-0 bg-gradient-to-r from-blue-500/10 to-cyan-500/10 rounded-2xl blur-xl opacity-50" />
<div className="relative bg-[#111113] rounded-2xl border border-white/10 p-8">
<form onSubmit={handleSubmit} className="space-y-6">
{error && (
<Alert variant="destructive" className="bg-red-500/10 border-red-500/20 text-red-400">
<AlertDescription>{error}</AlertDescription>
</Alert>
)}
<div className="bg-card rounded-lg border border-border p-6">
<form onSubmit={handleSubmit} className="space-y-4">
{error && (
<Alert variant="destructive" className="bg-destructive/10 border-destructive/20">
<AlertDescription>{error}</AlertDescription>
</Alert>
)}

<div className="space-y-2">
<Label htmlFor="email" className="text-gray-300">Email</Label>
<div className="space-y-2">
<Label htmlFor="email">Email</Label>
<div className="relative">
<Mail className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground" />
<Input
id="email"
type="email"
Expand All @@ -106,17 +66,23 @@ export function LoginForm() {
onChange={(e) => setEmail(e.target.value)}
required
disabled={loading}
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"
className="pl-10 h-10"
/>
</div>
</div>

<div className="space-y-2">
<div className="flex items-center justify-between">
<Label htmlFor="password" className="text-gray-300">Password</Label>
<button type="button" className="text-sm text-blue-400 hover:text-blue-300 transition-colors">
Forgot password?
</button>
</div>
<div className="space-y-2">
<div className="flex items-center justify-between">
<Label htmlFor="password">Password</Label>
<button
type="button"
className="text-xs text-muted-foreground hover:text-foreground transition-colors"
>
Forgot password?
</button>
</div>
<div className="relative">
<Lock className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground" />
<Input
id="password"
type="password"
Expand All @@ -126,59 +92,56 @@ export function LoginForm() {
required
minLength={6}
disabled={loading}
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"
className="pl-10 h-10"
/>
</div>

<Button
type="submit"
disabled={loading}
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"
>
{loading ? (
<div className="flex items-center gap-2">
<div className="w-4 h-4 border-2 border-white/30 border-t-white rounded-full animate-spin" />
<span>Signing in...</span>
</div>
) : (
'Sign in'
)}
</Button>
</form>

{/* Divider */}
<div className="relative my-6">
<div className="absolute inset-0 flex items-center">
<div className="w-full border-t border-white/10"></div>
</div>
<div className="relative flex justify-center text-sm">
<span className="px-4 bg-[#111113] text-gray-500">or continue with</span>
</div>
</div>

{/* Social Login */}
<Button
type="button"
variant="outline"
className="w-full h-12 bg-white/5 border-white/10 text-white hover:bg-white/10 rounded-xl"
disabled
type="submit"
disabled={loading}
className="w-full h-10 bg-accent hover:bg-accent/90 text-white"
>
<GitHubIcon />
<span className="ml-2">GitHub</span>
<span className="ml-2 text-xs text-gray-500">(Coming soon)</span>
{loading ? (
<span className="flex items-center gap-2">
<Loader2 className="w-4 h-4 animate-spin" />
Signing in...
</span>
) : (
'Sign in'
)}
</Button>
</form>

<div className="relative my-6">
<div className="absolute inset-0 flex items-center">
<div className="w-full border-t border-border" />
</div>
<div className="relative flex justify-center text-xs">
<span className="px-2 bg-card text-muted-foreground">or</span>
</div>
</div>

<Button
type="button"
variant="outline"
className="w-full h-10"
disabled
>
<Github className="w-4 h-4 mr-2" />
Continue with GitHub
<span className="ml-1 text-xs text-muted-foreground">(Soon)</span>
</Button>
</div>

{/* Sign up link */}
<p className="text-center text-gray-400 mt-6">
<p className="text-center text-sm text-muted-foreground mt-6">
Don't have an account?{' '}
<Link to="/signup" className="text-blue-400 hover:text-blue-300 font-medium transition-colors">
Sign up for free
<Link to="/signup" className="text-accent hover:underline">
Sign up
</Link>
</p>
</div>
</div>
</div>
);
)
}
Loading