React Hook form and yup validation - reactjs

I have created a buy now component for my react js ecommerce website. The problem I am facing is that the validation of form is not being done. I have used a resolver but still it doesnot validate my form.Here is my code :`
import React, { useEffect, useState } from 'react'
import "./e.css"
import { useForm } from "react-hook-form";
import { yupResolver } from "#hookform/resolvers/yup"
import * as yup from "yup"
export default function BuyNow(props) {
const [country, setCountry] = useState([])
useEffect(() => {
const getcountry = async () => {
const res = await fetch("http://localhost:3000/setpk.json")
const getcon = await res.json()
setCountry(await getcon)
}
getcountry()
}, [])
const schema = yup.object({
fullname: yup.string().required(),
email: yup.string().email().required(),
address: yup.string().required(),
phoneno: yup.number().required().integer().min(11),
city: yup.string().required(),
payment: yup.string().required()
})
const { register, handleSubmit, watch, formState: { errors } } = useForm({
resolver: yupResolver(schema)
});
const onSubmit = (data) => {
console.log(data)
}
return (
<>
<div className="details h-[90vh] bg-indigo-600 mt-20 text-indigo-400 text-center">
<h1 className='text-indigo-200'>Buy Now</h1>
<form onSubmit={handleSubmit(onSubmit)}>
<div className='space-y-5 mt-4 flex flex-col w-[70%] sm:w-[66%] md:w-[55%] mx-auto'>
<input name="thename" id="name" placeholder='Name' {...register("fullname")
} />
<input name="email" id="email" placeholder='Email' className="text-indigo-400 "
{...register("email")
} />
<input name="address" id="address" placeholder='Shipping Address' {...register("address")
} />
<input type="number" name="phone" id="" placeholder='Phone No.' {...register("phoneno")
} />
<select name="sa" id="as" {...register("city")
} >
<option disabled selected >--City Name--</option>
{
country.map((countryget, i) => (
<option key={i} >{countryget.city}</option>
))
}
</select>
<div className='flex relative w-auto'>
<select name="" id="" className='thepayment basis-full w-[70%] ' {...register("payment")
}>
<option disabled selected > --Payment Method-- </option>
<option >Credit Card</option>
<option >Cash on delivery</option>
<option >Bank Transfer</option>
</select>
<img src="http://localhost:3000/creditcard.png" alt="" className='absolute w-10 right-5' />
</div>
{/* <button type="submit" className='bg-indigo-600 p-2 rounded-lg font-mono absolute '>Proceed ➔</button> */}
</div>
<input type="submit" className='bg-rose-600 p-2 rounded-lg font-mono text-white mt-3' />
</form>
</div>
<div className="pricesection h-20 bg-rose-600 fixed bottom-0 left-0 right-0 flex items-center px-1 text-rose-100 justify-evenly md:justify-around">
<h2 className='text-xl md:text-2xl md:font-bold '>Total Price</h2>
<h2 className='text-2xl font-bold '>${props.totalprice}</h2>
</div>
</>
)
}
I want the form to be uncontrolled.I have written schema and also used resolver.

I fixed this by putting yup.string() instead of yup.integer()
phoneno: yup.number().required().integer().min(11),

Related

React TS, First submit returns empty array

I'm trying to make simple form using React,Typescript, have done some inputs and while adding them with onChange to one main state, first submit always returns empty. Why?
import React from "react";
import { useState } from "react";
import { Form } from "../components/Form/Form";
import { Navbar } from "../components/Navbar";
export const MainPage = () => {
const [formData, setFormData] = useState([]);
return (
<div className="w-full flex">
<Navbar />
<Form formData={formData} setFormData={setFormData} />
</div>
);
};
import React from "react";
import { useState } from "react";
interface Props{
formData: string[];
setFormData: React.Dispatch<React.SetStateAction<any>>;
}
export const Form: React.FC<Props> = ({setFormData, formData}) => {
const [organization, setOrganization] = useState<string>("");
const [title, setTitle] = useState<string>("");
const [firstName, setFirstName] = useState<string>("");
const [lastName, setLastName] = useState<string>("");
const [languages, setLanguages] = useState<string>("");
const [employmentType, setEmploymentType] = useState<string>("");
const [profession, setProfession] = useState<string>("");
const [proficiency, setProficiency] = useState<string>("");
const submitData = (e: any) => {
const data = {
organization,
title,
firstName,
lastName,
languages,
employmentType,
profession,
proficiency,
};
setFormData((prevData: any) => [...prevData, data]);
console.log(formData)
}
return (
<div className="w-full">
<div className="w-3/4 mx-auto mt-5">
<h1 className="text-2xl">About you</h1>
<div className="top flex mt-16 gap-8">
<div>
<h2 className="text-xl font-bold">Personal info</h2>
<p className="text-sm font-extralight">
Provide your personal info
</p>
</div>
<div className="flex flex-col gap-5">
<div>
<input
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setOrganization(e.target.value);
}}
className="w-full bg-gray-200 p-2 rounded-md placeholder:text-sm placeholder:text-black"
placeholder="Organization"
></input>
</div>
<div className="flex gap-3">
<select
onChange={(e: React.ChangeEvent<HTMLSelectElement>) => {
setTitle(e.target.value);
}}
className="bg-gray-200 p-2 rounded-md placeholder:text-sm placeholder:text-black"
>
<option value="Title">Title</option>
<option value="Mr">Mr</option>
<option value="Mrs">Mrs</option>
<option value="Miss">Miss</option>
<option value="Ms">Ms</option>
</select>
<input
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setFirstName(e.target.value);
}}
className="bg-gray-200 p-2 rounded-md placeholder:text-sm placeholder:text-black"
placeholder="First name"
></input>
<input
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setLastName(e.target.value);
}}
className="bg-gray-200 p-2 rounded-md placeholder:text-sm placeholder:text-black"
placeholder="Last name"
></input>
</div>
</div>
</div>
</div>
<hr className="mt-16"></hr>
<div className="bottom w-3/4 mx-auto mt-16">
<div>
<h2 className="text-xl font-bold">Professional info</h2>
<p className="text-sm font-extralight">
Provide your professional info
</p>
</div>
<div className="mt-14">
<div className="flex flex-col gap-8 items-center">
<input
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setLanguages(e.target.value);
}}
className="w-3/4 bg-gray-200 p-2 rounded-md placeholder:text-sm placeholder:text-black"
placeholder="Language(s) separate with comma"
></input>
<input
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setEmploymentType(e.target.value);
}}
className="w-3/4 bg-gray-200 p-2 rounded-md placeholder:text-sm placeholder:text-black"
placeholder="Type of employment"
></input>
<input
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setProfession(e.target.value);
}}
className="w-3/4 bg-gray-200 p-2 rounded-md placeholder:text-sm placeholder:text-black"
placeholder="Profession"
></input>
<input
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setProficiency(e.target.value);
}}
className="w-3/4 bg-gray-200 p-2 rounded-md placeholder:text-sm placeholder:text-black"
placeholder="Proficiency level"
></input>
</div>
</div>
</div>
<div className="w-3/4 flex justify-end mt-7">
<button onClick={(e) => submitData(e)} className="bg-sky-800 p-2 text-white rounded-md">Submit</button>
</div>
</div>
);
};
Read other threads about similar issue but there was mentioned using async, i believe there would be another way to fix this. Thank you
Hi there setState in Reactjs is asynchronous so when you called submitData console.log(formData) gets triggered even before the setState completed its task and with asynchronous code, javascript does not have to wait for setState to finish up it just keeps running other tasks.
setFormData((prevData: anyType) => {
const newData = [...prevData, data];
console.log(newData);
return newData;
});

How to Redirect a Register Page to another Page using React & Formik

The page is not responding after clicking the sign up button, I wonder what went wrong with the code. I want it to redirect to "dashboards/elearning" page. The NavLink points not to the Sign Up button, and if I add a NavLink around sign up button, the validation would be pointless.
Below is the register.js file.
import React from 'react';
import { NavLink } from 'react-router-dom';
import { Button, Form } from 'react-bootstrap';
import * as Yup from 'yup';
import { useFormik } from 'formik';
import LayoutFullpage from 'layout/LayoutFullpage';
import CsLineIcons from 'cs-line-icons/CsLineIcons';
import HtmlHead from 'components/html-head/HtmlHead';
const Register = () => {
const title = 'Register';
const description = 'Register Page';
const validationSchema = Yup.object().shape({
name: Yup.string().required('Name is required'),
email: Yup.string().email().required('Email is required'),
password: Yup.string().min(6, 'Must be at least 6 chars!').required('Password is required'),
terms: Yup.bool().required().oneOf([true], 'Terms must be accepted'),
});
const initialValues = { name: '', email: '', password: '', terms: false };
const onSubmit = (values) => console.log('submit form', values);
const formik = useFormik({ initialValues, validationSchema, onSubmit });
const { handleSubmit, handleChange, values, touched, errors } = formik;
const leftSide = (
<div className="min-h-100 d-flex align-items-center">
<div className="w-100 w-lg-75 w-xxl-50">
<div>
<div className="mb-5">
<h1 className="display-3 text-white">Multiple Niches</h1>
<h1 className="display-3 text-white">Ready for Your Project</h1>
</div>
<p className="h6 text-white lh-1-5 mb-5">
Dynamically target high-payoff intellectual capital for customized technologies. Objectively integrate emerging core competencies before
process-centric communities...
</p>
<div className="mb-5">
<Button size="lg" variant="outline-white" href="/">
Learn More
</Button>
</div>
</div>
</div>
</div>
);
// if <NavLink to="/dashboards/elearning"> Sign up </NavLink>, all other validation mathods invalid
const rightSide = (
<div className="sw-lg-70 min-h-100 bg-foreground d-flex justify-content-center align-items-center shadow-deep py-5 full-page-content-right-border">
<div className="sw-lg-50 px-5">
<div className="sh-11">
<NavLink to="/dashboards/elearning">
<div className="logo-default" />
</NavLink>
</div>
<div className="mb-5">
<h2 className="cta-1 mb-0 text-primary">Welcome,</h2>
<h2 className="cta-1 text-primary">let's get the ball rolling!</h2>
</div>
<div className="mb-5">
<p className="h6">Please use the form to register.</p>
<p className="h6">
If you are a member, please <NavLink to="/login">login</NavLink>.
</p>
</div>
<div>
<form id="registerForm" className="tooltip-end-bottom" onSubmit={handleSubmit}>
<div className="mb-3 filled form-group tooltip-end-top">
<CsLineIcons icon="user" />
<Form.Control type="text" name="name" placeholder="Name" value={values.name} onChange={handleChange} />
{errors.name && touched.name && <div className="d-block invalid-tooltip">{errors.name}</div>}
</div>
<div className="mb-3 filled form-group tooltip-end-top">
<CsLineIcons icon="email" />
<Form.Control type="text" name="email" placeholder="Email" value={values.email} onChange={handleChange} />
{errors.email && touched.email && <div className="d-block invalid-tooltip">{errors.email}</div>}
</div>
<div className="mb-3 filled form-group tooltip-end-top">
<CsLineIcons icon="lock-off" />
<Form.Control type="password" name="password" onChange={handleChange} value={values.password} placeholder="Password" />
{errors.password && touched.password && <div className="d-block invalid-tooltip">{errors.password}</div>}
</div>
<div className="mb-3 position-relative form-group">
<div className="form-check">
<input type="checkbox" className="form-check-input" name="terms" onChange={handleChange} value={values.terms} />
<label className="form-check-label">
I have read and accept the{' '}
<NavLink to="/dashboards/elearning" target="_blank">
terms and conditions.
</NavLink>
</label>
{errors.terms && touched.terms && <div className="d-block invalid-tooltip">{errors.terms}</div>}
</div>
</div>
<Button size="lg" type="submit">
Signup
</Button>
</form>
</div>
</div>
</div>
);
return (
<>
<HtmlHead title={title} description={description} />
<LayoutFullpage left={leftSide} right={rightSide} />
</>
);
};
export default Register;
You can use the useNavigate hook from react-router-dom
Please find the necessary snippet below.
import { useNavigate } from 'react-router-dom';
...
const navigate = useNavigate();
const onSubmit = (values) => {
console.log('submit form', values);
navigate('dashboards/elearning');
};
...

After browser relode i got the user profile pic in website.how can i get it first time without browser reloding

**
import { useForm } from "react-hook-form";
import React, { useState } from "react";
import { useEffect } from "react";
import { useUpdateProfile } from "react-firebase-hooks/auth";
import { ref, uploadBytesResumable, getDownloadURL } from "firebase/storage";
import {
useCreateUserWithEmailAndPassword,
useSignInWithGoogle,
} from "react-firebase-hooks/auth";
import auth, { storage } from "../../firebase.init";
import { Link, useLocation, useNavigate } from "react-router-dom";
import Loader from "../Shared/Loader";
const Register = () => {
const [image, setImage] = useState(null);
const [url, setUrl] = useState(null);
const [percentage, setPercentage] = useState("");
const [updateProfile, updating] = useUpdateProfile(auth);
const [signInWithGoogle, gUser, gLoading] = useSignInWithGoogle(auth);
const [
createUserWithEmailAndPassword,
user,
loading,
error,
] = useCreateUserWithEmailAndPassword(auth);
const navigate = useNavigate();
const { register, handleSubmit, formState } = useForm({
mode: "onChange", // I want to change it to onBlur
});
const { isValid, errors } = formState;
const handleimagechange = (e) => {
if (e.target.files[0]) {
setImage(e.target.files[0]);
}
};
**useEffect(() => {
if (user?.user?.uid) {
navigate("/appiontment");
window.location.reload();
}
}, [user?.user?.uid, navigate]);
useEffect(() => {
if (gUser?.user?.uid) {
navigate("/appiontment");
}
}, [gUser?.user?.uid, navigate]);**
**useEffect(() => {
const uploadImage = () => {
// const name = new Date().getTime + image.name
const storageRef = ref(storage, image.name);
const uploadTask = uploadBytesResumable(storageRef, image);
uploadTask.on(
"state_changed",
(snapshot) => {
const progress =
(snapshot.bytesTransferred / snapshot.totalBytes) * 100;
setPercentage(progress);
switch (snapshot.state) {
case "paused":
break;
case "running":
break;
default:
break;
}
},
(error) => {},
() => {
getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => {
console.log("File available at", downloadURL);
setUrl(downloadURL);
});
}
);
};
image && uploadImage();
}, [image]);**
let singninErrors;
if (error?.message === "Firebase: Error (auth/email-already-in-use).") {
singninErrors = (
<div
className="bg-red-100 rounded-lg py-5 px-6 mb-4 text-base text-red-700 mb-3"
role="alert"
>
Email already Exsist
</div>
);
console.log(error.message);
}
**const onSubmit = async (data) => {
await createUserWithEmailAndPassword(data.email, data.password, data.name);
await updateProfile({ displayName: data.name, photoURL: url });
};
if (error) {
console.log(error.message);
}**
if (loading || gLoading || updating) {
return <Loader />;
}
return (
<div className="flex h-screen justify-center items-center ">
<div className="card w-96 bg-base-100 shadow-xl">
<div className="card-body">
<div className="flex flex-col w-full border-opacity-50">
<h1 className="text-xl text-center">Sign Up</h1>
<form onSubmit={handleSubmit(onSubmit)}>
<div className="form-control w-full max-w-xs ">
<label className="label">
<span className="label-text">Name</span>
</label>
<input
{...register("name", {
required: {
value: true,
message: "Name is required",
},
})}
type="text"
placeholder="Your Name"
className="input input-bordered w-full max-w-xs"
/>
<label className="label">
{errors.name?.type === "required" && (
<span className="label-text text-red-500">
{errors.name.message}
</span>
)}
</label>
</div>
<div className="form-control w-full max-w-xs ">
<label className="label">
<span className="label-text">Email</span>
</label>
<input
{...register("email", {
required: {
value: true,
message: "Email Adress is required",
},
pattern: {
value: /^[^\s#]+#[^\s#]+\.[^\s#]+$/,
message: "please enter a valid email adress",
},
})}
type="email"
placeholder="Your Email"
className="input input-bordered w-full max-w-xs"
/>
<label className="label">
{errors.email?.type === "required" && (
<span className="label-text text-red-500">
{errors.email.message}
</span>
)}
{errors.email?.type === "pattern" && (
<span className="label-text text-red-500">
{errors.email.message}
</span>
)}
</label>
</div>
<div className="form-control w-full max-w-xs ">
<label className="label">
<span className="label-text">Password</span>
</label>
<input
{...register("password", {
required: {
value: true,
message: "password is required",
},
minLength: {
value: 6,
message: "password must be 6 character or long",
},
})}
type="password"
placeholder="Your password"
className="input input-bordered w-full max-w-xs"
/>
<label className="label">
{errors.password?.type === "required" && (
<span className="label-text text-red-500">
{errors.password.message}
</span>
)}
{errors.password?.type === "minLength" && (
<span className="label-text text-red-500">
{errors.password.message}
</span>
)}
</label>
</div>
<label className="label">Upload Your Avatar</label>
<div className="w-full bg-gray-200 rounded-full">
{percentage === 0 && (
<div
className="bg-blue-100 rounded-lg py-5 px-6 mb-4 text-base text-blue-700
mb-3"
role="alert"
>
Image Uploading please wait
</div>
)}
{percentage === 100 && url && (
<div
className="bg-green-100 rounded-lg py-5 px-6 mb-4 text-base text-green-700
mb-3"
role="alert"
>
img Uploading:{percentage}% Successfully
</div>
)}
</div>
<div className="flex justify-center">
<div className="mb-3 w-96 ">
<input
onChange={handleimagechange}
className="form-control block
w-full
px-3
py-1.5
text-base
font-normal
text-gray-700
bg-white bg-clip-padding
border border-solid border-gray-300
rounded
transition
ease-in-out
m-0
focus:text-gray-700 focus:bg-white focus:border-blue-
600 focus:outline-none"
type="file"
id="formFile"
/>
</div>
</div>
{singninErrors}
<button
disabled={!isValid || !url}
type="submit"
className="btn w-full max-w-xs">
Signup</button> </form>
<p className="font-semibold ">
<small>
already have an account ?
<Link className="text-secondary mx-2" to="/">
Please login
</Link>
</small>
</p>
<div className="divider">OR</div>
<button
onClick={() => signInWithGoogle()}
className="btn btn-outline"
>
Continue with Google
</button>
</div>
</div>
</div>
</div>
);
};
export default Register;
**

React Firebase is not getting data from React Hook form

This is what I'm stuck with for last couple of hours. I have tried default values from react hook form. I kinda getting the user input on the console but for firebase it's showing error. It is working with the normal input system
import React, { useEffect } from "react";
import {
useAuthState,
useCreateUserWithEmailAndPassword,
} from "react-firebase-hooks/auth";
import { useForm } from "react-hook-form";
import { Link, useNavigate } from "react-router-dom";
import { toast } from "react-toastify";
import auth from "../../firebase.init";
import Loading from "../Shared/Loading";
import GoogleLogin from "./GoogleLogin";
const Signup = () => {
const [createUserWithEmailAndPassword,loading] =
useCreateUserWithEmailAndPassword(auth);
const navigate = useNavigate();
const [user] = useAuthState(auth);
useEffect(() => {
if (user) {
navigate("/home");
}
}, [navigate, user]);
const {
register,
formState: { errors },
handleSubmit,
} = useForm();
const onSubmit = (data) => {
createUserWithEmailAndPassword(data);
if (user) {
toast.success("Successfully Registered");
}
console.log(data);
};
if(loading){
return <Loading></Loading>
}
return (
<section className="container mx-auto px-5 gap-5 md:px-12">
<form className="py-5 card" onSubmit={handleSubmit(onSubmit)}>
<div className="mt-5 mb-5">
<input
type="text"
className="input input-bordered py-5"
placeholder="Your Full Name"
{...register("name", {
required: { value: true, message: "Name is required" },
maxLength: 80,
pattern: {
value: /^[\w'\-,.][^0-9_!¡?÷?¿/\\+=##$%ˆ&*(){}|~<>;:[\]]{2,}$/,
message: `Don't use special characters`,
},
})}
/>
<br />
</div>
<div className="form-control w-full max-w-xs">
<label className="label">
<span className="label-text">Email</span>
</label>
<input
type="email"
placeholder="Your Email"
className="input input-bordered w-full max-w-xs"
{...register("email", {
required: {
value: true,
message: "Email is Required",
},
pattern: {
value: /[a-z0-9]+#[a-z]+\.[a-z]{2,3}/,
message: "Provide a valid Email",
},
})}
/>
<label className="label">
{errors.email?.type === "required" && (
<span className="label-text-alt text-red-500">
{errors.email.message}
</span>
)}
{errors.email?.type === "pattern" && (
<span className="label-text-alt text-red-500">
{errors.email.message}
</span>
)}
</label>
</div>
<div>
<input
type="password"
placeholder="Password"
className="input input-bordered"
{...register("password", {
required: {
value: true,
message: `Please provide a password between 6 to 30 character`,
},
})}
/>
<label className="label">
{errors.password?.type === "required" && (
<span className="label-text-alt text-red-500">
{errors.password.message}
</span>
)}
{errors.password?.type === "pattern" && (
<span className="label-text-alt text-red-500">
{errors.password.message}
</span>
)}
</label>
</div>
<input className="btn btn-primary" value="Register" type="submit" />
</form>
<GoogleLogin></GoogleLogin>
<div>
<Link className="btn btn-se" to="/login">
Login
</Link>
</div>
</section>
);
};
export default Signup;
So after submitting, I can see the data on console but can't send them to firebase.

