- 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

@ -12,9 +12,9 @@ const LeftSidebar = () => {
<LeftNavbar />
<div className={styles.container}>
{sections.map(({ id, component: Component }) => (
{sections.map(({ id, name, event, component: Component }) => (
<Fragment key={id}>
<Component state={state} />
<Component id={id} name={name} event={event} state={state} />
<hr />
</Fragment>
))}

View File

@ -1,6 +1,12 @@
.container {
z-index: 10;
box-shadow: var(--left-shadow);
-ms-overflow-style: none;
scrollbar-width: none;
@apply w-full h-screen overflow-scroll p-8;
@apply grid gap-6;
}
.container::-webkit-scrollbar {
display: none;
}

View File

@ -1,9 +1,7 @@
import React from "react";
const EmptyList = () => (
<div className="rounded border border-secondary py-6 text-center">
This list is empty.
</div>
<div className="py-6 opacity-75 text-center">This list is empty.</div>
);
export default EmptyList;

View File

@ -1,22 +1,67 @@
import { isEmpty } from "lodash";
import React from "react";
import { get, isEmpty } from "lodash";
import moment from "moment";
import React, { useContext } from "react";
import { MdAdd } from "react-icons/md";
import ModalContext from "../../../contexts/ModalContext";
import Button from "../../shared/Button";
import EmptyList from "./EmptyList";
import styles from "./List.module.css";
const List = ({ items, onAdd, children }) => {
const List = ({
path,
items,
title,
titlePath,
subtitle,
subtitlePath,
text,
textPath,
event,
listItemComponent: ListItemComponent,
}) => {
const { emitter } = useContext(ModalContext);
const handleAdd = () => emitter.emit(event);
const handleEdit = (data) => emitter.emit(event, data);
const formatDateRange = (x) =>
`${moment(x.startDate).format("MMMM Y")}${
moment(x.endDate).isValid()
? moment(x.endDate).format("MMMM Y")
: "Present"
}`;
return (
<div className="flex flex-col">
<div className={styles.container}>
{isEmpty(items) ? <EmptyList /> : children}
<div className={styles.list}>
{isEmpty(items) ? (
<EmptyList />
) : (
items.map((x, i) => (
<ListItemComponent
key={x.id}
data={x}
path={path}
title={title || get(x, titlePath, "")}
subtitle={
subtitle || get(x, subtitlePath, "") || formatDateRange(x)
}
text={text || get(x, textPath, "")}
className={styles.listItem}
onEdit={() => handleEdit(x)}
isFirst={i === 0}
isLast={i === items.length - 1}
/>
))
)}
</div>
<Button
outline
icon={MdAdd}
title="Add New"
onClick={onAdd}
onClick={handleAdd}
className="mt-8 ml-auto"
/>
</div>

View File

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

View File

@ -3,9 +3,9 @@ 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 "./SmallListItem.module.css";
import styles from "./DoubleFieldListItem.module.css";
const SmallListItem = ({
const DoubleFieldListItem = ({
title,
subtitle,
path,
@ -100,4 +100,4 @@ const SmallListItem = ({
);
};
export default SmallListItem;
export default DoubleFieldListItem;

View File

@ -0,0 +1,106 @@
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 "./TripleFieldListItem.module.css";
const TripleFieldListItem = ({
title,
subtitle,
text,
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="grid">
<span className="font-medium">{title}</span>
<span className="mt-1 text-sm opacity-75">{subtitle}</span>
<span className="w-4/5 mt-6 text-sm opacity-75 truncate">{text}</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 TripleFieldListItem;

View File

@ -0,0 +1,17 @@
.container {
@apply flex items-center justify-between border-t border-secondary px-8 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

@ -8,6 +8,7 @@ const RightSidebar = () => {
<div className="flex">
<div className={styles.container}>
<Layout />
<hr />
</div>
<RightNavbar />

View File

@ -1,5 +1,12 @@
.container {
z-index: 10;
box-shadow: var(--right-shadow);
@apply w-full h-screen p-8;
-ms-overflow-style: none;
scrollbar-width: none;
@apply w-full h-screen overflow-scroll p-8;
@apply grid gap-6;
}
.container::-webkit-scrollbar {
display: none;
}

View File

@ -0,0 +1,27 @@
import { get } from "lodash";
import React from "react";
import Heading from "../../shared/Heading";
import List from "../lists/List";
import TripleFieldListItem from "../lists/triple/TripleFieldListItem";
const Education = ({ 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="institution"
textPath="field"
listItemComponent={TripleFieldListItem}
/>
</section>
);
};
export default Education;

View File

@ -31,7 +31,11 @@ const Layout = () => {
Block {ind + 1}
</span>
{el.map((item, index) => (
<Draggable key={item} draggableId={item} index={index}>
<Draggable
key={item.id}
draggableId={item.id}
index={index}
>
{(provided) => (
<div
ref={provided.innerRef}
@ -39,7 +43,7 @@ const Layout = () => {
{...provided.draggableProps}
{...provided.dragHandleProps}
>
{item}
{item.name}
</div>
)}
</Draggable>

View File

@ -0,0 +1,15 @@
import React from "react";
import Heading from "../../shared/Heading";
import Input from "../../shared/Input";
const Objective = () => {
return (
<section>
<Heading>Objective</Heading>
<Input type="textarea" label="Objective" path="objective" />
</section>
);
};
export default Objective;

View File

@ -1,38 +1,25 @@
import { get } from "lodash";
import React, { useContext } from "react";
import ModalContext from "../../../contexts/ModalContext";
import React from "react";
import Heading from "../../shared/Heading";
import DoubleFieldListItem from "../lists/double/DoubleFieldListItem";
import List from "../lists/List";
import SmallListItem from "../lists/small/SmallListItem";
const Social = ({ state }) => {
const { emitter, events } = useContext(ModalContext);
const path = "social.items";
const Social = ({ id, name, event, state }) => {
const path = `${id}.items`;
const items = get(state, path, []);
const handleAdd = () => emitter.emit(events.SOCIAL_MODAL);
const handleEdit = (data) => emitter.emit(events.SOCIAL_MODAL, data);
return (
<section>
<Heading>Social Network</Heading>
<Heading>{name}</Heading>
<List items={items} onAdd={handleAdd}>
{items.map((x, i) => (
<SmallListItem
key={x.id}
data={x}
path={path}
title={x.network}
isFirst={i === 0}
subtitle={x.username}
onEdit={() => handleEdit(x)}
isLast={i === items.length - 1}
/>
))}
</List>
<List
path={path}
items={items}
event={event}
titlePath="network"
subtitlePath="username"
listItemComponent={DoubleFieldListItem}
/>
</section>
);
};

View File

@ -0,0 +1,27 @@
import { get } from "lodash";
import React from "react";
import Heading from "../../shared/Heading";
import List from "../lists/List";
import TripleFieldListItem from "../lists/triple/TripleFieldListItem";
const Work = ({ 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="company"
textPath="summary"
listItemComponent={TripleFieldListItem}
/>
</section>
);
};
export default Work;