add rag-view frontend
This commit is contained in:
163
rag-view/src/pages/RegisterPage.jsx
Normal file
163
rag-view/src/pages/RegisterPage.jsx
Normal file
@@ -0,0 +1,163 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import fetchRegisterUser from "../features/fetch-async/fetchRegisterUser";
|
||||
import {
|
||||
USER_NAME_UNDEFINED,
|
||||
USER_EMAIL_UNDEFINED,
|
||||
} from "../features/constants";
|
||||
|
||||
function RegisterPage() {
|
||||
const [login, setLogin] = useState("");
|
||||
const [email, setEmail] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
const [confirm, setConfirm] = useState("");
|
||||
const [validationError, setValidationError] = useState("");
|
||||
|
||||
const dispatch = useDispatch();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const { userName, userEmail, loading, error } = useSelector(
|
||||
(state) => state.userDetails
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (loading) return;
|
||||
|
||||
if (
|
||||
userName !== USER_NAME_UNDEFINED &&
|
||||
userEmail !== USER_EMAIL_UNDEFINED
|
||||
) {
|
||||
navigate("/");
|
||||
}
|
||||
}, [loading, userName, userEmail, navigate]);
|
||||
|
||||
const handleClear = () => {
|
||||
setLogin("");
|
||||
setEmail("");
|
||||
setPassword("");
|
||||
setConfirm("");
|
||||
setValidationError("");
|
||||
};
|
||||
|
||||
const handleSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
setValidationError("");
|
||||
|
||||
if (login.length < 3) {
|
||||
setValidationError("Login must be at least 3 characters.");
|
||||
return;
|
||||
}
|
||||
if (password.length < 8) {
|
||||
setValidationError("Password must be at least 8 characters.");
|
||||
return;
|
||||
}
|
||||
if (password !== confirm) {
|
||||
setValidationError("Password and Confirm password do not match.");
|
||||
return;
|
||||
}
|
||||
|
||||
const payload = {
|
||||
username: login,
|
||||
email: email,
|
||||
password: password,
|
||||
confirmPassword: confirm,
|
||||
};
|
||||
|
||||
dispatch(fetchRegisterUser(payload));
|
||||
};
|
||||
|
||||
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">
|
||||
Register
|
||||
</h1>
|
||||
<p className="text-sm text-slate-400 text-center mb-6">
|
||||
Create a new account by choosing a login, email and a strong password.
|
||||
</p>
|
||||
|
||||
{(validationError || error) && (
|
||||
<div className="mb-4 text-sm text-red-400 text-center">
|
||||
{validationError || error}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<form onSubmit={handleSubmit} className="space-y-5">
|
||||
<div className="space-y-2">
|
||||
<label className="block text-sm font-medium text-slate-200">
|
||||
Login
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
value={login}
|
||||
onChange={(e) => setLogin(e.target.value)}
|
||||
placeholder="Your login"
|
||||
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"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<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"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<label className="block text-sm font-medium text-slate-200">
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
value={password}
|
||||
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"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<label className="block text-sm font-medium text-slate-200">
|
||||
Confirm password
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
value={confirm}
|
||||
onChange={(e) => setConfirm(e.target.value)}
|
||||
placeholder="Repeat 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"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex gap-3 mt-2">
|
||||
<button
|
||||
type="submit"
|
||||
disabled={loading}
|
||||
className="flex-1 inline-flex items-center justify-center rounded-xl bg-indigo-500 hover:bg-indigo-400 disabled:opacity-60 disabled:cursor-not-allowed active:bg-indigo-600 transition-colors px-4 py-2.5 text-sm font-semibold text-white shadow-lg shadow-indigo-500/30"
|
||||
>
|
||||
{loading ? "Registering..." : "Register"}
|
||||
</button>
|
||||
{(validationError || error) && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleClear}
|
||||
className="inline-flex items-center justify-center rounded-xl bg-slate-700 hover:bg-slate-600 active:bg-slate-800 transition-colors px-4 py-2.5 text-sm font-semibold text-slate-300"
|
||||
>
|
||||
Clear
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default RegisterPage;
|
||||
Reference in New Issue
Block a user