- implement work experience

- implement education
- show dynamic names in layout
This commit is contained in:
Amruth Pillai
2020-07-08 16:49:26 +05:30
parent bee6a40e9f
commit 922db70107
33 changed files with 822 additions and 169 deletions

View File

@ -5,6 +5,7 @@ import { isFunction } from "lodash";
import React, { forwardRef, useImperativeHandle } from "react";
import { MdClose } from "react-icons/md";
import Button from "../components/shared/Button";
import { handleKeyDown } from "../utils";
import styles from "./BaseModal.module.css";
const BaseModal = forwardRef(
@ -33,7 +34,12 @@ const BaseModal = forwardRef(
<div className={styles.modal}>
<div className={styles.title}>
<h2>{title}</h2>
<MdClose size="18" onClick={handleClose} />
<MdClose
size="18"
tabIndex="0"
onClick={handleClose}
onKeyDown={(e) => handleKeyDown(e, handleClose)}
/>
</div>
<div className={styles.body}>{children}</div>

View File

@ -1,3 +1,4 @@
import { useFormikContext } from "formik";
import { isEmpty, isFunction } from "lodash";
import React, { useContext, useEffect, useRef, useState } from "react";
import { v4 as uuidv4 } from "uuid";
@ -12,7 +13,6 @@ const DataModal = ({
path,
event,
title,
formik,
onEdit,
onCreate,
children,
@ -25,6 +25,7 @@ const DataModal = ({
const { emitter } = useContext(ModalContext);
const { dispatch } = useContext(ResumeContext);
const { values, setValues, resetForm, validateForm } = useFormikContext();
useEffect(() => {
const unbind = emitter.on(event, (data) => {
@ -36,12 +37,12 @@ const DataModal = ({
}, [emitter, event]);
useEffect(() => {
data && formik.setValues(data) && setEditMode(true);
data && setValues(data) && setEditMode(true);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [data]);
const onSubmit = async (newData) => {
if (isEmpty(await formik.validateForm(newData))) {
if (isEmpty(await validateForm(newData))) {
if (isEditMode) {
if (data !== newData) {
isFunction(onEdit)
@ -79,15 +80,11 @@ const DataModal = ({
: title.create;
const submitAction = (
<Button
type="submit"
title={getTitle}
onClick={() => onSubmit(formik.values)}
/>
<Button type="submit" title={getTitle} onClick={() => onSubmit(values)} />
);
const onDestroy = () => {
formik.resetForm();
resetForm();
setEditMode(false);
setData(null);
};

View File

@ -1,7 +1,9 @@
import React, { Fragment } from "react";
import AuthModal from "./AuthModal";
import ResumeModal from "./ResumeModal";
import EducationModal from "./sections/EducationModal";
import SocialModal from "./sections/SocialModal";
import WorkModal from "./sections/WorkModal";
const ModalRegistrar = () => {
return (
@ -9,6 +11,8 @@ const ModalRegistrar = () => {
<AuthModal />
<ResumeModal />
<SocialModal />
<WorkModal />
<EducationModal />
</Fragment>
);
};

View File

@ -1,4 +1,5 @@
import { useFormik } from "formik";
import { Formik } from "formik";
import { get } from "lodash";
import React, { useContext } from "react";
import * as Yup from "yup";
import Input from "../components/shared/Input";
@ -20,44 +21,45 @@ const ResumeModal = () => {
const { events } = useContext(ModalContext);
const { createResume, updateResume } = useContext(DatabaseContext);
const formik = useFormik({
initialValues,
validationSchema,
});
const getFieldProps = (name) => ({
const getFieldProps = (formik, name) => ({
touched: get(formik, `touched.${name}`, false),
error: get(formik, `errors.${name}`, ""),
...formik.getFieldProps(name),
error: formik.errors[name],
});
return (
<DataModal
name="Resume"
formik={formik}
title={{
create: "Create Resume",
edit: "Edit Resume",
}}
onEdit={updateResume}
onCreate={createResume}
event={events.CREATE_RESUME_MODAL}
<Formik
validateOnBlur
initialValues={initialValues}
validationSchema={validationSchema}
>
<Input
type="text"
name="name"
label="Name"
className="mb-8"
placeholder="Full Stack Web Developer"
{...getFieldProps("name")}
/>
{(formik) => (
<DataModal
name="Resume"
title={{
create: "Create Resume",
edit: "Edit Resume",
}}
onEdit={updateResume}
onCreate={createResume}
event={events.CREATE_RESUME_MODAL}
>
<Input
label="Name"
className="mb-8"
placeholder="Full Stack Web Developer"
{...getFieldProps(formik, "name")}
/>
<p>
You are going to be creating a new resume from scratch, but first, let's
give it a name. This can be the name of the role you want to apply for,
or if you're making a resume for a friend, you could call it Alex's
Resume.
</p>
</DataModal>
<p>
You are going to be creating a new resume from scratch, but first,
let's give it a name. This can be the name of the role you want to
apply for, or if you're making a resume for a friend, you could call
it Alex's Resume.
</p>
</DataModal>
)}
</Formik>
);
};

View File

@ -0,0 +1,154 @@
import { Field, FieldArray, Formik } from "formik";
import { get } from "lodash";
import React, { useContext } from "react";
import { MdAdd } from "react-icons/md";
import * as Yup from "yup";
import Input from "../../components/shared/Input";
import ModalContext from "../../contexts/ModalContext";
import { handleKeyDown } from "../../utils";
import DataModal from "../DataModal";
const initialValues = {
institution: "",
field: "",
degree: "",
gpa: "",
startDate: "",
endDate: "",
courses: [],
__temp: "",
};
const validationSchema = Yup.object().shape({
institution: Yup.string().required("This is a required field."),
field: Yup.string().required("This is a required field."),
degree: Yup.string(),
gpa: Yup.string(),
startDate: Yup.date().required("This is a required field."),
endDate: Yup.date().when(
"startDate",
(startDate, schema) =>
startDate &&
schema.min(startDate, "End Date must be later than Start Date")
),
courses: Yup.array().of(Yup.string().required("This is a required field.")),
__temp: Yup.string().ensure(),
});
const EducationModal = () => {
const { events } = useContext(ModalContext);
const getFieldProps = (formik, name) => ({
touched: get(formik, `touched.${name}`, false),
error: get(formik, `errors.${name}`, ""),
...formik.getFieldProps(name),
});
return (
<Formik
validateOnBlur
initialValues={initialValues}
validationSchema={validationSchema}
>
{(formik) => (
<DataModal
path="education.items"
name="Education"
event={events.EDUCATION_MODAL}
>
<div className="grid grid-cols-2 gap-8">
<Input
label="Institution"
className="col-span-2"
placeholder="Dayananda Sagar College of Engineering"
{...getFieldProps(formik, "institution")}
/>
<Input
label="Field of Study"
className="col-span-2"
placeholder="Computer Science &amp; Engineering"
{...getFieldProps(formik, "field")}
/>
<Input
label="Degree Type"
placeholder="Bachelor's Degree"
{...getFieldProps(formik, "degree")}
/>
<Input
label="GPA"
placeholder="8.8"
{...getFieldProps(formik, "gpa")}
/>
<Input
type="date"
label="Start Date"
placeholder="6th August 208"
{...getFieldProps(formik, "startDate")}
/>
<Input
type="date"
label="End Date"
placeholder="6th August 208"
{...getFieldProps(formik, "endDate")}
/>
<FieldArray
name="courses"
render={(arrayHelpers) => {
const handleClickAdd = () => {
formik.values.__temp &&
arrayHelpers.push(formik.values.__temp);
formik.setFieldValue("__temp", "");
};
return (
<div className="col-span-2">
<label>
<span>Courses</span>
{formik.values.courses &&
formik.values.courses.map((x, i) => (
<Field key={i} name={`courses.${i}`}>
{({ field, meta }) => (
<Input
className="my-1"
showDeleteItemButton
onDeleteItem={() => arrayHelpers.remove(i)}
{...field}
{...meta}
/>
)}
</Field>
))}
<div className="flex items-center">
<Input
placeholder="Algorithms &amp; Data Structures"
{...getFieldProps(formik, "__temp")}
/>
<MdAdd
size="18px"
tabIndex="0"
className="mx-4 cursor-pointer opacity-50 hover:opacity-75"
onKeyDown={(e) => handleKeyDown(e, handleClickAdd)}
onClick={handleClickAdd}
/>
</div>
</label>
</div>
);
}}
/>
</div>
</DataModal>
)}
</Formik>
);
};
export default EducationModal;

View File

@ -1,4 +1,5 @@
import { useFormik } from "formik";
import { Formik } from "formik";
import { get } from "lodash";
import React, { useContext } from "react";
import * as Yup from "yup";
import Input from "../../components/shared/Input";
@ -25,52 +26,47 @@ const validationSchema = Yup.object().shape({
const SocialModal = () => {
const { events } = useContext(ModalContext);
const formik = useFormik({
initialValues,
validationSchema,
validateOnBlur: true,
});
const getFieldProps = (name) => ({
const getFieldProps = (formik, name) => ({
touched: get(formik, `touched.${name}`, false),
error: get(formik, `errors.${name}`, ""),
...formik.getFieldProps(name),
touched: formik.touched[name],
error: formik.errors[name],
});
return (
<DataModal
formik={formik}
path="social.items"
name="Social Network"
event={events.SOCIAL_MODAL}
<Formik
validateOnBlur
initialValues={initialValues}
validationSchema={validationSchema}
>
<div className="grid grid-cols-2 gap-8">
<Input
type="text"
name="network"
label="Network"
placeholder="Twitter"
{...getFieldProps("network")}
/>
{(formik) => (
<DataModal
path="social.items"
name="Social Network"
event={events.SOCIAL_MODAL}
>
<div className="grid grid-cols-2 gap-8">
<Input
label="Network"
placeholder="Twitter"
{...getFieldProps(formik, "network")}
/>
<Input
type="text"
name="username"
label="Username"
placeholder="KingOKings"
{...getFieldProps("username")}
/>
<Input
label="Username"
placeholder="KingOKings"
{...getFieldProps(formik, "username")}
/>
<Input
type="text"
name="url"
label="URL"
className="col-span-2"
placeholder="https://twitter.com/KingOKings"
{...getFieldProps("url")}
/>
</div>
</DataModal>
<Input
label="URL"
className="col-span-2"
placeholder="https://twitter.com/KingOKings"
{...getFieldProps(formik, "url")}
/>
</div>
</DataModal>
)}
</Formik>
);
};

View File

@ -0,0 +1,156 @@
import { Field, FieldArray, Formik } from "formik";
import { get } from "lodash";
import React, { useContext } from "react";
import { MdAdd } from "react-icons/md";
import * as Yup from "yup";
import Input from "../../components/shared/Input";
import ModalContext from "../../contexts/ModalContext";
import { handleKeyDown } from "../../utils";
import DataModal from "../DataModal";
const initialValues = {
company: "",
position: "",
website: "https://",
startDate: "",
endDate: "",
summary: "",
highlights: [],
__temp: "",
};
const validationSchema = Yup.object().shape({
company: Yup.string().required("This is a required field."),
position: Yup.string().required("This is a required field."),
website: Yup.string().url("Must be a valid URL"),
startDate: Yup.date().required("This is a required field."),
endDate: Yup.date().when(
"startDate",
(startDate, schema) =>
startDate &&
schema.min(startDate, "End Date must be later than Start Date")
),
summary: Yup.string().min(10, "Please enter at least 10 characters."),
highlights: Yup.array().of(
Yup.string().required("This is a required field.")
),
__temp: Yup.string().ensure(),
});
const WorkModal = () => {
const { events } = useContext(ModalContext);
const getFieldProps = (formik, name) => ({
touched: get(formik, `touched.${name}`, false),
error: get(formik, `errors.${name}`, ""),
...formik.getFieldProps(name),
});
return (
<Formik
validateOnBlur
initialValues={initialValues}
validationSchema={validationSchema}
>
{(formik) => (
<DataModal
path="work.items"
name="Work Experience"
event={events.WORK_MODAL}
>
<div className="grid grid-cols-2 gap-8">
<Input
label="Company"
className="col-span-2"
placeholder="Postdot Technologies Pvt. Ltd."
{...getFieldProps(formik, "company")}
/>
<Input
label="Position"
placeholder="Full Stack Web Developer"
{...getFieldProps(formik, "position")}
/>
<Input
label="Website"
placeholder="https://example.com/"
{...getFieldProps(formik, "website")}
/>
<Input
type="date"
label="Start Date"
placeholder="6th August 208"
{...getFieldProps(formik, "startDate")}
/>
<Input
type="date"
label="End Date"
placeholder="6th August 208"
{...getFieldProps(formik, "endDate")}
/>
<Input
type="textarea"
label="Summary"
className="col-span-2"
{...getFieldProps(formik, "summary")}
/>
<FieldArray
name="highlights"
render={(arrayHelpers) => {
const handleClickAdd = () => {
formik.values.__temp &&
arrayHelpers.push(formik.values.__temp);
formik.setFieldValue("__temp", "");
};
return (
<div className="col-span-2">
<label>
<span>Highlights</span>
{formik.values.highlights &&
formik.values.highlights.map((x, i) => (
<Field key={i} name={`highlights.${i}`}>
{({ field, meta }) => (
<Input
className="my-1"
showDeleteItemButton
onDeleteItem={() => arrayHelpers.remove(i)}
{...field}
{...meta}
/>
)}
</Field>
))}
<div className="flex items-center">
<Input
placeholder="Worked passionately in customer service in a high volume restaurant."
{...getFieldProps(formik, "__temp")}
/>
<MdAdd
size="18px"
tabIndex="0"
className="mx-4 cursor-pointer opacity-50 hover:opacity-75"
onKeyDown={(e) => handleKeyDown(e, handleClickAdd)}
onClick={handleClickAdd}
/>
</div>
</label>
</div>
);
}}
/>
</div>
</DataModal>
)}
</Formik>
);
};
export default WorkModal;