I created logged in form wherein it will pop-out a toastify
when logged in correctly. So my problem right now is I have a logic wherein the user can only access the website when his account is active
, but my toastify is not popping correctly. I'm using reduxjs/toolkit my state.
So what I'm trying to achieve here:
1.) Show an error message
if the account is not existing or wrong password
2.) Show Account still pending
if the user correctly input his username and password but still not active
3.) Navigate to login page when account is active
api/login.js
const login = async (req,res, next) =>{
try {
const user = await User.findOne({studentNumber: req.body.studentNumber})
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 or Username!"))
const accessToken = jwt.sign({id: user._id, isAdmin: user.isAdmin}, 'secretkey')
const {password, ...others} = user._doc
if(others.status === 'active'){
res.status(200).json({...others, accessToken})
}
else{
next(createError(203, "Account is still pending.."))
}
} catch (error) {
next(error);
}
}
authSlice.js
const authSlice = createSlice({
name: 'auth',
initialState: {
currentUser: null,
isFetching : false,
isError: false,
isSuccess: false,
message: ''
},
reducers: {
resetState: (state) =>{
state.currentUser = null;
state.isFetching = false
state.isError = false
state.isSuccess = false
},
loginStart: (state)=>{
state.isFetching = true;
state.isError = false;
},
loginSuccess: (state, action) =>{
state.isFetching = true;
state.isSuccess = true;
state.currentUser = action.payload
state.message = action.payload
},
loginFailure: (state, action) =>{
state.isSuccess = false;
state.isFetching = false;
state.isError = true;
state.message = action.payload
},
}
})
In authSlice.js, I have a problem that it automatically run the loginFailure, even though the user correctly input it's credential.
apiCall.js
const loginUser = async (user, dispatch) => {
dispatch(loginStart());
try {
const res = await publicRequest.post("/auth/login", user);
dispatch(loginSuccess(res.data));
} catch (err) {
dispatch(loginFailure());
}
};
Login.jsx
const {isError, currentUser, message} = useSelector((state) => state.auth)
const dispatch = useDispatch()
const navigate = useNavigate()
const {register, handleSubmit, formState: {errors}} = useForm({
studentNumber: '',
password: ''
})
const onSubmit = ({studentNumber,password}) =>{
let user ={studentNumber, password}
loginUser(user,dispatch)
}
useEffect(() =>{
if(isError){
toast.error(message)
}
dispatch(resetState())
},[dispatch, isError])
useEffect(() =>{
if(currentUser){
toast.success(message)
}
},[dispatch, currentUser])
Login.jsx
const Login () =>{
const {isError, currentUser, message} = useSelector((state) => state.auth)
const dispatch = useDispatch()
const navigate = useNavigate()
const {register, handleSubmit, formState: {errors}} = useForm({
studentNumber: '',
password: ''
})
const onSubmit = ({studentNumber,password}) =>{
let user ={studentNumber, password}
loginUser(user,dispatch)
}
useEffect(() =>{
if(isError){
toast.error(message)
}
dispatch(resetState())
},[dispatch, isError])
useEffect(() =>{
if(currentUser){
toast.success(message)
}
},[dispatch, currentUser])
return (
<form onSubmit={handleSubmit(onSubmit)}>
<TextField name="studentNumber" {...register('studentNumber)} type="text" />
<TextField name="password" {...register('password)} type="password" />
</form>
)
}
EDIT Please ignore the form field if I type it wrong, I just copy paste it and missed something