Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Signup Process with Email Verification and Page Redirection #152

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 21 additions & 7 deletions src/components/AuthPage/Login/ViewAlerts.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import CloseIcon from "@mui/icons-material/Close";
import Alert from "@mui/lab/Alert";
import React, { useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { useHistory } from "react-router-dom";
import { resendVerifyEmail } from "../../../store/actions";

const AlertComp = ({ description, type }) => {
Expand Down Expand Up @@ -33,7 +34,8 @@ const AlertComp = ({ description, type }) => {
);
};

const ViewAlerts = ({ error }) => {
const ViewAlerts = ({ error, successMessage }) => {
const history = useHistory();
const [resendLoading, setResendLoading] = useState(false);
const [resendError, setResendError] = useState("");
const [success, setSuccess] = useState(false);
Expand All @@ -53,6 +55,23 @@ const ViewAlerts = ({ error }) => {
}
}, [errorProp, loadingProp]);

useEffect(() => {
if (successMessage) {
// If success message is received, set success state to true
setSuccess(true);

// Set a timer to clear the success message after 5 seconds
const timer = setTimeout(() => {
setSuccess(false);
// Reset location state
history.replace({ ...history.location, state: { successMessage: "" } });
}, 5000);

// Return a cleanup function to clear the timer when the component unmounts or successMessage changes
return () => clearTimeout(timer);
}
}, [successMessage, history]);

return (
<>
{error && error !== "email-unverified" && !resendError && (
Expand Down Expand Up @@ -83,12 +102,7 @@ const ViewAlerts = ({ error }) => {
<AlertComp description={"Resending the verification email..."} />
)}

{success && (
<AlertComp
description={"Please check your email and verify your email."}
type="success"
/>
)}
{success && <AlertComp description={successMessage} type="success" />}
</>
);
};
Expand Down
15 changes: 13 additions & 2 deletions src/components/AuthPage/Login/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import VisibilityOff from "@mui/icons-material/VisibilityOff";
import React, { useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { useFirebase } from "react-redux-firebase";
import { Link } from "react-router-dom";
import { Link, useLocation } from "react-router-dom";
import validator from "validator";
import Divider from "../../../globalComponents/Divider";
import { clearAuthError, signIn } from "../../../store/actions";
Expand Down Expand Up @@ -48,6 +48,13 @@ const Login = ({
const errorProp = useSelector(({ auth }) => auth.profile.error);
const loadingProp = useSelector(({ auth }) => auth.profile.loading);
const dispatch = useDispatch();
const location = useLocation();
const [signupMessage, setSignupMessage] = useState("");

useEffect(() => {
// Update signupMessage when the location state changes
setSignupMessage(location.state?.successMessage || "");
}, [location.state]);

useEffect(() => setError(errorProp), [errorProp]);
useEffect(() => setLoading(loadingProp), [loadingProp]);
Expand Down Expand Up @@ -128,7 +135,11 @@ const Login = ({
>
{loginText}
</Typography>
<ViewAlerts error={error} email={email} />
<ViewAlerts
error={error}
email={email}
successMessage={signupMessage}
/>
<div>
<TextField
error={emailValidateError}
Expand Down
27 changes: 20 additions & 7 deletions src/components/AuthPage/SignUp/signupForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,18 @@ import { Alert } from "@mui/material";
import React, { useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { useFirebase } from "react-redux-firebase";
import { useHistory } from "react-router-dom"; // Import useHistory
import validator from "validator";
import { clearAuthError, signUp } from "../../../store/actions";
import Card from "@mui/material/Card";

const SignupForm = () => {
const [loading, setLoading] = useState(false);
const [error, setError] = useState("");
const [success, setSuccess] = useState(false);
// const [success, setSuccess] = useState(false);
const firebase = useFirebase();
const dispatch = useDispatch();
const history = useHistory(); // Initialize useHistory
const errorProp = useSelector(({ auth }) => auth.profile.error);
const loadingProp = useSelector(({ auth }) => auth.profile.loading);

Expand Down Expand Up @@ -60,11 +62,16 @@ const SignupForm = () => {

useEffect(() => {
if (errorProp === false && loadingProp === false) {
setSuccess(true);
// setSuccess(true);
// Redirect to login page with state
history.push("/login", {
successMessage:
"Verification email has been sent. Please verify your email."
});
} else {
setSuccess(false);
// setSuccess(false);
}
}, [errorProp, loadingProp]);
}, [errorProp, loadingProp, history]);

const handleClickShowPassword = () => setShowPassword(!showPassword);
const handleClickShowConfirmPassword = () =>
Expand Down Expand Up @@ -137,7 +144,13 @@ const SignupForm = () => {
validateConfirmPassword() &&
agreed
) {
await signUp({ email, password })(firebase, dispatch);
try {
// Dispatch signup action with email and password
await signUp({ email, password })(firebase, dispatch);
} catch (error) {
setError(error);
setErrorOpen(true);
}
} else {
setAgreedText(true);
}
Expand Down Expand Up @@ -183,7 +196,7 @@ const SignupForm = () => {
</Collapse>
)}

{success && (
{/* {success && (
<Collapse in={success}>
<Alert
severity="success"
Expand All @@ -205,7 +218,7 @@ const SignupForm = () => {
verification link.
</Alert>
</Collapse>
)}
)} */}

<Card data-testId="signUpForm" style={{ boxShadow: "none" }}>
<TextField
Expand Down
46 changes: 36 additions & 10 deletions src/store/actions/authActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,36 @@ export const signUp = userData => async (firebase, dispatch) => {
try {
dispatch({ type: actions.SIGN_UP_START });
const { email, password } = userData;
await firebase.createUser({ email, password }, { email });

// Create user with email and password
const createdUser = await firebase.createUser({ email, password }, { email });
// console.log("createdUser is ", createdUser);

// Get the current user
const currentUser = firebase.auth().currentUser;
// console.log("currentUser is ", currentUser);

if (!currentUser) {
throw new Error('User not found after signup');
}

// Send email verification
try {
await currentUser.sendEmailVerification();
console.log("Email verification sent successfully.");
} catch (verificationError) {
console.error("Error sending email verification:", verificationError);
dispatch({ type: actions.SIGN_UP_FAIL, payload: verificationError });
throw verificationError;
}

// Logout after successful signup and email verification
await firebase.logout();

// Dispatch action indicating signup success
dispatch({ type: actions.SIGN_UP_SUCCESS });
} catch (e) {
// Dispatch action indicating signup failure with error payload
dispatch({ type: actions.SIGN_UP_FAIL, payload: e });
}
};
Expand Down Expand Up @@ -135,15 +161,15 @@ export const verifyPasswordResetCode =

export const confirmPasswordReset =
({ actionCode, password }) =>
async (firebase, dispatch) => {
try {
dispatch({ type: actions.PASSWORD_RECOVERY_START });
await firebase.confirmPasswordReset(actionCode, password);
dispatch({ type: actions.PASSWORD_RECOVERY_SUCCESS });
} catch (e) {
dispatch({ type: actions.PASSWORD_RECOVERY_FAIL, payload: e.message });
}
};
async (firebase, dispatch) => {
try {
dispatch({ type: actions.PASSWORD_RECOVERY_START });
await firebase.confirmPasswordReset(actionCode, password);
dispatch({ type: actions.PASSWORD_RECOVERY_SUCCESS });
} catch (e) {
dispatch({ type: actions.PASSWORD_RECOVERY_FAIL, payload: e.message });
}
};

export const verifyEmail = actionCode => async (firebase, dispatch) => {
try {
Expand Down
Loading