-
JASWANTH A authoredJASWANTH A authored
AdminLogin4.jsx 7.12 KiB
import { useState } from "react";
import { FiMail, FiEye, FiEyeOff } from "react-icons/fi";
import { useNavigate } from "react-router-dom";
import axios from "axios";
const loginImage = new URL("/public/assets/login_img/loginadmin.svg", import.meta.url).href;
//const API_BASE_URL = "https://8dfst7hm-3000.inc1.devtunnels.ms/";
const API_BASE_URL = "http://localhost:5000/";
export default function AdminLogin() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [showPassword, setShowPassword] = useState(false);
const [error, setError] = useState({ email: "", password: "", general: "" });
const validateEmail = (email) => /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(email);
const validatePassword = (pass) => pass.length >= 8;
const navigate = useNavigate();
const handleEmailChange = (e) => {
const value = e.target.value;
setEmail(value);
setError((prev) => ({
...prev,
email: value === "" ? "" : !validateEmail(value) ? "Invalid email format" : ""
}));
};
const handlePasswordChange = (e) => {
const value = e.target.value;
setPassword(value);
setError((prev) => ({
...prev,
password: value === "" ? "" : !validatePassword(value) ? "Password must be at least 8 characters" : ""
}));
};
const [loading, setLoading] = useState(false);
const handleSubmit = async (e) => {
e.preventDefault();
if (loading) return;
setLoading(true);
let newErrors = { email: "", password: "", general: "" };
// Validation
if (!validateEmail(email)) newErrors.email = "Invalid email format.";
if (!validatePassword(password)) newErrors.password = "Password must be at least 8 characters long.";
if (newErrors.email || newErrors.password) {
//newErrors.general = "*Incorrect Email or Password!";
setError(newErrors);
setLoading(false);
return;
}
try {
const response = await axios.post(
`${API_BASE_URL}api/auth/login`,
{ email, password },
{
headers: { "Content-Type": "application/json" },
withCredentials: true,
}
);
if (response.status === 200) {
console.log("Login Success:", response.data);
alert("Login Successful!");
setError({ email: "", password: "", general: "" });
navigate("/dashboard");
}
} catch (error) {
console.error(error.response?.data || error.message);
setError({
email: error.response?.data?.email || "",
password: error.response?.data?.password || "",
general: error.response?.data?.message || "Login failed. Please check your credentials.",
});
}finally{
setLoading(false);
}
};
return (
<div className="flex flex-col items-center justify-center h-screen bg-[#D9F6F0] px-6 py-4">
<h1 className="text-4xl font-font-primary font-bold text-[#0C4339] mb-6 text-center w-full max-w-[90%] md:text-left">
OMPOI - Admin
</h1>
<div className="bg-[#2E2E2E] p-6 rounded-[32.6px] shadow-lg w-[90%] h-[85%] flex flex-col md:flex-row py-12">
<div className="hidden md:flex w-1/2 items-center justify-center p-4 min-w-[300px]">
<img src={loginImage} alt="Login" className="w-[80%] lg:w-[80%] xl:w-[80%]" />
</div>
<div className="w-[1px] bg-[#7DEBD9] hidden md:block"></div>
<div className="w-full md:w-1/2 flex flex-col items-center justify-start p-6 text-[#6FE7D1] mt-12">
<h2 className="text-4xl md:text-3xl font-font-primary font-semibold text-[7DEBD9] mb-11 md:mb-15">
Admin Login
</h2>
<form onSubmit={handleSubmit} className="w-full max-w-md">
<div className="relative w-full mb-8">
<div className={`relative border-2 rounded-lg border-[#6FE7D1] bg-transparent ${error.email ? "border-[#EEAB4D]" : ""}`}>
<label
className={`absolute -top-3 left-4 px-2 bg-[#2E2E2E] border border-[#6FE7D1] rounded-md text-sm font-font-primary font-medium ${error.email ? "border-[#EEAB4D] text-[#EEAB4D]" : "text-[#6FE7D1]"}`}
>
Admin Email
</label>
<input
type="text"
value={email}
onChange={handleEmailChange}
placeholder="Enter email"
className={`w-full h-14 px-3 pr-12 bg-transparent text-white text-lg focus:outline-none font-font-primary ${
error.email ? "border-red-500" : "border-gray-300"
}`}
/>
<FiMail
className="absolute right-4 top-1/2 transform -translate-y-1/2 text-xl"
style={{ color: error.email ? "#EEAB4D" : "#6FE7D1" }}
/>
</div>
{error.email && <p className="text-[#EEAB4D] text-sm mt-1">{error.email}</p>}
</div>
{/* Passwd Input */}
<div className="relative w-full mb-2">
<div className={`relative border-2 rounded-lg border-[#6FE7D1] bg-transparent ${error.password ? "border-[#EEAB4D]" : ""}`}>
<label
className={`absolute -top-3 left-4 px-2 bg-[#2E2E2E] border border-[#6FE7D1] rounded-md text-sm font-font-primary font-medium ${error.password ? "border-[#EEAB4D] text-[#EEAB4D]" : "text-[#6FE7D1]"}`}
>
Password
</label>
<input
type={showPassword ? "text" : "password"}
value={password}
onChange={handlePasswordChange}
placeholder="Enter your password"
className="w-full h-14 px-4 pr-12 bg-transparent text-white text-lg focus:outline-none font-font-primary"
/>
{showPassword ? (
<FiEyeOff
className="absolute right-4 top-1/2 transform -translate-y-1/2 text-xl cursor-pointer"
style={{ color: error.password ? "#EEAB4D" : "#6FE7D1" }}
onClick={() => setShowPassword(!showPassword)}
/>
) : (
<FiEye
className="absolute right-4 top-1/2 transform -translate-y-1/2 text-xl cursor-pointer"
style={{ color: error.password ? "#EEAB4D" : "#6FE7D1" }}
onClick={() => setShowPassword(!showPassword)}
/>
)}
</div>
{error.password && <p className="text-[#EEAB4D] text-sm mt-1">{error.password}</p>}
</div>
{/* Fgt Passwd & general error */}
<div className="flex justify-between items-center mt-2 w-full">
<a href="#" className="text-[#27DEBF] hover:underline text-sm font-font-primary font-semibold">
Forgot Password?
</a>
{error.general && (
<span className="text-[#EEAB4D] text-sm font-semibold font-font-primary">
{error.general}
</span>
)}
</div>
{/* signin btn */}
<div className="mt-8 flex justify-center">
<button
type="submit"
className="w-[100%] md:w-48 h-14 text-[#263238] font-bold rounded-full bg-[#6FE7D1] shadow-md hover:bg-[#5CC4AE] transition text-lg font-font-primary font-extrabold flex items-center justify-center"
disabled={loading}
>
{loading ? (
<svg className="animate-spin h-6 w-6 mr-2" 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-8v8H4z"></path>
</svg>
) : (
"Sign In"
)}
</button>
</div>
</form>
</div>
</div>
</div>
);
}