Compare commits

..

13 Commits

9 changed files with 485 additions and 329 deletions
+4
View File
@@ -21,6 +21,10 @@ REACT_APP_SESSION_EXPIRE_MINUTES=300000
REACT_APP_SESSION_EXPIRE_CHECKER=60000
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.orion.g1.wrenchboard.com:76.209.103.227
+3 -1
View File
@@ -13,6 +13,7 @@
"chartjs": "^0.3.24",
"cors": "^2.8.5",
"faker": "^6.6.6",
"formik": "^2.2.9",
"react": "^18.0.0",
"react-chartjs-2": "^4.1.0",
"react-countup": "^6.2.0",
@@ -25,7 +26,8 @@
"react-toastify": "^9.0.1",
"redux": "^4.2.0",
"slick-carousel": "^1.8.1",
"web-vitals": "^1.0.1"
"web-vitals": "^1.0.1",
"yup": "^1.1.1"
},
"scripts": {
"start": "react-scripts start",
+140 -36
View File
@@ -1,49 +1,153 @@
import React from "react";
import { Link } from 'react-router-dom';
import titleShape from "../../../assets/images/shape/title-shape-two.svg";
import React, { useEffect, useState } from "react";
import { Link, useNavigate } from 'react-router-dom';
import WrenchBoard from "../../../assets/images/wrenchboard.png"
import InputCom from "../../Helpers/Inputs/InputCom";
import AuthLayout from "../AuthLayout";
import usersService from "../../../services/UsersService";
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 (
<>
<AuthLayout
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="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">
<h1 className="sm:text-5xl text-4xl font-bold sm:leading-[74px] text-dark-gray dark:text-white">
Forget Password
</h1>
<div className="shape sm:w-[377px] w-[270px] -mt-1 ml-0">
<img src={titleShape} alt="shape" />
<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="title-area flex flex-col justify-center items-center relative text-center mb-7">
<h1 className="text-[#181c32] font-semibold dark:text-white mb-3" style={{
fontSize: 'calc(1rem + .6vw)'
}}>
Forget Password
</h1>
<span className="text-gray-400 font-medium text-xl">Enter your email to reset your password.</span>
</div>
</div>
<div className="input-area">
<div className="input-item mb-5">
<InputCom
placeholder="example@quomodosoft.com"
label="Email Address"
name="email"
type="email"
iconName="message"
/>
</div>
<div className="signin-area mb-3.5">
<a
href="/verify-you"
className="w-full rounded-[50px] mb-5 h-[58px] text-xl text-white font-bold flex justify-center bg-purple items-center"
>
Send Code
</a>
<Link to="/"
className=" my-40 font-bold flex justify-center text-red-500 items-center"
>
Back to Home
</Link>
<div className="input-area">
<div className="input-item mb-10">
<InputCom
placeholder="Your Username/Email"
label="Email"
name="email"
type="email"
value={email}
inputHandler={handleEmail}
iconName="message"
/>
</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="flex justify-center items-center gap-2">
<button
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]`}
>
{resetLoading ? (
<div className="signup btn-loader"></div>
) : (
<span>Send Code</span>
)}
</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] `}
>
Cancel
</button>
</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 appleLogo from "../../../assets/images/apple-black.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 usersService from "../../../services/UsersService";
import InputCom from "../../Helpers/Inputs/InputCom";
@@ -24,8 +22,6 @@ export default function Login() {
setValue(!checked);
};
console.log(process.env.REACT_APP_LOGIN_ERROR_TIMEOUT)
// email
const [email, setMail] = useState("");
const handleEmail = (e) => {
@@ -168,7 +164,7 @@ export default function Login() {
Forgot Password
</a>
</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>}
<div className="signin-area mb-3.5">
<div className="flex justify-center">
+10 -4
View File
@@ -29,14 +29,15 @@ export default function SignUp() {
// To Show and Hide Password
const togglePasswordVisibility = () => {
setShowPassword(!showPassword);
// return console.log('showPassword')
};
const rememberMe = () => {
setValue(!checked);
};
const navigate = useNavigate();
const userApi = new usersService();
// Get Country Api
const getCountryList = async () => {
const res = await userApi.getSignupCountryData()
@@ -74,27 +75,32 @@ export default function SignUp() {
}
const res = await userApi.CreateUser(reqData)
setSignUpLoading(true)
if (res.status === 200) {
const { data } = res
if (data.status == -1 && data.acc == 'DULPICATE') {
setMsgError('This account has been already created')
setSignUpLoading(false)
}
if (data.status > 0 && data.internal_return == 100 && data.session != '') {
localStorage.setItem("email", `${data.email}`);
localStorage.setItem("country", `${data.country}`);
localStorage.setItem("firstname", `${data.firstname}`);
localStorage.setItem("lastname", `${data.lastname}`);
setSignUpLoading(true)
setTimeout(() => {
navigate("/", { replace: true });
setSignUpLoading(false)
}, 2000)
console.log('Success')
} else {
setMsgError(data.status)
setSignUpLoading(false)
}
}
} else {
setMsgError('This account does not exist')
setSignUpLoading(false)
}
} catch (error) {
throw new Error(error)
@@ -102,7 +108,7 @@ export default function SignUp() {
} finally {
setTimeout(() => {
setMsgError(null)
}, 7000)
}, process.env.REACT_APP_SIGNUP_ERROR_TIMEOUT)
}
}
@@ -12,7 +12,9 @@ export default function InputCom({
inputHandler,
value,
forgotPassword,
onClick
onClick,
disable,
blurHandler,
}) {
return (
<div className="input-com">
@@ -25,7 +27,7 @@ export default function InputCom({
{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 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
@@ -36,7 +38,8 @@ export default function InputCom({
type={type}
id={name}
name={name}
required
readOnly={disable}
onBlur={blurHandler}
/>
{iconName && (
<div className="absolute right-6 bottom-[10px] z-10">
+302 -274
View File
@@ -1,4 +1,4 @@
import React, { useState } from "react";
import React, { useEffect, useState } from "react";
import Icons from "../../Helpers/Icons";
import InputCom from "../../Helpers/Inputs/InputCom";
import {Link, useNavigate} from 'react-router-dom'
@@ -7,6 +7,41 @@ import LoadingSpinner from "../../Spinners/LoadingSpinner";
import {toast} from 'react-toastify'
import {Formik, Form} from 'formik'
import * as Yup from 'yup'
const validationSchema = Yup.object().shape({
email: Yup.string()
.email('Wrong email format')
.min(3, 'Minimum 3 characters')
.max(50, 'Maximum 50 characters')
.required('Email is required'),
firstname: Yup.string()
.min(3, 'Minimum 3 characters')
.max(25, 'Maximum 25 characters')
.required('Firstname is required'),
lastname: Yup.string()
.min(3, 'Minimum 3 characters')
.max(25, 'Maximum 25 characters')
.required('Lastname is required'),
city: Yup.string()
.min(3, 'Minimum 3 characters')
.max(25, 'Maximum 25 characters')
.required('City is required'),
state: Yup.string()
.min(3, 'Minimum 3 characters')
.max(25, 'Maximum 25 characters')
.required('State is required'),
})
const initialValues = {
firstname: '',
lastname: '',
state: '',
city: '',
email: ''
}
export default function PersonalInfoTab({
datas,
frstNmeHndlr,
@@ -27,7 +62,13 @@ export default function PersonalInfoTab({
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: '',
loading: false,
status: false
@@ -41,40 +82,18 @@ export default function PersonalInfoTab({
email: ''
})
const handleChange = ({target:{name, value}}) => {
setInputs(prev => ({...prev, [name]:value}))
}
// const handleChange = ({target:{name, value}}) => {
// setInputs(prev => ({...prev, [name]:value}))
// }
const handleUpdateUser = ()=> {
const handleUpdateUser = (values, helpers)=> {
setRequestState({message: '', loading: true, status: false})
let {firstname, lastname, state, city, email} = inputs
if(!firstname || !lastname || !state || !city || !email){
setRequestState({message: 'Please Fill all fields', loading: false, status: false})
return
}
//checks if email is a valid email address
let regEx = /^[^0-9][a-zA-Z0-9._%+-]+@[a-zA-Z]+(\.[a-zA-Z]+)+$/;
if (regEx.test(email) == false) {
setRequestState({message: 'Your Email is Invalid', loading: false, status: false})
return
}
apiCall.updateProfile(inputs).then((res)=>{
apiCall.updateProfile(values).then((res)=>{
if(res.data.internal_return < 0){
setRequestState({message: 'Profile Was unable to update', loading: false, status: false})
return
}
setInputs({
firstname: '',
lastname: '',
state: '',
city: '',
email: ''
})
// setRequestState({message: 'Profile update successfully', loading: false, status: true})
toast.success("Update Successful");
setTimeout(()=>{navigate('/',{replace:true})},1000)
@@ -83,258 +102,267 @@ export default function PersonalInfoTab({
})
}
const loadProfile = ()=>{ // function to load user profile
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 (
<div className="personal-info-tab w-full flex flex-col justify-between">
<div className="flex flex-col-reverse sm:flex-row">
<div className="flex-1 sm:mr-10">
<div className="fields w-full">
{/* inputs starts here */}
{/* username */}
<div className='profile-input my-3'>
<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'
value={'username@gamil.com'}
name='username'
type="text"
placeholder='username@gamil.com'
disabled
/>
</div>
{/* Email */}
<div className='profile-input my-3'>
<label className='w-full text-slate-600 text-lg'>Email <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'
value={inputs.email}
name='email'
type="text"
placeholder='Firstname'
onChange={handleChange}
/>
</div>
{/* Fullname */}
<div className='profile-input my-3'>
<label className='w-full text-slate-600 text-lg'>Fullname <span className='text-red-500'>*</span></label>
<div className="w-full flex items-center justify-center space-x-1 space-y-1">
<input className='p-3 text-lg text-slate-500 bg-slate-100 rounded-md outline-0 placeholder:text-slate-500 placeholder:text-lg'
value={inputs.firstname}
name='firstname'
type="text"
placeholder='Firstname'
onChange={handleChange}
/>
<input className='p-3 text-lg text-slate-500 bg-slate-100 rounded-md outline-0 placeholder:text-slate-500 placeholder:text-lg'
value={inputs.lastname}
name='lastname'
type="text"
placeholder='Lastname'
onChange={handleChange}
/>
</div>
</div>
{/* Country */}
<div className='profile-input my-3'>
<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'
value='Nigeria'
name='country'
type="text"
disabled
/>
</div>
{/* State/Province */}
<div className='profile-input my-3'>
<label className='w-full text-slate-600 text-lg'>State/Province <span className='text-red-500'>*</span></label>
<input className='w-full p-3 text-lg text-slate-500 bg-slate-100 rounded-md outline-0 placeholder:text-slate-500 placeholder:text-lg'
value={inputs.state}
name='state'
type="text"
placeholder='State'
onChange={handleChange}
/>
</div>
{/* City */}
<div className='profile-input my-3'>
<label className='w-full text-slate-600 text-lg'>City <span className='text-red-500'>*</span></label>
<input className='w-full p-3 text-lg text-slate-500 bg-slate-100 rounded-md outline-0 placeholder:text-slate-500 placeholder:text-lg'
value={inputs.city}
name='city'
type="text"
placeholder='City'
onChange={handleChange}
/>
</div>
{/* Preferred Communication*/}
<div className='profile-input my-3'>
<label className='text-slate-600 text-lg'>Pref. Communication <span className='text-red-500'>*</span></label>
<div className="check-box">
<div className="flex items-center justify-start">
<div className="check-input flex items-center">
<input className="mx-2 w-4 h-4 cursor-pointer" type="checkbox" name="prefcomm1" id="" />
<span className="text-slate-600 text-lg">Email</span>
</div>
<div className="check-input flex items-center">
<input className="mx-2 w-4 h-4 cursor-pointer" type="checkbox" name="prefcomm2" id="" />
<span className="text-slate-600 text-lg">Phone</span>
</div>
</div>
</div>
</div>
{/* Allow Promotions */}
<div className='profile-input my-3 flex items-center space-x-4'>
<label className='text-slate-600 text-lg'>Allow Promotions</label>
<div className="cursor-pointer flex items-center" onClick={()=>setTogglePromotion(prev => !prev)}>
<div className={`h-6 w-8 mr-1 p-1 ${togglePromotion ? 'bg-sky-blue flex justify-end items-center': 'bg-slate-200'} rounded-full transition`}>
<div className="w-4 h-full bg-white rounded-full"></div>
</div>
</div>
</div>
{/* inputs ends here */}
</div>
</div>
<div className="w-[232px] mb-10">
<div className="update-profile w-full mb-9">
<h1 className="text-xl tracking-wide font-bold text-dark-gray dark:text-white flex items-center mb-2">
Update Profile
<span className="ml-1">
<Icons name="block-question" />
</span>
</h1>
<p className="text-base text-thin-light-gray mb-5">
Profile of at least Size
<span className="ml-1 text-dark-gray dark:text-white">
300x300
</span>
. Gifs work too.
<span className="ml-1 text-dark-gray dark:text-white">
Max 5mb
</span>
.
</p>
<div className="flex justify-center">
<div className="w-full relative">
<img
src={profileImg}
alt=""
className="sm:w-[198px] sm:h-[198px] w-[120px] h-[120px] rounded-full overflow-hidden object-cover"
/>
<input
ref={profileImgInput}
onChange={(e) => profileImgChangHandler(e)}
type="file"
className="hidden"
/>
<div
onClick={browseProfileImg}
className="w-[32px] h-[32px] absolute bottom-7 sm:right-10 right-[105px] hover:bg-pink bg-dark-gray rounded-full cursor-pointer"
>
<svg
width="32"
height="32"
viewBox="0 0 32 32"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M16.5147 11.5C17.7284 12.7137 18.9234 13.9087 20.1296 15.115C19.9798 15.2611 19.8187 15.4109 19.6651 15.5683C17.4699 17.7635 15.271 19.9587 13.0758 22.1539C12.9334 22.2962 12.7948 22.4386 12.6524 22.5735C12.6187 22.6034 12.5663 22.6296 12.5213 22.6296C11.3788 22.6334 10.2362 22.6297 9.09365 22.6334C9.01498 22.6334 9 22.6034 9 22.536C9 21.4009 9 20.2621 9.00375 19.1271C9.00375 19.0746 9.02997 19.0109 9.06368 18.9772C10.4123 17.6249 11.7609 16.2763 13.1095 14.9277C14.2295 13.8076 15.3459 12.6913 16.466 11.5712C16.4884 11.5487 16.4997 11.5187 16.5147 11.5Z"
fill="white"
/>
<path
d="M20.9499 14.2904C19.7436 13.0842 18.5449 11.8854 17.3499 10.6904C17.5634 10.4694 17.7844 10.2446 18.0054 10.0199C18.2639 9.76139 18.5261 9.50291 18.7884 9.24443C19.118 8.91852 19.5713 8.91852 19.8972 9.24443C20.7251 10.0611 21.5492 10.8815 22.3771 11.6981C22.6993 12.0165 22.7105 12.4698 22.3996 12.792C21.9238 13.2865 21.4443 13.7772 20.9686 14.2717C20.9648 14.2792 20.9536 14.2867 20.9499 14.2904Z"
fill="white"
/>
</svg>
</div>
</div>
</div>
</div>
<div className="update-profile w-full">
<h1 className="text-xl tracking-wide font-bold text-dark-gray dark:text-white flex items-center mb-2">
Update Cover
<span className="ml-1">
<Icons name="block-question" />
</span>
</h1>
<p className="text-base text-thin-light-gray mb-5">
Cover of at least Size
<span className="ml-1 text-dark-gray dark:text-white">
1170x920
</span>
.
</p>
<div className="flex justify-center">
<div className="w-full relative">
<img
src={coverImg}
alt=""
className="w-full h-[120px] rounded-lg overflow-hidden object-cover"
/>
<input
ref={coverImgInput}
onChange={(e) => coverImgChangHandler(e)}
type="file"
className="hidden"
/>
<div
onClick={browseCoverImg}
className="w-[32px] h-[32px] absolute -bottom-4 right-4 bg-dark-gray hover:bg-pink rounded-full cursor-pointer"
>
<svg
width="32"
height="32"
viewBox="0 0 32 32"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M16.5147 11.5C17.7284 12.7137 18.9234 13.9087 20.1296 15.115C19.9798 15.2611 19.8187 15.4109 19.6651 15.5683C17.4699 17.7635 15.271 19.9587 13.0758 22.1539C12.9334 22.2962 12.7948 22.4386 12.6524 22.5735C12.6187 22.6034 12.5663 22.6296 12.5213 22.6296C11.3788 22.6334 10.2362 22.6297 9.09365 22.6334C9.01498 22.6334 9 22.6034 9 22.536C9 21.4009 9 20.2621 9.00375 19.1271C9.00375 19.0746 9.02997 19.0109 9.06368 18.9772C10.4123 17.6249 11.7609 16.2763 13.1095 14.9277C14.2295 13.8076 15.3459 12.6913 16.466 11.5712C16.4884 11.5487 16.4997 11.5187 16.5147 11.5Z"
fill="white"
/>
<path
d="M20.9499 14.2904C19.7436 13.0842 18.5449 11.8854 17.3499 10.6904C17.5634 10.4694 17.7844 10.2446 18.0054 10.0199C18.2639 9.76139 18.5261 9.50291 18.7884 9.24443C19.118 8.91852 19.5713 8.91852 19.8972 9.24443C20.7251 10.0611 21.5492 10.8815 22.3771 11.6981C22.6993 12.0165 22.7105 12.4698 22.3996 12.792C21.9238 13.2865 21.4443 13.7772 20.9686 14.2717C20.9648 14.2792 20.9536 14.2867 20.9499 14.2904Z"
fill="white"
/>
</svg>
</div>
</div>
</div>
</div>
profile.loading ?
<div className="personal-info-tab w-full flex flex-col justify-between">
<div className="p-3">
<LoadingSpinner size='32' color='sky-blue' />
</div>
</div>
<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>}
<div className="w-full h-[120px] border-t border-light-purple dark:border-[#5356fb29] flex justify-end items-center">
<div className="flex items-center space-x-4 mr-9">
<Link
to='/'
className="text-18 text-light-red tracking-wide "
>
<span className="border-b dark:border-[#5356fb29] border-light-red">
{" "}
Cancel
</span>
</Link>
:
<div className="personal-info-tab w-full flex flex-col justify-between">
<Formik initialValues={inputs} validationSchema={validationSchema} onSubmit={handleUpdateUser}>
{(props => {
return (
<Form>
{
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="fields w-full">
{/* inputs starts here */}
{/* username */}
<div className="field w-full mb-6">
<InputCom
label="User Name"
type="text"
name="username"
placeholder=""
value={item.username}
disable={true}
/>
</div>
{requestStatus.loading ?
<LoadingSpinner size='8' color='sky-blue' />
{/* Email */}
<div className="field w-full mb-6">
<InputCom
label="Email"
type="text"
name="email"
placeholder="Email"
value={props.values.email}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{(props.errors.email && props.touched.email) && <p className="text-sm text-red-500">{props.errors.email}</p>}
</div>
{/* first name and last name */}
<div className="xl:flex xl:space-x-7 mb-6">
<div className="field w-full mb-6 xl:mb-0">
<InputCom
label="First Name"
type="text"
name="firstname"
placeholder="First Name"
value={props.values.firstname}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{(props.errors.firstname && props.touched.firstname) && <p className="text-sm text-red-500">{props.errors.firstname}</p>}
</div>
<div className="field w-full">
<InputCom
label="Last Name"
type="text"
name="lastname"
placeholder="Last Name"
value={props.values.lastname}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{(props.errors.lastname && props.touched.lastname) && <p className="text-sm text-red-500">{props.errors.lastname}</p>}
</div>
</div>
{/* Country */}
<div className="field w-full mb-6">
<InputCom
label="Country"
type="text"
name="country"
value={item.country}
disable={true}
/>
</div>
{/* State/Province */}
<div className="field w-full mb-6">
<InputCom
label="State/Province"
type="text"
name="state"
placeholder="State"
value={props.values.state}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{(props.errors.state && props.touched.state) && <p className="text-sm text-red-500">{props.errors.state}</p>}
</div>
{/* City */}
<div className="field w-full mb-6">
<InputCom
label="City"
type="text"
name="city"
placeholder="City"
value={props.values.city}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{(props.errors.city && props.touched.city) && <p className="text-sm text-red-500">{props.errors.city}</p>}
</div>
{/* Preferred Communication*/}
<div className='field w-full mb-6 md:flex items-center space-x-4'>
<label className='input-label text-[#181c32] dark:text-white text-base font-semibold'>Pref. Communication</label>
<div className="check-box">
<div className="flex items-center justify-start">
<div className="check-input flex items-center mr-1">
<input className="w-4 h-4 cursor-pointer" type="checkbox" name="prefcomm1" id="" />
<span className="mx-2 text-base text-dark-gray dark:text-white">Email</span>
</div>
<div className="check-input flex items-center">
<input className="w-4 h-4 cursor-pointer" type="checkbox" name="prefcomm2" id="" />
<span className="mx-2 text-base text-dark-gray dark:text-white">Phone</span>
</div>
</div>
</div>
</div>
{/* Allow Promotions */}
<div className='field w-full mb-6 flex items-center space-x-4'>
<label className='input-label text-[#181c32] dark:text-white text-base font-semibold'>Allow Promotions</label>
<div className="cursor-pointer flex items-center" onClick={()=>setTogglePromotion(prev => !prev)}>
<div className={`h-6 w-8 mr-1 p-1 ${togglePromotion ? 'bg-sky-blue flex justify-end items-center': 'bg-slate-200'} rounded-full transition`}>
<div className="w-4 h-full bg-white rounded-full"></div>
</div>
</div>
</div>
{/* inputs ends here */}
</div>
</div>
<div className="w-[232px] mb-10">
<div className="update-profile w-full mb-9">
<h1 className="text-xl tracking-wide font-bold text-dark-gray dark:text-white flex items-center mb-2">
Update Profile
<span className="ml-1">
<Icons name="block-question" />
</span>
</h1>
<p className="text-base text-thin-light-gray mb-5">
Profile of at least Size
<span className="ml-1 text-dark-gray dark:text-white">
300x300
</span>
. Gifs work too.
<span className="ml-1 text-dark-gray dark:text-white">
Max 5mb
</span>
.
</p>
<div className="flex justify-center">
<div className="w-full relative">
<img
src={profileImg}
alt=""
className="sm:w-[198px] sm:h-[198px] w-[120px] h-[120px] rounded-full overflow-hidden object-cover"
/>
<input
ref={profileImgInput}
onChange={(e) => profileImgChangHandler(e)}
type="file"
className="hidden"
/>
<div
onClick={browseProfileImg}
className="w-[32px] h-[32px] absolute bottom-7 sm:right-10 right-[105px] hover:bg-pink bg-dark-gray rounded-full cursor-pointer"
>
<svg
width="32"
height="32"
viewBox="0 0 32 32"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M16.5147 11.5C17.7284 12.7137 18.9234 13.9087 20.1296 15.115C19.9798 15.2611 19.8187 15.4109 19.6651 15.5683C17.4699 17.7635 15.271 19.9587 13.0758 22.1539C12.9334 22.2962 12.7948 22.4386 12.6524 22.5735C12.6187 22.6034 12.5663 22.6296 12.5213 22.6296C11.3788 22.6334 10.2362 22.6297 9.09365 22.6334C9.01498 22.6334 9 22.6034 9 22.536C9 21.4009 9 20.2621 9.00375 19.1271C9.00375 19.0746 9.02997 19.0109 9.06368 18.9772C10.4123 17.6249 11.7609 16.2763 13.1095 14.9277C14.2295 13.8076 15.3459 12.6913 16.466 11.5712C16.4884 11.5487 16.4997 11.5187 16.5147 11.5Z"
fill="white"
/>
<path
d="M20.9499 14.2904C19.7436 13.0842 18.5449 11.8854 17.3499 10.6904C17.5634 10.4694 17.7844 10.2446 18.0054 10.0199C18.2639 9.76139 18.5261 9.50291 18.7884 9.24443C19.118 8.91852 19.5713 8.91852 19.8972 9.24443C20.7251 10.0611 21.5492 10.8815 22.3771 11.6981C22.6993 12.0165 22.7105 12.4698 22.3996 12.792C21.9238 13.2865 21.4443 13.7772 20.9686 14.2717C20.9648 14.2792 20.9536 14.2867 20.9499 14.2904Z"
fill="white"
/>
</svg>
</div>
</div>
</div>
</div>
</div>
</div>
))
:
<button
type="button"
className="w-[152px] h-[46px] flex justify-center items-center btn-gradient text-base rounded-full text-white"
onClick={handleUpdateUser}
>
Upadate Profile
</button>
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>
</div>
<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>}
<div className="w-full h-[120px] border-t border-light-purple dark:border-[#5356fb29] flex justify-end items-center">
<div className="flex items-center space-x-4 mr-9">
<Link
to='/'
className="text-18 text-light-red tracking-wide "
>
<span className="border-b dark:border-[#5356fb29] border-light-red">
{" "}
Cancel
</span>
</Link>
{requestStatus.loading ?
<LoadingSpinner size='8' color='sky-blue' />
:
<button
type="submit"
className="w-[152px] h-[46px] flex justify-center items-center btn-gradient text-base rounded-full text-white"
>
Update Profile
</button>
}
</div>
</div>
</div>
</Form>
)
})}
</Formik>
</div>
</div>
);
}
-1
View File
@@ -8,7 +8,6 @@ const AuthRoute = ({ redirectPath = "/login", children }) => {
const navigate = useNavigate();
const { pathname } = useLocation();
//Removing Data stored at localStorage after session expires
const expireSession = () => {
localStorage.removeItem("email");
+19 -5
View File
@@ -6,6 +6,11 @@ class usersService {
console.log("WRB Service Entry");
}
CreateUser(reqData){
localStorage.setItem("session_token", ``);
return this.postAuxEnd("/createuser", reqData);
}
getHomeDate(){
var postData = {
uuid: localStorage.getItem("uuid"),
@@ -48,11 +53,6 @@ class usersService {
return this.postAuxEnd("/apigate", null);
}
CreateUser(reqData){
localStorage.setItem("session_token", ``);
return this.postAuxEnd("/createuser", reqData);
}
getLoadProfile(){
var postData = {
uuid: localStorage.getItem("uid"),
@@ -228,11 +228,25 @@ class usersService {
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
sendReferralMsg(postData){
return this.postAuxEnd("/sendreferral", postData);
}
StartResetPassword(reqData){
return this.postAuxEnd("/startresetpasword", reqData)
}
getCouponRedeem(){
var postData = {
uuid: localStorage.getItem("uid"),