ajinkya-mhetre-mern
Version:
A MERN starter with frontend and backend folders
145 lines (130 loc) • 5.21 kB
JSX
// src/pages/auth/Login.jsx
import React, { useState } from 'react'
import { Link } from 'react-router-dom'
import { useAuth } from '../../contexts/AuthContext'
const baseUrl = import.meta.env.VITE_API_URL;
function Login() {
const [formData, setFormData] = useState({
email: '',
password: ''
})
const [loading, setLoading] = useState(false)
const [error, setError] = useState('')
const { login } = useAuth()
const handleChange = (e) => {
setFormData({
...formData,
[e.target.name]: e.target.value
})
// Clear error when user starts typing
if (error) setError('')
}
const handleSubmit = async (e) => {
e.preventDefault()
setLoading(true)
setError('')
try {
const response = await fetch(`${baseUrl}/auth/login`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(formData)
})
const data = await response.json()
if (data.success) {
login(data) // This will handle routing based on user role
} else {
setError(data.message || 'Login failed')
}
} catch (error) {
setError('Network error. Please try again.')
console.error('Login error:', error)
} finally {
setLoading(false)
}
}
return (
<div className="min-h-screen bg-gradient-to-br from-green-50 to-blue-50 flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
<div className="max-w-md w-full space-y-8">
<div>
<div className="mx-auto h-16 w-16 bg-green-600 rounded-full flex items-center justify-center">
<svg className="h-8 w-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.746 0 3.332.477 4.5 1.253v13C19.832 18.477 18.246 18 16.5 18c-1.746 0-3.332.477-4.5 1.253" />
</svg>
</div>
<h2 className="mt-6 text-center text-3xl font-extrabold text-gray-900">
Sign in to your account
</h2>
<p className="mt-2 text-center text-sm text-gray-600">
Welcome back to Farm Platform
</p>
</div>
<form className="mt-8 space-y-6" onSubmit={handleSubmit}>
<div className="bg-white p-8 rounded-xl shadow-lg space-y-6">
{error && (
<div className="bg-red-50 border border-red-200 text-red-700 px-4 py-3 rounded-lg">
{error}
</div>
)}
<div>
<label htmlFor="email" className="block text-sm font-medium text-gray-700 mb-2">
Email Address
</label>
<input
id="email"
name="email"
type="email"
required
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-green-500 focus:border-transparent transition duration-200"
placeholder="Enter your email"
value={formData.email}
onChange={handleChange}
/>
</div>
<div>
<label htmlFor="password" className="block text-sm font-medium text-gray-700 mb-2">
Password
</label>
<input
id="password"
name="password"
type="password"
required
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-green-500 focus:border-transparent transition duration-200"
placeholder="Enter your password"
value={formData.password}
onChange={handleChange}
/>
</div>
<br></br>
<button
type="submit"
disabled={loading}
className="w-full bg-green-600 text-white py-3 px-4 rounded-lg hover:bg-green-700 focus:ring-2 focus:ring-green-500 focus:ring-offset-2 transition duration-200 font-medium disabled:opacity-50 disabled:cursor-not-allowed"
>
{loading ? (
<div className="flex items-center justify-center">
<div className="animate-spin rounded-full h-5 w-5 border-b-2 border-white mr-2"></div>
Signing in...
</div>
) : (
'Sign in'
)}
</button>
<div className="text-center">
<span className="text-gray-600">Don't have an account? </span>
<Link
to="/register"
className="text-green-600 hover:text-green-500 font-medium"
>
Sign up here
</Link>
</div>
</div>
</form>
</div>
</div>
)
}
export default Login