I'm trying to let the user sign in using email OR username, I already implemented the backend and it's working fine using Postman, but I didn't know how to implement it in the frontend,
Login.jsx:
export default function Login() {
const [credentials, setCredentials] = useState({
email: undefined,
username: undefined,
password: undefined,
});
const [loginErr, setMsg] = useState({
fail: false,
msg: "",
});
const { user, isFetching, dispatch } = useContext(Context);
const handleChange = (e) => {
setCredentials((prev) => ({ ...prev, [e.target.id]: e.target.value }));
};
const handleSubmit = async (e) => {
e.preventDefault();
dispatch({ type: "LOGIN_START" });
try {
const res = await axios.post("/login", credentials);
dispatch({ type: "LOGIN_SUCCESS", payload: res.data });
} catch (err) {
setMsg({ fail: true, msg: err.response.data.message });
dispatch({ type: "LOGIN_FAILURE", payload: err.response.data });
}
};
return (
<div className="login">
{/* LOGIN FORM */}
<form onSubmit={handleSubmit}>
<Stack>
<Typography>
Login to
</Typography>
{/* Username or Email Address */}
<Typography variant="h9"
gutterBottom
component="div"
style={{ fontWeight: "bold",
textAlign: "left"}}
mt={1}>
Username or Email Address
</Typography>
<div class="relative w-full">
<div class="flex absolute
inset-y-0 left-0 items-center pl-3
pointer-events-none">
<PersonIcon class="w-5 h-5" />
</div>
<input type="text"
className="loginInput"
style={{ border: loginErr.fail ? '1px solid red' : '' }}
// ref={userRef}
name="email"
id="email"
onChange={handleChange}/>
</div>
<button
className="loginButton"
type="submit"
disabled={isFetching}>
{isFetching ? (
<CircularProgress size={15}/>
) : (
<Typography
variant="subtitle2"
color="white">
Login
</Typography>)}
</button>
</Stack>
</form>
{/* LOGIN FORM ENDS */}
</div>
);
}
My question is how to let the INPUT knows if the user is typing a username or an email and then act accordingly, or is there any easy way to get this done?
Backend Auth.js:
router.post("/login", async (req, res, next) => {
try {
if (!req.body.password) {
return next(createError(400, "Invalid password"));
}
const user = await User.findOne({$or: [
{email: req.body.email},
{username: req.body.username}
]});
if (!user) return next(createError(404, "User not found!"));
const isPasswordCorrect = await bcrypt.compare(
req.body.password,
user.password
);
if (!isPasswordCorrect) return next(createError(400, "Wrong password!"));
const { password, ...others } = user._doc;
res.status(200).json(others);
} catch (err) {
next(err);
}
});