add rag-view frontend
This commit is contained in:
136
rag-view/src/pages/LoginPage.jsx
Normal file
136
rag-view/src/pages/LoginPage.jsx
Normal file
@@ -0,0 +1,136 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { clearError } from "../features/slices/details-slice";
|
||||
import fetchLoginUser from "../features/fetch-async/fetchLoginUser";
|
||||
|
||||
function LoginPage() {
|
||||
const [email, setEmail] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
|
||||
const dispatch = useDispatch();
|
||||
const navigate = useNavigate();
|
||||
const { loading, error, token } = useSelector((state) => state.userDetails);
|
||||
|
||||
// Redirect if already logged in
|
||||
useEffect(() => {
|
||||
if (token) {
|
||||
navigate("/");
|
||||
}
|
||||
}, [token, navigate]);
|
||||
|
||||
// Clear error on unmount
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
dispatch(clearError());
|
||||
};
|
||||
}, [dispatch]);
|
||||
|
||||
const handleSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
const result = await dispatch(fetchLoginUser({ email, password }));
|
||||
|
||||
if (fetchLoginUser.fulfilled.match(result)) {
|
||||
navigate("/");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-[60vh] flex items-center justify-center">
|
||||
<div className="w-full max-w-md bg-slate-900/80 backdrop-blur-xl rounded-2xl shadow-2xl border border-slate-700/60 p-8">
|
||||
<h1 className="text-2xl font-semibold text-slate-50 text-center mb-2">
|
||||
Login
|
||||
</h1>
|
||||
<p className="text-sm text-slate-400 text-center mb-6">
|
||||
Enter your email and password, then press the button to continue.
|
||||
</p>
|
||||
|
||||
{error && (
|
||||
<div className="mb-4 p-3 rounded-xl bg-red-500/20 border border-red-500/50 text-red-300 text-sm text-center">
|
||||
{error.message || `Error: ${error.status}`}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<form onSubmit={handleSubmit} className="space-y-5">
|
||||
<div className="space-y-2">
|
||||
<label className="block text-sm font-medium text-slate-200">
|
||||
Email
|
||||
</label>
|
||||
<input
|
||||
type="email"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
placeholder="Your email"
|
||||
className="w-full rounded-xl bg-slate-800/80 border border-slate-600 focus:border-indigo-400 focus:ring-2 focus:ring-indigo-500/60 focus:outline-none px-4 py-2.5 text-slate-100 placeholder:text-slate-500 text-sm"
|
||||
required
|
||||
disabled={loading}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<label className="block text-sm font-medium text-slate-200">
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
value={password}
|
||||
minLength={8}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
placeholder="Your password"
|
||||
className="w-full rounded-xl bg-slate-800/80 border border-slate-600 focus:border-indigo-400 focus:ring-2 focus:ring-indigo-500/60 focus:outline-none px-4 py-2.5 text-slate-100 placeholder:text-slate-500 text-sm"
|
||||
required
|
||||
disabled={loading}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
disabled={loading}
|
||||
className="w-full mt-2 inline-flex items-center justify-center rounded-xl bg-indigo-500 hover:bg-indigo-400 active:bg-indigo-600 disabled:bg-indigo-500/50 disabled:cursor-not-allowed transition-colors px-4 py-2.5 text-sm font-semibold text-white shadow-lg shadow-indigo-500/30"
|
||||
>
|
||||
{loading ? (
|
||||
<>
|
||||
<svg
|
||||
className="animate-spin -ml-1 mr-2 h-4 w-4 text-white"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<circle
|
||||
className="opacity-25"
|
||||
cx="12"
|
||||
cy="12"
|
||||
r="10"
|
||||
stroke="currentColor"
|
||||
strokeWidth="4"
|
||||
></circle>
|
||||
<path
|
||||
className="opacity-75"
|
||||
fill="currentColor"
|
||||
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
||||
></path>
|
||||
</svg>
|
||||
Logging in...
|
||||
</>
|
||||
) : (
|
||||
"Login"
|
||||
)}
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<p className="mt-6 text-center text-sm text-slate-400">
|
||||
Don't have an account?{" "}
|
||||
<a
|
||||
href="/register"
|
||||
className="text-indigo-400 hover:text-indigo-300 transition-colors"
|
||||
>
|
||||
Register
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default LoginPage;
|
||||
Reference in New Issue
Block a user