DarainHyder
Initial clean deploy commit: removing binary files and venv
25732fb
import React, { useState } from 'react'
import { Link, useNavigate } from 'react-router-dom'
import { motion } from 'framer-motion'
import { useAuth } from '../../hooks/useAuth'
import { LogIn, Mail, Lock, BookOpen } from 'lucide-react'
import toast from 'react-hot-toast'
const Login = () => {
const navigate = useNavigate()
const { login } = useAuth()
const [formData, setFormData] = useState({
username: '',
email: ''
})
const [loading, setLoading] = useState(false)
const handleChange = (e) => {
setFormData({
...formData,
[e.target.name]: e.target.value
})
}
const handleSubmit = async (e) => {
e.preventDefault()
setLoading(true)
try {
await login(formData)
navigate('/')
} catch (error) {
// Error handled by toast in api.js
} finally {
setLoading(false)
}
}
return (
<div className="min-h-screen flex items-center justify-center p-4">
{/* Background decoration */}
<div className="absolute inset-0 overflow-hidden">
<div className="absolute -top-40 -right-40 w-80 h-80 bg-primary-400 rounded-full mix-blend-multiply filter blur-3xl opacity-20 animate-pulse-slow"></div>
<div className="absolute -bottom-40 -left-40 w-80 h-80 bg-accent-400 rounded-full mix-blend-multiply filter blur-3xl opacity-20 animate-pulse-slow" style={{ animationDelay: '1s' }}></div>
</div>
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5 }}
className="relative z-10 w-full max-w-md"
>
{/* Header */}
<div className="text-center mb-8">
<motion.div
initial={{ scale: 0 }}
animate={{ scale: 1 }}
transition={{ delay: 0.2, type: 'spring', stiffness: 200 }}
className="inline-flex items-center justify-center w-20 h-20 bg-gradient-to-br from-primary-500 to-accent-500 rounded-2xl mb-4 shadow-xl"
>
<BookOpen className="w-10 h-10 text-white" />
</motion.div>
<h1 className="text-4xl font-bold gradient-text mb-2">
Welcome Back
</h1>
<p className="text-slate-600">
Continue your learning journey
</p>
</div>
{/* Login Form */}
<motion.div
initial={{ opacity: 0, scale: 0.95 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ delay: 0.3 }}
className="card"
>
<form onSubmit={handleSubmit} className="space-y-6">
{/* Username */}
<div>
<label className="block text-sm font-semibold text-slate-700 mb-2">
Username
</label>
<div className="relative">
<Mail className="absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-slate-400" />
<input
type="text"
name="username"
value={formData.username}
onChange={handleChange}
className="input-field pl-11"
placeholder="Enter your username"
required
/>
</div>
</div>
{/* Email (optional for compatibility) */}
<div>
<label className="block text-sm font-semibold text-slate-700 mb-2">
Email
</label>
<div className="relative">
<Lock className="absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-slate-400" />
<input
type="email"
name="email"
value={formData.email}
onChange={handleChange}
className="input-field pl-11"
placeholder="Enter your email"
/>
</div>
</div>
{/* Submit Button */}
<motion.button
whileHover={{ scale: 1.02 }}
whileTap={{ scale: 0.98 }}
type="submit"
disabled={loading}
className="w-full btn-primary flex items-center justify-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed"
>
{loading ? (
<>
<div className="animate-spin rounded-full h-5 w-5 border-b-2 border-white"></div>
Logging in...
</>
) : (
<>
<LogIn className="w-5 h-5" />
Login
</>
)}
</motion.button>
</form>
{/* Divider */}
<div className="relative my-6">
<div className="absolute inset-0 flex items-center">
<div className="w-full border-t border-slate-200"></div>
</div>
<div className="relative flex justify-center text-sm">
<span className="px-4 bg-white text-slate-500">
Don't have an account?
</span>
</div>
</div>
{/* Register Link */}
<Link to="/register">
<motion.button
whileHover={{ scale: 1.02 }}
whileTap={{ scale: 0.98 }}
type="button"
className="w-full btn-secondary"
>
Create Account
</motion.button>
</Link>
</motion.div>
{/* Footer */}
<motion.p
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ delay: 0.5 }}
className="text-center text-sm text-slate-500 mt-6"
>
Powered by Multi-Agent AI System
</motion.p>
</motion.div>
</div>
)
}
export default Login