From 63f2ee3e6cc7350c36d0f4f02a7d26c3663cd59d Mon Sep 17 00:00:00 2001 From: Ebube Date: Thu, 27 Apr 2023 14:01:12 +0100 Subject: [PATCH 1/3] removed a field --- src/components/AuthPages/Login/index.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/AuthPages/Login/index.jsx b/src/components/AuthPages/Login/index.jsx index f06a758..9e2cafc 100644 --- a/src/components/AuthPages/Login/index.jsx +++ b/src/components/AuthPages/Login/index.jsx @@ -118,7 +118,6 @@ export default function Login() { iconName="message" /> -
Date: Thu, 27 Apr 2023 22:54:27 +0100 Subject: [PATCH 2/3] added complete signup handler --- src/Routers.jsx | 2 +- .../AuthPages/ForgotPassword/index.jsx | 37 +++---- src/components/AuthPages/Login/index.jsx | 19 ++-- src/components/AuthPages/SignUp/index.jsx | 60 +++++------ src/components/AuthPages/VerifyLink/index.jsx | 101 +++++++++++++++--- src/components/AuthPages/VerifyYou/index.jsx | 56 ++++++---- .../Helpers/Inputs/InputCom/index.jsx | 6 +- src/services/UsersService.js | 5 + 8 files changed, 183 insertions(+), 103 deletions(-) diff --git a/src/Routers.jsx b/src/Routers.jsx index 061a28d..ca6ebcc 100644 --- a/src/Routers.jsx +++ b/src/Routers.jsx @@ -50,7 +50,7 @@ export default function Routers() { element={} /> } /> - } /> + } /> {/* private route */} }> diff --git a/src/components/AuthPages/ForgotPassword/index.jsx b/src/components/AuthPages/ForgotPassword/index.jsx index 589d446..65bdbe7 100644 --- a/src/components/AuthPages/ForgotPassword/index.jsx +++ b/src/components/AuthPages/ForgotPassword/index.jsx @@ -11,6 +11,7 @@ export default function ForgotPassword() { // email const [email, setMail] = useState(""); const [msgError, setMsgError] = useState(''); + const [msgSuccess, setMsgSuccess] = useState(false) const navigate = useNavigate(); const userApi = new usersService(); @@ -20,8 +21,8 @@ export default function ForgotPassword() { }; const humanChecker = () => { - setValue(!checked); - }; + setValue(!checked) + } const resetHandler = async () => { if (email == '') { @@ -30,24 +31,16 @@ export default function ForgotPassword() { setMsgError('Check if you are human') } - if (email != '' && checked) { + if (email !== '' && checked) { const reqData = { email } setResetLoading(true) try { const res = await userApi.StartResetPassword(reqData) if (res.status === 200) { - const { data } = res - if (data.status == -1) { - setMsgError('This is an incorrect or duplicate email') - setResetLoading(false) - } else if (data.status > 0) { - setResetLoading(false) - navigate("/verify-you", { replace: true }) - } else{ - setMsgError("reset was not successful") - setResetLoading(false) - } + setMsgSuccess(true) setMail("") + setValue(false) + setResetLoading(false) } } catch (error) { setResetLoading(false) @@ -79,12 +72,10 @@ export default function ForgotPassword() {
-

+

Forget Password

- Enter your email to reset your password. + Enter your email to reset your password.
@@ -98,7 +89,6 @@ export default function ForgotPassword() { iconName="message" />
- {msgError &&
{msgError}
} {/* hCaptha clone for the time being */}
@@ -108,7 +98,7 @@ export default function ForgotPassword() {
- +
@@ -126,12 +116,15 @@ export default function ForgotPassword() {
+ {msgError &&
{msgError}
} + {msgSuccess &&
If we find your email, you will receive a link to reset your password. Please use or contact form if you did not get our message after few minutes.
} +
diff --git a/src/components/AuthPages/Login/index.jsx b/src/components/AuthPages/Login/index.jsx index 9e2cafc..7d18634 100644 --- a/src/components/AuthPages/Login/index.jsx +++ b/src/components/AuthPages/Login/index.jsx @@ -99,12 +99,10 @@ export default function Login() {
-

+

Sign In to WrenchBoard

- New Here? Create an Account + New Here? Create an Account
@@ -164,15 +162,14 @@ export default function Login() { Forgot Password
*/} - {loginError &&
Invalid username or password- Please reset your password or create a new account
} - {msgError &&
{msgError}
} + {loginError &&
Invalid username or password- Please reset your password or create a new account
} + {msgError &&
{msgError}
}
*/} -
This site is protected by hCaptcha and the our Privacy Policy and Terms of Service apply.
+
This site is protected by hCaptcha and the our Privacy Policy and Terms of Service apply.
@@ -215,8 +212,8 @@ const BrandBtn = ({ className="w-full border border-light-purple dark:border-[#5356fb29] rounded-[0.475rem] h-[48px] flex justify-center bg-[#FAFAFA] hover:bg-[#eff2f5] hover:text-[#7e8299] transition duration-300 dark:bg-[#11131F] items-center font-medium cursor-pointer" > logo-icon(s) - - Sign In with {brand} + + Continue with {brand}
diff --git a/src/components/AuthPages/SignUp/index.jsx b/src/components/AuthPages/SignUp/index.jsx index 549a501..2b2069e 100644 --- a/src/components/AuthPages/SignUp/index.jsx +++ b/src/components/AuthPages/SignUp/index.jsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from "react"; +import React, { useCallback, useEffect, useState } from "react"; import { useNavigate, Link } from "react-router-dom"; import facebookLogo from "../../../assets/images/facebook-4.svg"; import WrenchBoard from "../../../assets/images/wrenchboard.png"; @@ -39,20 +39,22 @@ export default function SignUp() { const userApi = new usersService(); // Get Country Api - const getCountryList = async () => { - const res = await userApi.getSignupCountryData() - - try { - if (res.status === 200) { - const { signup_country } = await res.data - setCountries(signup_country) - } else if (res.data.result !== 100) { - setCountries('Nothing see here!') + const getCountryList = useCallback( + async () => { + const res = await userApi.getSignupCountryData() + + try { + if (res.status === 200) { + const { signup_country } = await res.data + setCountries(signup_country) + } else if (res.data.result !== 100) { + setCountries('Nothing see here!') + } + } catch (error) { + throw new Error(error) } - } catch (error) { - throw new Error(error) - } - } + }, [] + ) const handleSignUp = async () => { let { country, first_name, last_name, email, password } = formData @@ -85,13 +87,14 @@ export default function SignUp() { } if (data && data.status === '1') { setTimeout(() => { - navigate("/verify-you", { replace: true }); setSignUpLoading(false) + navigate("/outmessage", { replace: true }); }, 2000) - } else { - setSignUpLoading(false) - setMsgError('This account does not exist') - } + } + // else { + // setSignUpLoading(false) + // setMsgError('This account does not exist') + // } } else { setSignUpLoading(false) setMsgError('An error occurred') @@ -132,16 +135,14 @@ export default function SignUp() {
-

+

Create Account

- Already have an account? Sign in here + Already have an account? Sign in here
I agree with all - terms and condition - +
@@ -245,8 +246,7 @@ export default function SignUp() { diff --git a/src/components/AuthPages/VerifyYou/index.jsx b/src/components/AuthPages/VerifyYou/index.jsx index 5cf2fee..c8d8831 100644 --- a/src/components/AuthPages/VerifyYou/index.jsx +++ b/src/components/AuthPages/VerifyYou/index.jsx @@ -1,31 +1,49 @@ +import { useNavigate, Link } from "react-router-dom"; import AuthLayout from "../AuthLayout"; +import WrenchBoard from "../../../assets/images/wrenchboard.png" export default function VerifyYou() { + const navigate = useNavigate() return ( <> -
-
-
-

- Verification Sent -

+
+
+ + wrenchboard + +
+
+
+
+

+ Let's verify your email now +

+ Check your email. +
+
+
+

+ Verify Email. Help us secure your WrenchBoard account by verifying your email registration address. Verification will let you access all of WrenchBoard's features. +

+
+
+

+ If you do not receive the confirmation message within a few minutes of signing up, please check your Junk E-mail folder just in case the confirmation email got delivered there instead of your inbox. If so, select the confirmation message and click Not Junk, which will allow future messages to get through. +

+
+
+
+
-
-
-

- To complete the verification process, you should check your email inbox and look for the verification email. It may take a few minutes for the email to arrive, so be patient. Once you receive the email, open it and click on the verification link provided. -

-
-
-

- If you haven't received the verification email after a reasonable amount of time, make sure to check your spam or junk mail folder. It's also possible that the email was sent to the wrong email address, so double-check that you entered your email address correctly. -

-
diff --git a/src/components/Helpers/Inputs/InputCom/index.jsx b/src/components/Helpers/Inputs/InputCom/index.jsx index 707d0cc..5382c53 100644 --- a/src/components/Helpers/Inputs/InputCom/index.jsx +++ b/src/components/Helpers/Inputs/InputCom/index.jsx @@ -68,20 +68,20 @@ export default function InputCom({
{label && ( )} - {forgotPassword && Forgot Password?} + {forgotPassword && Forgot Password?}
Date: Fri, 28 Apr 2023 02:08:04 +0100 Subject: [PATCH 3/3] Added intervals for the requests for the verification --- src/components/AuthPages/SignUp/index.jsx | 165 ++++++++------ src/components/AuthPages/VerifyLink/index.jsx | 207 +++++++++++------- src/hooks/debounce.js | 21 ++ 3 files changed, 238 insertions(+), 155 deletions(-) create mode 100644 src/hooks/debounce.js diff --git a/src/components/AuthPages/SignUp/index.jsx b/src/components/AuthPages/SignUp/index.jsx index 2b2069e..8224c6c 100644 --- a/src/components/AuthPages/SignUp/index.jsx +++ b/src/components/AuthPages/SignUp/index.jsx @@ -6,10 +6,10 @@ import usersService from "../../../services/UsersService"; import InputCom from "../../Helpers/Inputs/InputCom"; export default function SignUp() { - const [signUpLoading, setSignUpLoading] = useState(false) + const [signUpLoading, setSignUpLoading] = useState(false); const [checked, setValue] = useState(false); // for the catch error - const [msgError, setMsgError] = useState(''); + const [msgError, setMsgError] = useState(""); const [showPassword, setShowPassword] = useState(false); const [countries, setCountries] = useState([]); @@ -18,7 +18,7 @@ export default function SignUp() { first_name: "", last_name: "", email: "", - password: "" + password: "", }); const handleInputChange = (event) => { @@ -39,33 +39,36 @@ export default function SignUp() { const userApi = new usersService(); // Get Country Api - const getCountryList = useCallback( - async () => { - const res = await userApi.getSignupCountryData() - - try { - if (res.status === 200) { - const { signup_country } = await res.data - setCountries(signup_country) - } else if (res.data.result !== 100) { - setCountries('Nothing see here!') - } - } catch (error) { - throw new Error(error) + const getCountryList = useCallback(async () => { + const res = await userApi.getSignupCountryData(); + + try { + if (res.status === 200) { + const { signup_country } = await res.data; + setCountries(signup_country); + } else if (res.data.result !== 100) { + setCountries("Nothing see here!"); } - }, [] - ) + } catch (error) { + throw new Error(error); + } + }, []); const handleSignUp = async () => { - let { country, first_name, last_name, email, password } = formData + let { country, first_name, last_name, email, password } = formData; - if (email === '' && password === '' && first_name === '') { - setMsgError('Please fill in fields') + if (email === "" && password === "" && first_name === "") { + setMsgError("Please fill in fields"); } try { - if (email !== '' && password !== '' && first_name !== '' && last_name !== '') { - setSignUpLoading(true) + if ( + email !== "" && + password !== "" && + first_name !== "" && + last_name !== "" + ) { + setSignUpLoading(true); const reqData = { country: country, firstname: first_name, @@ -74,51 +77,40 @@ export default function SignUp() { username: email, password: password, terms: 1, - news: 1 - } + news: 1, + }; - const res = await userApi.CreateUser(reqData) + const res = await userApi.CreateUser(reqData); if (res.status === 200) { - const { data } = res - if (data.status === -1 && data.acc === 'DULPICATE') { - setMsgError('This account has been already created') - setSignUpLoading(false) + const { data } = res; + if (data.status === -1 && data.acc === "DULPICATE") { + setMsgError("This account has been already created"); + setSignUpLoading(false); } - if (data && data.status === '1') { + if (data && data.status === "1") { setTimeout(() => { - setSignUpLoading(false) navigate("/outmessage", { replace: true }); - }, 2000) - } - // else { - // setSignUpLoading(false) - // setMsgError('This account does not exist') - // } + setSignUpLoading(false); + }, 2000); + } } else { - setSignUpLoading(false) - setMsgError('An error occurred') + setSignUpLoading(false); + setMsgError("An error occurred"); } } } catch (error) { - throw new Error(error) + throw new Error(error); } finally { setTimeout(() => { - setMsgError(null) - }, process.env.REACT_APP_SIGNUP_ERROR_TIMEOUT) - setFormData({ - first_name: '', - last_name: '', - email: '', - country: '', - password: '' - }) + setMsgError(null); + }, process.env.REACT_APP_SIGNUP_ERROR_TIMEOUT); } - } + }; useEffect(() => { - getCountryList() - }) + getCountryList(); + }); return ( <> @@ -127,9 +119,13 @@ export default function SignUp() {
-
- - wrenchboard +
+ + wrenchboard
@@ -138,23 +134,37 @@ export default function SignUp() {

Create Account

- Already have an account? Sign in here + + Already have an account?{" "} + + Sign in here + +
- OR + + OR +
- {msgError &&
{msgError}
} + {msgError && ( +
+ {msgError} +
+ )}
- ) -} + ); +}; diff --git a/src/components/AuthPages/VerifyLink/index.jsx b/src/components/AuthPages/VerifyLink/index.jsx index 02b7ebd..8d5d8cb 100644 --- a/src/components/AuthPages/VerifyLink/index.jsx +++ b/src/components/AuthPages/VerifyLink/index.jsx @@ -3,20 +3,21 @@ import { useLocation, Link, useNavigate } from "react-router-dom"; import AuthLayout from "../AuthLayout"; import InputCom from "../../Helpers/Inputs/InputCom"; import usersService from "../../../services/UsersService"; -import WrenchBoard from "../../../assets/images/wrenchboard.png" +import WrenchBoard from "../../../assets/images/wrenchboard.png"; +import debounce from "../../../hooks/debounce"; export default function VerifyLink() { - const [email, setEmail] = useState('') - const [password, setPassword] = useState('') - const [msgError, setMsgError] = useState(''); - const [pageLoader, setPageLoader] = useState(true) - const [linkSuccess, setLinkSuccess] = useState(false) - const [linkError, setLinkError] = useState(false) - const navigate = useNavigate() + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + const [msgError, setMsgError] = useState(""); + const [linkLoader, setLinkLoader] = useState(false); + const [pageLoader, setPageLoader] = useState(true); + const [linkSuccess, setLinkSuccess] = useState(true); + const navigate = useNavigate(); const location = useLocation(); - const queryParams = new URLSearchParams(location?.search) - const token = queryParams.get('vlnk') - const userApi = new usersService() + const queryParams = new URLSearchParams(location?.search); + const token = queryParams.get("vlnk"); + const userApi = new usersService(); // email const handleEmail = (e) => { @@ -27,107 +28,127 @@ export default function VerifyLink() { setPassword(e.target.value); }; - // for verifying the incoming verification link and render the correct component - const verifyEmail = useCallback( - async (code) => { - try { - const verifyRes = await userApi.verifyEmail(code) - if (verifyRes.status === 200) { - let { data } = verifyRes + // for verifying the incoming verification link and render the correct component + const verifyEmail = useCallback(async (code) => { + try { + const verifyRes = await userApi.verifyEmail(code); + if (verifyRes.status === 200) { + let { data } = verifyRes; - if (data && data.internal_return >= 0 && data.status_text === 'Link Verfied') { - setPageLoader(false) - setLinkSuccess(true) - } else { - setPageLoader(false) - setLinkError(true) - } + if ( + data && + data.internal_return >= 0 && + data.status_text === "Link Verfied" + ) { + setPageLoader(false); + } else { + setPageLoader(false); + setLinkSuccess(false); } - } catch (error) { - setPageLoader(false) - setLinkError(true) - throw new Error(error) } - }, [] - ) + } catch (error) { + setPageLoader(false); + setLinkSuccess(false); + throw new Error(error); + } + }, []); - // if verification is okay. set a complete signup form + // delay verify requests by 10000ms + const debouncedEmail = debounce(verifyEmail, 1000); + + // if verification is okay. set a complete signup form const completeSignup = async () => { - if (email === '' && password === '') { - setMsgError('Please fill in fields') + if (email === "" && password === "") { + setMsgError("Please fill in fields"); } try { if (email !== "" && password !== "") { + setLinkLoader(true); var postData = { username: email, password: password, - sessionid: 'STARTER-NOTREAL', + login_mode: 100, + sessionid: "STARTER-NOTREAL", verify_link: token, - action: 11012 - } - const res = await userApi.CompleteSignUp(postData) - console.log(res) + action: 11012, + }; + const res = await userApi.CompleteSignUp(postData); if (res.status === 200) { - const { data } = res - // Invalid Link & Password Combination - if (data.internal_return == -1 && data.acc == 'Invalid Link & Password Combination') { - setMsgError('Invalid Link & Password Combination') - // setSignUpLoading(false) + const { data } = res; + if ( + data?.status > 0 && + data?.internal_return == 100 && + data?.session != "" + ) { + localStorage.setItem("email", `${data?.email}`); + localStorage.setItem("member_id", `${data?.member_id}`); + localStorage.setItem("session_token", `${data?.session}`); + localStorage.setItem("added", `${data?.added}`); + localStorage.setItem("city", `${data?.city}`); + localStorage.setItem("country", `${data?.country}`); + localStorage.setItem("firstname", `${data?.firstname}`); + localStorage.setItem("last_login", `${data?.last_login}`); + localStorage.setItem("lastname", `${data?.lastname}`); + localStorage.setItem("state", `${data?.state}`); + localStorage.setItem("zip_code", `${data?.zip_code}`); + localStorage.setItem("session", `${data?.session}`); + + navigate("/", { replace: true }); + setLinkLoader(false); + } else { + setLinkLoader(false); + setMsgError("Invalid Link or Password Combination"); } - if (data && data.status === '1') { - setTimeout(() => { - // setSignUpLoading(false) - navigate("/", { replace: true }); - }, 2000) - } } else { - // setSignUpLoading(false) - setMsgError('An error occurred') + setLinkLoader(false); + setLinkSuccess(false) + setMsgError("An error occurred"); } } } catch (error) { - throw new Error(error) + setLinkLoader(false); + setLinkSuccess(false) + throw new Error(error); } finally { setTimeout(() => { - setMsgError(null) - }, process.env.REACT_APP_SIGNUP_ERROR_TIMEOUT) + setMsgError(null); + }, process.env.REACT_APP_SIGNUP_ERROR_TIMEOUT); } - } + }; useLayoutEffect(() => { - verifyEmail(token) - }) - - // console.log(token) + debouncedEmail(token); + }); return ( <> - + {pageLoader ? ( wrenchboard ) : (
-
- - wrenchboard +
+ + wrenchboard

- {linkError && 'Invalid verification link'} - {linkSuccess && 'Sign In to WrenchBoard'} + {linkSuccess + ? "Sign In to WrenchBoard" + : "Invalid verification link"}

{/* If the verification was a success */} - { - linkSuccess - && + {linkSuccess ? ( - } - - {/* If the verification was unsuccessful */} - {linkError && navigate('/login')} />} + ) : ( + navigate("/login")} /> + )}
)} - ) + ); } - -const SuccessfulComponent = ({ onSubmit, password, handlePassword, email, handleEmail, msgErr }) => ( +const SuccessfulComponent = ({ + onSubmit, + password, + handlePassword, + email, + handleEmail, + msgErr, + loader, +}) => (
{/* INPUT */}
@@ -175,36 +203,45 @@ const SuccessfulComponent = ({ onSubmit, password, handlePassword, email, handle iconName="password" />
- {msgErr &&
{msgErr}
} + {msgErr && ( +
+ {msgErr} +
+ )}
-) +); const ErrorComponent = ({ onClick }) => (

- This error occurs because you have already verified this link or the link has expired. Try login or reset password. If none worked, try to create the account from the start. + This error occurs because you have already verified this link or the + link has expired. Try login or reset password. If none worked, try to + create the account from the start.

-
-) \ No newline at end of file +); diff --git a/src/hooks/debounce.js b/src/hooks/debounce.js new file mode 100644 index 0000000..9af499d --- /dev/null +++ b/src/hooks/debounce.js @@ -0,0 +1,21 @@ +/** + +Returns a debounced version of a given function, which means that it delays the execution of the function until a certain amount of time has passed without the function being called again. This can be useful for performance optimization, especially when dealing with expensive or resource-intensive functions that are called frequently. +@param {Function} func - The function to debounce. +@param {number} delay - The number of milliseconds to wait before executing the debounced function. +@returns {Function} - The debounced version of the original function. +*/ + +export default function debounce(func, delay) { + let timeoutId; + + return function (...args) { + const context = this; + + clearTimeout(timeoutId); + + timeoutId = setTimeout(() => { + func.apply(context, args); + }, delay); + }; +}