- implement certifications section

This commit is contained in:
Amruth Pillai
2020-07-08 20:20:44 +05:30
parent c38788aa3b
commit 70866420e5
16 changed files with 129 additions and 139 deletions

View File

@ -6,6 +6,7 @@ import ModalContext from "../../../contexts/ModalContext";
import Button from "../../shared/Button"; import Button from "../../shared/Button";
import EmptyList from "./EmptyList"; import EmptyList from "./EmptyList";
import styles from "./List.module.css"; import styles from "./List.module.css";
import ListItem from "./ListItem";
const List = ({ const List = ({
path, path,
@ -17,7 +18,6 @@ const List = ({
text, text,
textPath, textPath,
event, event,
listItemComponent: ListItemComponent,
}) => { }) => {
const { emitter } = useContext(ModalContext); const { emitter } = useContext(ModalContext);
@ -39,7 +39,7 @@ const List = ({
<EmptyList /> <EmptyList />
) : ( ) : (
items.map((x, i) => ( items.map((x, i) => (
<ListItemComponent <ListItem
key={x.id} key={x.id}
data={x} data={x}
path={path} path={path}

View File

@ -2,10 +2,10 @@ import { Menu, MenuItem } from "@material-ui/core";
import React, { useContext, useState } from "react"; import React, { useContext, useState } from "react";
import { IoIosArrowDown, IoIosArrowUp } from "react-icons/io"; import { IoIosArrowDown, IoIosArrowUp } from "react-icons/io";
import { MdMoreVert } from "react-icons/md"; import { MdMoreVert } from "react-icons/md";
import ResumeContext from "../../../../contexts/ResumeContext"; import ResumeContext from "../../../contexts/ResumeContext";
import styles from "./TripleFieldListItem.module.css"; import styles from "./ListItem.module.css";
const TripleFieldListItem = ({ const ListItem = ({
title, title,
subtitle, subtitle,
text, text,
@ -67,9 +67,14 @@ const TripleFieldListItem = ({
<div className={styles.container}> <div className={styles.container}>
<div className="grid"> <div className="grid">
<span className="font-medium truncate">{title}</span> <span className="font-medium truncate">{title}</span>
<span className="mt-1 text-sm opacity-75 truncate">{subtitle}</span>
<span className="w-4/5 mt-5 text-sm opacity-75 truncate">{text}</span> {subtitle && (
<span className="mt-1 text-sm opacity-75 truncate">{subtitle}</span>
)}
{text && (
<span className="w-4/5 mt-5 text-sm opacity-75 truncate">{text}</span>
)}
</div> </div>
<div className={styles.menu}> <div className={styles.menu}>
@ -103,4 +108,4 @@ const TripleFieldListItem = ({
); );
}; };
export default TripleFieldListItem; export default ListItem;

View File

@ -1,103 +0,0 @@
import { Menu, MenuItem } from "@material-ui/core";
import React, { useContext, useState } from "react";
import { IoIosArrowDown, IoIosArrowUp } from "react-icons/io";
import { MdMoreVert } from "react-icons/md";
import ResumeContext from "../../../../contexts/ResumeContext";
import styles from "./DoubleFieldListItem.module.css";
const DoubleFieldListItem = ({
title,
subtitle,
path,
data,
isFirst,
isLast,
onEdit,
}) => {
const [anchorEl, setAnchorEl] = useState(null);
const { dispatch } = useContext(ResumeContext);
const handleClick = (event) => setAnchorEl(event.currentTarget);
const handleClose = () => setAnchorEl(null);
const handleEdit = () => {
onEdit();
handleClose();
};
const handleMoveUp = () => {
dispatch({
type: "on_move_item_up",
payload: {
path,
value: data,
},
});
handleClose();
};
const handleMoveDown = () => {
dispatch({
type: "on_move_item_down",
payload: {
path,
value: data,
},
});
handleClose();
};
const handleDelete = () => {
dispatch({
type: "on_delete_item",
payload: {
path,
value: data,
},
});
handleClose();
};
return (
<div className={styles.container}>
<div className="flex flex-col">
<span className="font-medium truncate">{title}</span>
<span className="mt-1 text-sm opacity-75 truncate">{subtitle}</span>
</div>
<div className={styles.menu}>
<MdMoreVert
size="18px"
aria-haspopup="true"
onClick={handleClick}
className="cursor-pointer"
/>
<Menu
keepMounted
anchorEl={anchorEl}
onClose={handleClose}
open={Boolean(anchorEl)}
>
<div className="flex items-center space-around">
<MenuItem disabled={isFirst} onClick={handleMoveUp}>
<IoIosArrowUp size="18px" />
</MenuItem>
<MenuItem disabled={isLast} onClick={handleMoveDown}>
<IoIosArrowDown size="18px" />
</MenuItem>
</div>
<MenuItem onClick={handleEdit}>Edit</MenuItem>
<MenuItem onClick={handleDelete}>
<span className="text-red-600 font-medium">Delete</span>
</MenuItem>
</Menu>
</div>
</div>
);
};
export default DoubleFieldListItem;

View File

@ -1,17 +0,0 @@
.container {
@apply flex items-center justify-between border-t border-secondary px-6 py-5;
}
.container:first-child {
@apply border-t-0;
}
.menu {
@apply opacity-0;
@apply transition-opacity duration-200 ease-in-out;
}
.container:hover .menu {
@apply opacity-100;
@apply transition-opacity duration-200 ease-in-out;
}

View File

@ -2,7 +2,6 @@ import { get } from "lodash";
import React from "react"; import React from "react";
import Heading from "../../shared/Heading"; import Heading from "../../shared/Heading";
import List from "../lists/List"; import List from "../lists/List";
import TripleFieldListItem from "../lists/triple/TripleFieldListItem";
const Awards = ({ id, name, event, state }) => { const Awards = ({ id, name, event, state }) => {
const path = `${id}.items`; const path = `${id}.items`;
@ -19,7 +18,6 @@ const Awards = ({ id, name, event, state }) => {
titlePath="title" titlePath="title"
subtitlePath="awarder" subtitlePath="awarder"
textPath="summary" textPath="summary"
listItemComponent={TripleFieldListItem}
/> />
</section> </section>
); );

View File

@ -0,0 +1,26 @@
import { get } from "lodash";
import React from "react";
import Heading from "../../shared/Heading";
import List from "../lists/List";
const Certifications = ({ id, name, event, state }) => {
const path = `${id}.items`;
const items = get(state, path, []);
return (
<section>
<Heading>{name}</Heading>
<List
path={path}
items={items}
event={event}
titlePath="title"
subtitlePath="issuer"
textPath="summary"
/>
</section>
);
};
export default Certifications;

View File

@ -2,7 +2,6 @@ import { get } from "lodash";
import React from "react"; import React from "react";
import Heading from "../../shared/Heading"; import Heading from "../../shared/Heading";
import List from "../lists/List"; import List from "../lists/List";
import TripleFieldListItem from "../lists/triple/TripleFieldListItem";
const Education = ({ id, name, event, state }) => { const Education = ({ id, name, event, state }) => {
const path = `${id}.items`; const path = `${id}.items`;
@ -18,7 +17,6 @@ const Education = ({ id, name, event, state }) => {
event={event} event={event}
titlePath="institution" titlePath="institution"
textPath="field" textPath="field"
listItemComponent={TripleFieldListItem}
/> />
</section> </section>
); );

View File

@ -1,7 +1,6 @@
import { get } from "lodash"; import { get } from "lodash";
import React from "react"; import React from "react";
import Heading from "../../shared/Heading"; import Heading from "../../shared/Heading";
import DoubleFieldListItem from "../lists/double/DoubleFieldListItem";
import List from "../lists/List"; import List from "../lists/List";
const Social = ({ id, name, event, state }) => { const Social = ({ id, name, event, state }) => {
@ -18,7 +17,6 @@ const Social = ({ id, name, event, state }) => {
event={event} event={event}
titlePath="network" titlePath="network"
subtitlePath="username" subtitlePath="username"
listItemComponent={DoubleFieldListItem}
/> />
</section> </section>
); );

View File

@ -2,7 +2,6 @@ import { get } from "lodash";
import React from "react"; import React from "react";
import Heading from "../../shared/Heading"; import Heading from "../../shared/Heading";
import List from "../lists/List"; import List from "../lists/List";
import TripleFieldListItem from "../lists/triple/TripleFieldListItem";
const Work = ({ id, name, event, state }) => { const Work = ({ id, name, event, state }) => {
const path = `${id}.items`; const path = `${id}.items`;
@ -18,7 +17,6 @@ const Work = ({ id, name, event, state }) => {
event={event} event={event}
titlePath="company" titlePath="company"
textPath="summary" textPath="summary"
listItemComponent={TripleFieldListItem}
/> />
</section> </section>
); );

View File

@ -5,6 +5,7 @@ const ModalEvents = {
WORK_MODAL: "work_modal", WORK_MODAL: "work_modal",
EDUCATION_MODAL: "education_modal", EDUCATION_MODAL: "education_modal",
AWARD_MODAL: "award_modal", AWARD_MODAL: "award_modal",
CERTIFICATION_MODAL: "certification_modal",
}; };
export default ModalEvents; export default ModalEvents;

View File

@ -1,8 +1,9 @@
import { AiOutlineTwitter } from "react-icons/ai"; import { AiFillSafetyCertificate, AiOutlineTwitter } from "react-icons/ai";
import { FaAward } from "react-icons/fa"; import { FaAward } from "react-icons/fa";
import { IoMdBriefcase, IoMdDocument } from "react-icons/io"; import { IoMdBriefcase, IoMdDocument } from "react-icons/io";
import { MdPerson, MdSchool } from "react-icons/md"; import { MdPerson, MdSchool } from "react-icons/md";
import Awards from "../components/builder/sections/Awards"; import Awards from "../components/builder/sections/Awards";
import Certifications from "../components/builder/sections/Certifications";
import Education from "../components/builder/sections/Education"; import Education from "../components/builder/sections/Education";
import Objective from "../components/builder/sections/Objective"; import Objective from "../components/builder/sections/Objective";
import Profile from "../components/builder/sections/Profile"; import Profile from "../components/builder/sections/Profile";
@ -51,4 +52,11 @@ export default [
component: Awards, component: Awards,
event: ModalEvents.AWARD_MODAL, event: ModalEvents.AWARD_MODAL,
}, },
{
id: "certifications",
name: "Certifications",
icon: AiFillSafetyCertificate,
component: Certifications,
event: ModalEvents.CERTIFICATION_MODAL,
},
]; ];

View File

@ -2,6 +2,7 @@ import React, { Fragment } from "react";
import AuthModal from "./AuthModal"; import AuthModal from "./AuthModal";
import ResumeModal from "./ResumeModal"; import ResumeModal from "./ResumeModal";
import AwardModal from "./sections/AwardModal"; import AwardModal from "./sections/AwardModal";
import CertificateModal from "./sections/CertificateModal";
import EducationModal from "./sections/EducationModal"; import EducationModal from "./sections/EducationModal";
import SocialModal from "./sections/SocialModal"; import SocialModal from "./sections/SocialModal";
import WorkModal from "./sections/WorkModal"; import WorkModal from "./sections/WorkModal";
@ -15,6 +16,7 @@ const ModalRegistrar = () => {
<WorkModal /> <WorkModal />
<EducationModal /> <EducationModal />
<AwardModal /> <AwardModal />
<CertificateModal />
</Fragment> </Fragment>
); );
}; };

View File

@ -36,8 +36,8 @@ const AwardModal = () => {
> >
{(formik) => ( {(formik) => (
<DataModal <DataModal
name="Award"
path="awards.items" path="awards.items"
name="Awards"
event={ModalEvents.AWARD_MODAL} event={ModalEvents.AWARD_MODAL}
> >
<div className="grid grid-cols-2 gap-8"> <div className="grid grid-cols-2 gap-8">

View File

@ -0,0 +1,76 @@
import { Formik } from "formik";
import { get } from "lodash";
import React from "react";
import * as Yup from "yup";
import Input from "../../components/shared/Input";
import ModalEvents from "../../constants/ModalEvents";
import DataModal from "../DataModal";
const initialValues = {
title: "",
issuer: "",
date: "",
summary: "",
};
const validationSchema = Yup.object().shape({
title: Yup.string().required("This is a required field."),
issuer: Yup.string().required("This is a required field."),
date: Yup.date().max(new Date()),
summary: Yup.string(),
});
const CertificateModal = () => {
const getFieldProps = (formik, name) => ({
touched: get(formik, `touched.${name}`, false),
error: get(formik, `errors.${name}`, ""),
isRequired: get(validationSchema, `fields.${name}._exclusive.required`),
...formik.getFieldProps(name),
});
return (
<Formik
validateOnBlur
initialValues={initialValues}
validationSchema={validationSchema}
>
{(formik) => (
<DataModal
name="Certificate"
path="certifications.items"
event={ModalEvents.CERTIFICATION_MODAL}
>
<div className="grid grid-cols-2 gap-8">
<Input
label="Title"
className="col-span-2"
placeholder="CCNP"
{...getFieldProps(formik, "title")}
/>
<Input
label="Issuer"
placeholder="Cisco Systems"
{...getFieldProps(formik, "issuer")}
/>
<Input
type="date"
label="Date"
{...getFieldProps(formik, "date")}
/>
<Input
type="textarea"
label="Summary"
className="col-span-2"
{...getFieldProps(formik, "summary")}
/>
</div>
</DataModal>
)}
</Formik>
);
};
export default CertificateModal;

View File

@ -51,8 +51,8 @@ const EducationModal = () => {
> >
{(formik) => ( {(formik) => (
<DataModal <DataModal
path="education.items"
name="Education" name="Education"
path="education.items"
event={ModalEvents.EDUCATION_MODAL} event={ModalEvents.EDUCATION_MODAL}
> >
<div className="grid grid-cols-2 gap-8"> <div className="grid grid-cols-2 gap-8">