Compare commits

..

8 Commits

8 changed files with 443 additions and 275 deletions
+4
View File
@@ -21,6 +21,10 @@ REACT_APP_SESSION_EXPIRE_MINUTES=300000
REACT_APP_SESSION_EXPIRE_CHECKER=60000 REACT_APP_SESSION_EXPIRE_CHECKER=60000
REACT_APP_LOGIN_ERROR_TIMEOUT=7000 REACT_APP_LOGIN_ERROR_TIMEOUT=7000
REACT_APP_SIGNUP_ERROR_TIMEOUT=7000
# Had to change the error time to 3sec cause it took too long
REACT_APP_RESET_START_ERROR_TIMEOUT=3000
#apigate.lotus.g1.wrenchboard.com:76.209.103.227 #apigate.lotus.g1.wrenchboard.com:76.209.103.227
#apigate.orion.g1.wrenchboard.com:76.209.103.227 #apigate.orion.g1.wrenchboard.com:76.209.103.227
+126 -22
View File
@@ -1,49 +1,153 @@
import React from "react"; import React, { useEffect, useState } from "react";
import { Link } from 'react-router-dom'; import { Link, useNavigate } from 'react-router-dom';
import titleShape from "../../../assets/images/shape/title-shape-two.svg"; import WrenchBoard from "../../../assets/images/wrenchboard.png"
import InputCom from "../../Helpers/Inputs/InputCom"; import InputCom from "../../Helpers/Inputs/InputCom";
import AuthLayout from "../AuthLayout"; import AuthLayout from "../AuthLayout";
import usersService from "../../../services/UsersService";
export default function ForgotPassword() { export default function ForgotPassword() {
const [checked, setValue] = useState(false);
const [resetLoading, setResetLoading] = useState(false)
// email
const [email, setMail] = useState("");
const [msgError, setMsgError] = useState('');
const navigate = useNavigate();
const userApi = new usersService();
const handleEmail = (e) => {
setMail(e?.target.value);
};
const humanChecker = () => {
setValue(!checked);
};
const resetHandler = async () => {
if (email == '') {
setMsgError('An email is required')
} else if (!checked) {
setMsgError('Check if you are human')
}
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)
}
setMail("")
}
} catch (error) {
setResetLoading(false)
setMail("")
setMsgError('An error occurred')
throw new Error(error)
} finally {
setTimeout(() => {
setMsgError(null)
}, process.env.REACT_APP_RESET_START_ERROR_TIMEOUT)
}
}
setTimeout(() => {
setMsgError(null)
}, process.env.REACT_APP_RESET_START_ERROR_TIMEOUT)
}
return ( return (
<> <>
<AuthLayout <AuthLayout
slogan="Welcome to WrenchBoard" slogan="Welcome to WrenchBoard"
> >
<div className="content-wrapper xl:bg-white dark:bg-dark-white xl:px-[70px] w-full sm:w-auto 2xl:px-[100px] h-[818px] rounded-xl "> <div className="w-full">
<div className='mb-12'>
<Link to='#'>
<img src={WrenchBoard} alt="wrenchboard" className="h-10 mx-auto" />
</Link>
</div>
<div className="content-wrapper login shadow-md w-full lg:max-w-[500px] mx-auto flex justify-center items-center xl:bg-white dark:bg-dark-white 2xl:w-[828px] rounded-[0.475rem] sm:p-7 p-5">
<div className="flex flex-col justify-center w-full h-full px-5"> <div className="flex flex-col justify-center w-full h-full px-5">
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7"> <div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
<h1 className="sm:text-5xl text-4xl font-bold sm:leading-[74px] text-dark-gray dark:text-white"> <h1 className="text-[#181c32] font-semibold dark:text-white mb-3" style={{
fontSize: 'calc(1rem + .6vw)'
}}>
Forget Password Forget Password
</h1> </h1>
<div className="shape sm:w-[377px] w-[270px] -mt-1 ml-0"> <span className="text-gray-400 font-medium text-xl">Enter your email to reset your password.</span>
<img src={titleShape} alt="shape" />
</div>
</div> </div>
<div className="input-area"> <div className="input-area">
<div className="input-item mb-5"> <div className="input-item mb-10">
<InputCom <InputCom
placeholder="example@quomodosoft.com" placeholder="Your Username/Email"
label="Email Address" label="Email"
name="email" name="email"
type="email" type="email"
value={email}
inputHandler={handleEmail}
iconName="message" iconName="message"
/> />
</div> </div>
{msgError && <div className="relative p-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px]">{msgError}</div>}
{/* hCaptha clone for the time being */}
<div className="mb-10">
<div className="w-[303px] h-[78px] mx-auto overflow-hidden">
<div className="w-[300px] h-[74px] bg-white bottom-[1px] rounded border-gray-100 overflow-hidden cursor-pointer">
{/* Checkbox */}
<div className="h-full relative inline-block">
<div className="relative table top-0 h-full">
<div className="table-cell align-middle">
<div className="relative w-[30px] h-[30px] mx-[15px]">
<input type="checkbox" name="human-checkbox" id="human-checkbox" className="w-[28px] h-[28px] border-[1px] rounded border-gray-400 checked:bg-white" onClick={humanChecker} />
</div>
</div>
</div>
</div>
<div className="h-full relative inline-block w-[170px]">
<label className="relative table top-0 h-full">
<label className="table-cell align-middle">
<label className="text-800 text-sm" htmlFor="human-checkbox">
I am human
</label>
</label>
</label>
</div>
<div className="h-full relative inline-block w-16"></div>
</div>
</div>
</div>
<div className="signin-area mb-3.5"> <div className="signin-area mb-3.5">
<a <div className="flex justify-center items-center gap-2">
href="/verify-you" <button
className="w-full rounded-[50px] mb-5 h-[58px] text-xl text-white font-bold flex justify-center bg-purple items-center" type="button"
onClick={resetHandler}
className={`rounded-[0.475rem] mb-6 text-[1.15rem] font-semibold text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center py-[0.8875rem] px-[1.81rem]`}
> >
Send Code {resetLoading ? (
</a> <div className="signup btn-loader"></div>
) : (
<span>Send Code</span>
<Link to="/" )}
className=" my-40 font-bold flex justify-center text-red-500 items-center" </button>
<button
type="button"
onClick={() => navigate("/login")}
className={`rounded-[0.475rem] mb-6 text-[1.15rem] font-semibold text-[#009ef7] hover:text-white flex justify-center bg-[#f1faff] hover:bg-[#009ef7] transition-all duration-300 items-center py-[0.8875rem] px-[1.8125rem] `}
> >
Back to Home Cancel
</Link> </button>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
+1 -5
View File
@@ -4,8 +4,6 @@ import { toast } from "react-toastify";
import googleLogo from "../../../assets/images/google-logo.svg"; import googleLogo from "../../../assets/images/google-logo.svg";
import appleLogo from "../../../assets/images/apple-black.svg"; import appleLogo from "../../../assets/images/apple-black.svg";
import facebookLogo from "../../../assets/images/facebook-4.svg"; import facebookLogo from "../../../assets/images/facebook-4.svg";
// import titleShape from "../../../assets/images/shape/title-shape.svg";
import titleShape from "../../../assets/images/shape/login_straight_underline.svg";
import WrenchBoard from "../../../assets/images/wrenchboard.png" import WrenchBoard from "../../../assets/images/wrenchboard.png"
import usersService from "../../../services/UsersService"; import usersService from "../../../services/UsersService";
import InputCom from "../../Helpers/Inputs/InputCom"; import InputCom from "../../Helpers/Inputs/InputCom";
@@ -24,8 +22,6 @@ export default function Login() {
setValue(!checked); setValue(!checked);
}; };
console.log(process.env.REACT_APP_LOGIN_ERROR_TIMEOUT)
// email // email
const [email, setMail] = useState(""); const [email, setMail] = useState("");
const handleEmail = (e) => { const handleEmail = (e) => {
@@ -168,7 +164,7 @@ export default function Login() {
Forgot Password Forgot Password
</a> </a>
</div> */} </div> */}
{loginError && <div className="relative p-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px]">Invalid username or password- Please <Link to='/#' className='text-[#009ef7]'>reset your password</Link> or <Link to='/signup' className='text-[#009ef7]'>create a new account</Link></div>} {loginError && <div className="relative p-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-thin leading-[19.5px]">Invalid username or password- Please <Link to='/#' className='text-[#009ef7]'>reset your password</Link> or <Link to='/signup' className='text-[#009ef7]'>create a new account</Link></div>}
{msgError && <div className="relative p-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px]">{msgError}</div>} {msgError && <div className="relative p-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px]">{msgError}</div>}
<div className="signin-area mb-3.5"> <div className="signin-area mb-3.5">
<div className="flex justify-center"> <div className="flex justify-center">
+10 -4
View File
@@ -29,14 +29,15 @@ export default function SignUp() {
// To Show and Hide Password // To Show and Hide Password
const togglePasswordVisibility = () => { const togglePasswordVisibility = () => {
setShowPassword(!showPassword); setShowPassword(!showPassword);
// return console.log('showPassword')
}; };
const rememberMe = () => { const rememberMe = () => {
setValue(!checked); setValue(!checked);
}; };
const navigate = useNavigate(); const navigate = useNavigate();
const userApi = new usersService(); const userApi = new usersService();
// Get Country Api // Get Country Api
const getCountryList = async () => { const getCountryList = async () => {
const res = await userApi.getSignupCountryData() const res = await userApi.getSignupCountryData()
@@ -74,27 +75,32 @@ export default function SignUp() {
} }
const res = await userApi.CreateUser(reqData) const res = await userApi.CreateUser(reqData)
setSignUpLoading(true)
if (res.status === 200) { if (res.status === 200) {
const { data } = res const { data } = res
if (data.status == -1 && data.acc == 'DULPICATE') { if (data.status == -1 && data.acc == 'DULPICATE') {
setMsgError('This account has been already created') setMsgError('This account has been already created')
setSignUpLoading(false)
} }
if (data.status > 0 && data.internal_return == 100 && data.session != '') { if (data.status > 0 && data.internal_return == 100 && data.session != '') {
localStorage.setItem("email", `${data.email}`); localStorage.setItem("email", `${data.email}`);
localStorage.setItem("country", `${data.country}`); localStorage.setItem("country", `${data.country}`);
localStorage.setItem("firstname", `${data.firstname}`); localStorage.setItem("firstname", `${data.firstname}`);
localStorage.setItem("lastname", `${data.lastname}`); localStorage.setItem("lastname", `${data.lastname}`);
setSignUpLoading(true)
setTimeout(() => { setTimeout(() => {
navigate("/", { replace: true }); navigate("/", { replace: true });
setSignUpLoading(false) setSignUpLoading(false)
}, 2000) }, 2000)
console.log('Success')
} else { } else {
setMsgError(data.status) setMsgError(data.status)
setSignUpLoading(false)
} }
} }
} else {
setMsgError('This account does not exist')
setSignUpLoading(false)
} }
} catch (error) { } catch (error) {
throw new Error(error) throw new Error(error)
@@ -102,7 +108,7 @@ export default function SignUp() {
} finally { } finally {
setTimeout(() => { setTimeout(() => {
setMsgError(null) setMsgError(null)
}, 7000) }, process.env.REACT_APP_SIGNUP_ERROR_TIMEOUT)
} }
} }
@@ -25,7 +25,7 @@ export default function InputCom({
{label} {label}
</label> </label>
)} )}
{forgotPassword && <Link href="/forgot-password" className="text-base text-[#4687ba] hover:text-[#009ef7]">Forgot Password?</Link>} {forgotPassword && <Link to="/forgot-password" className="text-base text-[#4687ba] hover:text-[#009ef7]">Forgot Password?</Link>}
</div> </div>
<div className="input-wrapper border border-[#f5f8fa]] dark:border-[#5e6278] w-full rounded-[0.475rem] h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] text-base "> <div className="input-wrapper border border-[#f5f8fa]] dark:border-[#5e6278] w-full rounded-[0.475rem] h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] text-base ">
<input <input
@@ -1,4 +1,4 @@
import React, { useState } from "react"; import React, { useEffect, useState } from "react";
import Icons from "../../Helpers/Icons"; import Icons from "../../Helpers/Icons";
import InputCom from "../../Helpers/Inputs/InputCom"; import InputCom from "../../Helpers/Inputs/InputCom";
import {Link, useNavigate} from 'react-router-dom' import {Link, useNavigate} from 'react-router-dom'
@@ -27,7 +27,13 @@ export default function PersonalInfoTab({
let [togglePromotion, setTogglePromotion] = useState(false) let [togglePromotion, setTogglePromotion] = useState(false)
let [requestStatus, setRequestState] = useState({ let [profile, setProfile] = useState({ // state for requesting from load profile API
data: [],
loading: true,
status: false
})
let [requestStatus, setRequestState] = useState({ // state for requesting from update api
message: '', message: '',
loading: false, loading: false,
status: false status: false
@@ -83,9 +89,40 @@ export default function PersonalInfoTab({
}) })
} }
const loadProfile = ()=>{
apiCall.loadProfile().then((res)=>{
if(res.data.internal_return < 0){
setProfile(prev => ({...prev, loading: false, status: true}))
return
}
setProfile(prev => ({...prev, data: [res.data], loading: false, status: true}))
setInputs({
firstname: res.data.firstname,
lastname: res.data.lastname,
state: res.data.state,
city: res.data.city,
email: res.data.email
})
}).catch(error =>{
setProfile(prev => ({...prev, loading: false, status: false}))
})
}
useEffect(()=>{
loadProfile() // loads user profile unto the page
},[])
return ( return (
<div className="personal-info-tab w-full flex flex-col justify-between"> <div className="personal-info-tab w-full flex flex-col justify-between">
<div className="flex flex-col-reverse sm:flex-row">
{profile.loading ?
<div className="p-3">
<LoadingSpinner size='32' color='sky-blue' />
</div>
:
profile.data.length ?
profile.data.map((item, index) => (
<div key={index} className="flex flex-col-reverse sm:flex-row">
<div className="flex-1 sm:mr-10"> <div className="flex-1 sm:mr-10">
<div className="fields w-full"> <div className="fields w-full">
{/* inputs starts here */} {/* inputs starts here */}
@@ -93,7 +130,7 @@ export default function PersonalInfoTab({
<div className='profile-input my-3'> <div className='profile-input my-3'>
<label className='w-full text-slate-600 text-lg'>Username <span className='text-red-500'>*</span></label> <label className='w-full text-slate-600 text-lg'>Username <span className='text-red-500'>*</span></label>
<input className='w-full p-3 text-lg text-slate-500 bg-slate-200 opacity-90 rounded-md outline-0 placeholder:text-slate-500 placeholder:text-lg' <input className='w-full p-3 text-lg text-slate-500 bg-slate-200 opacity-90 rounded-md outline-0 placeholder:text-slate-500 placeholder:text-lg'
value={'username@gamil.com'} value={item.username}
name='username' name='username'
type="text" type="text"
placeholder='username@gamil.com' placeholder='username@gamil.com'
@@ -108,7 +145,7 @@ export default function PersonalInfoTab({
value={inputs.email} value={inputs.email}
name='email' name='email'
type="text" type="text"
placeholder='Firstname' placeholder='Email'
onChange={handleChange} onChange={handleChange}
/> />
</div> </div>
@@ -138,7 +175,7 @@ export default function PersonalInfoTab({
<div className='profile-input my-3'> <div className='profile-input my-3'>
<label className='w-full text-slate-600 text-lg'>Country <span className='text-red-500'>*</span></label> <label className='w-full text-slate-600 text-lg'>Country <span className='text-red-500'>*</span></label>
<input className='w-full p-3 text-lg text-slate-500 bg-slate-200 opacity-90 rounded-md outline-0 placeholder:text-slate-500 placeholder:text-lg' <input className='w-full p-3 text-lg text-slate-500 bg-slate-200 opacity-90 rounded-md outline-0 placeholder:text-slate-500 placeholder:text-lg'
value='Nigeria' value={item.country}
name='country' name='country'
type="text" type="text"
disabled disabled
@@ -307,6 +344,14 @@ export default function PersonalInfoTab({
</div> </div>
</div> </div>
</div> </div>
))
:
profile.status ?
<div className="py-3 text-slate-500">No User Information Found!</div>
:
<div className="py-3 text-slate-500">Opps! something went wrong. Try Again Later!</div>
}
<div className="content-footer w-full"> <div className="content-footer w-full">
{requestStatus.message != '' && <p className={`text-center text-base ${requestStatus.status ? 'text-green-800' : 'text-red-600'}`}>{requestStatus.message}</p>} {requestStatus.message != '' && <p className={`text-center text-base ${requestStatus.status ? 'text-green-800' : 'text-red-600'}`}>{requestStatus.message}</p>}
<div className="w-full h-[120px] border-t border-light-purple dark:border-[#5356fb29] flex justify-end items-center"> <div className="w-full h-[120px] border-t border-light-purple dark:border-[#5356fb29] flex justify-end items-center">
-1
View File
@@ -8,7 +8,6 @@ const AuthRoute = ({ redirectPath = "/login", children }) => {
const navigate = useNavigate(); const navigate = useNavigate();
const { pathname } = useLocation(); const { pathname } = useLocation();
//Removing Data stored at localStorage after session expires //Removing Data stored at localStorage after session expires
const expireSession = () => { const expireSession = () => {
localStorage.removeItem("email"); localStorage.removeItem("email");
+19 -5
View File
@@ -6,6 +6,11 @@ class usersService {
console.log("WRB Service Entry"); console.log("WRB Service Entry");
} }
CreateUser(reqData){
localStorage.setItem("session_token", ``);
return this.postAuxEnd("/createuser", reqData);
}
getHomeDate(){ getHomeDate(){
var postData = { var postData = {
uuid: localStorage.getItem("uuid"), uuid: localStorage.getItem("uuid"),
@@ -48,11 +53,6 @@ class usersService {
return this.postAuxEnd("/apigate", null); return this.postAuxEnd("/apigate", null);
} }
CreateUser(reqData){
localStorage.setItem("session_token", ``);
return this.postAuxEnd("/createuser", reqData);
}
getLoadProfile(){ getLoadProfile(){
var postData = { var postData = {
uuid: localStorage.getItem("uid"), uuid: localStorage.getItem("uid"),
@@ -228,11 +228,25 @@ class usersService {
return this.postAuxEnd("/updateprofile", postData); return this.postAuxEnd("/updateprofile", postData);
} }
//END POINT CALL FOR GETTING USER PROFILE
loadProfile(post){
var postData = {
uid: localStorage.getItem("uid"),
member_id: localStorage.getItem("member_id"),
sessionid: localStorage.getItem("session_token"),
};
return this.postAuxEnd("/loadprofile", postData);
}
//END POINT CALL FOR SENDING REFERRAL MESSAGE //END POINT CALL FOR SENDING REFERRAL MESSAGE
sendReferralMsg(postData){ sendReferralMsg(postData){
return this.postAuxEnd("/sendreferral", postData); return this.postAuxEnd("/sendreferral", postData);
} }
StartResetPassword(reqData){
return this.postAuxEnd("/startresetpasword", reqData)
}
getCouponRedeem(){ getCouponRedeem(){
var postData = { var postData = {
uuid: localStorage.getItem("uid"), uuid: localStorage.getItem("uid"),