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
201 changes: 145 additions & 56 deletions frontend/src/components/auth/LoginForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,27 @@ import { useNavigate, Link } from 'react-router-dom';
import { Button } from '../ui/button';
import { Input } from '../ui/input';
import { Label } from '../ui/label';
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '../ui/card';
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>
)

export function LoginForm() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
Expand All @@ -22,7 +40,7 @@ export function LoginForm() {

try {
await signIn(email, password);
navigate('/');
navigate('/dashboard');
} catch (err: any) {
setError(err.message || 'Login failed');
} finally {
Expand All @@ -31,65 +49,136 @@ export function LoginForm() {
};

return (
<div className="min-h-screen flex items-center justify-center bg-gradient-to-br from-slate-50 to-slate-100 dark:from-slate-900 dark:to-slate-800 p-4">
<Card className="w-full max-w-md">
<CardHeader className="space-y-1">
<CardTitle className="text-2xl font-bold">Welcome back</CardTitle>
<CardDescription>
Enter your credentials to access CodeIntel
</CardDescription>
</CardHeader>

<form onSubmit={handleSubmit}>
<CardContent className="space-y-4">
{error && (
<Alert variant="destructive">
<AlertDescription>{error}</AlertDescription>
</Alert>
)}
<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="space-y-2">
<Label htmlFor="email">Email</Label>
<Input
id="email"
type="email"
placeholder="your@email.com"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
disabled={loading}
/>
{/* 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="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">
Sign in to CodeIntel
</h1>
<p className="text-gray-400">
Continue your AI-powered code exploration
</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="space-y-2">
<Label htmlFor="password">Password</Label>
<Input
id="password"
type="password"
placeholder="••••••••"
value={password}
onChange={(e) => setPassword(e.target.value)}
required
minLength={6}
disabled={loading}
/>
<div className="space-y-2">
<Label htmlFor="email" className="text-gray-300">Email</Label>
<Input
id="email"
type="email"
placeholder="you@example.com"
value={email}
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"
/>
</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>
<Input
id="password"
type="password"
placeholder="••••••••"
value={password}
onChange={(e) => setPassword(e.target.value)}
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"
/>
</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
>
<GitHubIcon />
<span className="ml-2">GitHub</span>
<span className="ml-2 text-xs text-gray-500">(Coming soon)</span>
</Button>
</div>
</CardContent>
</div>

<CardFooter className="flex flex-col space-y-4">
<Button type="submit" className="w-full" disabled={loading}>
{loading ? 'Signing in...' : 'Sign In'}
</Button>

<p className="text-sm text-center text-muted-foreground">
Don't have an account?{' '}
<Link to="/signup" className="text-primary hover:underline font-medium">
Sign up
</Link>
</p>
</CardFooter>
</form>
</Card>
{/* Sign up link */}
<p className="text-center text-gray-400 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>
</p>
</div>
</div>
</div>
);
}
Loading
Loading