Compare commits

...

3 Commits

Author SHA1 Message Date
victorAnumudu e6153e0b3d update profile validation with formik and yup 2023-04-25 19:57:40 +01:00
DESKTOP-GBA0BK8\Admin 02fe8cb399 npm i yup npm i formik 2023-04-25 08:40:18 -04:00
ameye 0819105fcb Merge branch 'profile_page_styling' of WrenchBoard/Users-Wrench into master 2023-04-25 12:28:13 +00:00
3 changed files with 282 additions and 247 deletions
+3 -1
View File
@@ -13,6 +13,7 @@
"chartjs": "^0.3.24", "chartjs": "^0.3.24",
"cors": "^2.8.5", "cors": "^2.8.5",
"faker": "^6.6.6", "faker": "^6.6.6",
"formik": "^2.2.9",
"react": "^18.0.0", "react": "^18.0.0",
"react-chartjs-2": "^4.1.0", "react-chartjs-2": "^4.1.0",
"react-countup": "^6.2.0", "react-countup": "^6.2.0",
@@ -25,7 +26,8 @@
"react-toastify": "^9.0.1", "react-toastify": "^9.0.1",
"redux": "^4.2.0", "redux": "^4.2.0",
"slick-carousel": "^1.8.1", "slick-carousel": "^1.8.1",
"web-vitals": "^1.0.1" "web-vitals": "^1.0.1",
"yup": "^1.1.1"
}, },
"scripts": { "scripts": {
"start": "react-scripts start", "start": "react-scripts start",
@@ -13,7 +13,8 @@ export default function InputCom({
value, value,
forgotPassword, forgotPassword,
onClick, onClick,
disable disable,
blurHandler,
}) { }) {
return ( return (
<div className="input-com"> <div className="input-com">
@@ -37,8 +38,8 @@ export default function InputCom({
type={type} type={type}
id={name} id={name}
name={name} name={name}
required
readOnly={disable} readOnly={disable}
onBlur={blurHandler}
/> />
{iconName && ( {iconName && (
<div className="absolute right-6 bottom-[10px] z-10"> <div className="absolute right-6 bottom-[10px] z-10">
@@ -7,6 +7,41 @@ import LoadingSpinner from "../../Spinners/LoadingSpinner";
import {toast} from 'react-toastify' 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({ export default function PersonalInfoTab({
datas, datas,
frstNmeHndlr, frstNmeHndlr,
@@ -47,40 +82,18 @@ export default function PersonalInfoTab({
email: '' email: ''
}) })
const handleChange = ({target:{name, value}}) => { // const handleChange = ({target:{name, value}}) => {
setInputs(prev => ({...prev, [name]:value})) // setInputs(prev => ({...prev, [name]:value}))
} // }
const handleUpdateUser = ()=> { const handleUpdateUser = (values, helpers)=> {
setRequestState({message: '', loading: true, status: false}) setRequestState({message: '', loading: true, status: false})
let {firstname, lastname, state, city, email} = inputs apiCall.updateProfile(values).then((res)=>{
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)=>{
if(res.data.internal_return < 0){ if(res.data.internal_return < 0){
setRequestState({message: 'Profile Was unable to update', loading: false, status: false}) setRequestState({message: 'Profile Was unable to update', loading: false, status: false})
return return
} }
setInputs({
firstname: '',
lastname: '',
state: '',
city: '',
email: ''
})
// setRequestState({message: 'Profile update successfully', loading: false, status: true}) // setRequestState({message: 'Profile update successfully', loading: false, status: true})
toast.success("Update Successful"); toast.success("Update Successful");
setTimeout(()=>{navigate('/',{replace:true})},1000) setTimeout(()=>{navigate('/',{replace:true})},1000)
@@ -89,7 +102,7 @@ export default function PersonalInfoTab({
}) })
} }
const loadProfile = ()=>{ const loadProfile = ()=>{ // function to load user profile
apiCall.loadProfile().then((res)=>{ apiCall.loadProfile().then((res)=>{
if(res.data.internal_return < 0){ if(res.data.internal_return < 0){
setProfile(prev => ({...prev, loading: false, status: true})) setProfile(prev => ({...prev, loading: false, status: true}))
@@ -113,13 +126,20 @@ export default function PersonalInfoTab({
},[]) },[])
return ( return (
<div className="personal-info-tab w-full flex flex-col justify-between">
{profile.loading ? profile.loading ?
<div className="personal-info-tab w-full flex flex-col justify-between">
<div className="p-3"> <div className="p-3">
<LoadingSpinner size='32' color='sky-blue' /> <LoadingSpinner size='32' color='sky-blue' />
</div> </div>
</div>
: :
<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.length ?
profile.data.map((item, index) => ( profile.data.map((item, index) => (
<div key={index} className="flex flex-col-reverse sm:flex-row"> <div key={index} className="flex flex-col-reverse sm:flex-row">
@@ -145,9 +165,11 @@ export default function PersonalInfoTab({
type="text" type="text"
name="email" name="email"
placeholder="Email" placeholder="Email"
value={inputs.email} value={props.values.email}
inputHandler={handleChange} inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/> />
{(props.errors.email && props.touched.email) && <p className="text-sm text-red-500">{props.errors.email}</p>}
</div> </div>
{/* first name and last name */} {/* first name and last name */}
<div className="xl:flex xl:space-x-7 mb-6"> <div className="xl:flex xl:space-x-7 mb-6">
@@ -157,9 +179,11 @@ export default function PersonalInfoTab({
type="text" type="text"
name="firstname" name="firstname"
placeholder="First Name" placeholder="First Name"
value={inputs.firstname} value={props.values.firstname}
inputHandler={handleChange} 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>
<div className="field w-full"> <div className="field w-full">
<InputCom <InputCom
@@ -167,9 +191,11 @@ export default function PersonalInfoTab({
type="text" type="text"
name="lastname" name="lastname"
placeholder="Last Name" placeholder="Last Name"
value={inputs.lastname} value={props.values.lastname}
inputHandler={handleChange} 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>
</div> </div>
@@ -191,9 +217,11 @@ export default function PersonalInfoTab({
type="text" type="text"
name="state" name="state"
placeholder="State" placeholder="State"
value={inputs.state} value={props.values.state}
inputHandler={handleChange} inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/> />
{(props.errors.state && props.touched.state) && <p className="text-sm text-red-500">{props.errors.state}</p>}
</div> </div>
{/* City */} {/* City */}
@@ -201,11 +229,13 @@ export default function PersonalInfoTab({
<InputCom <InputCom
label="City" label="City"
type="text" type="text"
name="state" name="city"
placeholder="City" placeholder="City"
value={inputs.city} value={props.values.city}
inputHandler={handleChange} inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/> />
{(props.errors.city && props.touched.city) && <p className="text-sm text-red-500">{props.errors.city}</p>}
</div> </div>
{/* Preferred Communication*/} {/* Preferred Communication*/}
@@ -302,7 +332,6 @@ export default function PersonalInfoTab({
: :
<div className="py-3 text-slate-500">Opps! something went wrong. Try Again Later!</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">
@@ -321,16 +350,19 @@ export default function PersonalInfoTab({
<LoadingSpinner size='8' color='sky-blue' /> <LoadingSpinner size='8' color='sky-blue' />
: :
<button <button
type="button" type="submit"
className="w-[152px] h-[46px] flex justify-center items-center btn-gradient text-base rounded-full text-white" className="w-[152px] h-[46px] flex justify-center items-center btn-gradient text-base rounded-full text-white"
onClick={handleUpdateUser}
> >
Upadate Profile Update Profile
</button> </button>
} }
</div> </div>
</div> </div>
</div> </div>
</Form>
)
})}
</Formik>
</div> </div>
); );
} }