How to Store Choose File Image to Local Storage with React Hooks

I am building a profile page but i have some problems with storing the profile image to browser local storage. I choose the file from my device and upload it. but when i refresh the page, it s gone.
below is my code below and also a visual of the page. the local storage function works for everything in the page except for the image. what is the problem here ?
If you can help i will be so glad.
useLocalStorage.js
import React from "react"
import { useState, useEffect } from "react";
function getStorageValue(key, defaultValue) {
// getting stored value
const saved = localStorage.getItem(key);
const initial = JSON.parse(saved);
return initial || defaultValue;
}
export const useLocalStorage = (key, defaultValue) => {
const [value, setValue] = useState(() => {
return getStorageValue(key, defaultValue);
});
useEffect(() => {
// storing input name
localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);
return [value, setValue];
};
formikData.js
import * as Yup from "yup";
const initialValues = {
fullname: "",
email: "",
phone: "",
bio: "",
city: "",
state: "",
street: "",
zip: "",
};
const yupValidation = {
phone: Yup.number().required("Phone is Required"),
bio: Yup.string().required("Bio is Required"),
city: Yup.string().required("City is Required"),
state: Yup.string().required("State is Required"),
street: Yup.string().required("Street is Required"),
};
export { initialValues, yupValidation };
PersonalDetails.js
import React, { useState, useEffect } from "react";
import { Col, Row, Container, Alert } from "react-bootstrap";
import poodle from "../../images/poodle.jpg";
import { Formik, Field, Form, ErrorMessage } from "formik";
import { initialValues, yupValidation } from "./formikData";
import * as Yup from "yup";
import cities from "../../data/cities";
import "./PersonalDetails.css";
import { useSelector } from "react-redux";
import { db } from "../../firebase";
import { useLocalStorage } from "./useLocalStorage";
import { useTranslation } from "react-i18next";
const PersonalDetails = () => {
const user = useSelector((state) => state.user);
const [fullname, setFullname] = useLocalStorage("fullname", "");
const [email, setEmail] = useLocalStorage("email", "");
const [bio, setBio] = useLocalStorage("bio", "")
const [phone, setPhone] = useLocalStorage("phone", "");
const [city, setCity] = useLocalStorage("city", "");
const [state, setState] = useLocalStorage("state", "");
const [street, setStreet] = useLocalStorage("street", "");
const [zip, setZip] = useLocalStorage("zip", "");
const [alertShown, isAlertShown] = useState(false);
const [picture, setPicture] = useLocalStorage("picture", poodle);
const onChangePicture = e => {
setPicture(URL.createObjectURL(e.target.files[0]));
};
const clearInfo = () => {
setBio("")
setPhone("")
setCity("")
setState("")
setStreet("")
setZip("")
setPicture("");
}
const fetchUserName = async () => {
try {
const query = await db
.collection("profile")
.where("uid", "==", user.uid)
.get();
const data = await query.docs[0].data();
setFullname(data.name);
setEmail(data.email);
} catch (err) {
console.error(err);
alert("An error occured while loading user data");
}
};
useEffect(() => {
if(user) fetchUserName();
}, [user]);
const { t } = useTranslation();
return (
<Container fluid className="mainContainer profile">
<Container className="pt-3 pb-4">
<Row>
<Col lg="4" md="12">
<div class="bgWhite fullHeight">
<img
src={picture}
alt=""
width="120"
height="120"
className="align-items-center mb-4 avatar"
/>
<input className="mb-5" id="profilePic" type="file" onChange={onChangePicture} />
<h5 className="mb-2 text-uppercase newColor">
{fullname}
</h5>
<p className="newColor">
{email}
</p>
<p className="profileInfo">
Tel: {''}
<span>{phone}</span>
</p>
<p className="profileInfo">
{t("personalPage.sideText0")} : {''}
<span>{city}</span>
</p>
<p className="profileInfo">
{t("personalPage.sideText1")} : {''}
<span>{state}</span>
</p>
<p className="profileInfo">
{t("personalPage.sideText2")} : {''}
<span>{street}</span>
</p>
<p className="profileInfo">
{t("personalPage.sideText3")} : {''}
<span>{zip}</span>
</p>
{bio && (
<h4 className="mb-2 mt-4 newColor">About</h4>
)}
<p className="profileInfo">
Bio: {''}
<span>{bio}</span>
</p>
</div>
</Col>
<Col lg="8" md="12" className="mt-lg-0 mt-5 formSection">
<div className="bgWhite personelInfo" align="left">
{alertShown && (
<Alert variant="success">{t("personalPage.alert0")}</Alert>
)}
<Formik
initialValues={initialValues}
validationSchema={Yup.object(yupValidation)}
onSubmit={(values, { setSubmitting }) => {
isAlertShown(true);
setFullname(values.fullname)
setEmail(values.email);
setBio(values.bio)
setPhone(values.phone)
setCity(values.city)
setState(values.state)
setStreet(values.street)
setZip(values.zip)
}}
>
{(props) => {
const { values } = props;
return (
<>
<Form>
<h3 className="newColor">{t("personalPage.title0")}</h3>
<div className="row d-flex justify-content-around mt-4">
</div>
<div className="row d-flex justify-content-around mt-4">
<div>
<Field
placeholder={t("personalPage.placeholder2")}
type="tel"
name="phone"
className="shadow inputStyle"
/>
<div className="error">
<ErrorMessage name="phone" />
</div>
</div>
<div>
<Field
placeholder={t("personalPage.placeholder3")}
name="bio"
as="textarea"
className="shadow inputStyle"
/>
<div className="error">
<ErrorMessage name="bio" />
</div>
</div>
</div>
<div className="mt-4">
<h3 className="newColor">{t("personalPage.title1")}</h3>
<div className="row d-flex justify-content-around mt-4 ">
<div>
<Field
component="select"
id="city"
name="city"
multiple={false}
className="shadow inputStyle"
>
<option value="">{t("personalPage.dropdown")}</option>
{cities.map((city) => {
return (
<option name="city">{city.name}</option>
);
})}
</Field>
<div className="error">
<ErrorMessage name="city" />
</div>
</div>
<div>
<Field
placeholder={t("personalPage.placeholder5")}
type="text"
name="state"
className="shadow inputStyle"
/>
<div className="error">
<ErrorMessage name="state" />
</div>
</div>
</div>
<div className="row d-flex justify-content-around mt-4 ">
<div>
<Field
placeholder={t("personalPage.placeholder6")}
type="text"
name="street"
className="shadow inputStyle"
/>
<div className="error">
<ErrorMessage name="street" />
</div>
</div>
<div>
<Field
placeholder={t("personalPage.placeholder7")}
type="text"
name="zip"
className="shadow inputStyle"
/>
<div className="error">
<ErrorMessage name="zip" />
</div>
</div>
</div>
<div className="row d-flex mt-5 justify-content-center">
<button
className="m-2 button"
type="submit"
>
{t("personalPage.button0")}{" "}
</button>
<button
className="m-2 button cancelBtn"
onClick={clearInfo}
type="button"
>
{t("personalPage.button1")}{" "}
</button>
</div>
</div>
</Form>
</>
);
}}
</Formik>
</div>
</Col>
</Row>
</Container>
</Container>
);
};
export default PersonalDetails;

Resources