diff --git a/src/components/LeftSidebar/tabs/Languages.js b/src/components/LeftSidebar/tabs/Languages.js
new file mode 100644
index 00000000..3a7f5bca
--- /dev/null
+++ b/src/components/LeftSidebar/tabs/Languages.js
@@ -0,0 +1,212 @@
+import React, { useState, useEffect, useContext } from 'react';
+import { v4 as uuidv4 } from 'uuid';
+import set from 'lodash/set';
+
+import TextField from '../../../shared/TextField';
+import AppContext from '../../../context/AppContext';
+import Checkbox from '../../../shared/Checkbox';
+import Counter from '../../../shared/Counter';
+import { addItem, deleteItem, moveItemUp, moveItemDown } from '../../../utils';
+
+const LanguagesTab = ({ data, onChange }) => {
+ const context = useContext(AppContext);
+ const { dispatch } = context;
+
+ useEffect(() => {
+ if (!('languages' in data)) {
+ dispatch({
+ type: 'migrate_section',
+ payload: {
+ key: 'languages',
+ value: {
+ enable: false,
+ heading: 'Languages',
+ items: [],
+ },
+ },
+ });
+
+ dispatch({ type: 'save_data' });
+ }
+ }, [data, dispatch]);
+
+ return (
+ 'languages' in data && (
+ <>
+
+
+ onChange('data.languages.enable', v)}
+ />
+
+
+ onChange('data.languages.heading', v)}
+ />
+
+
+
+
+
+ {data.languages.items.map((x, index) => (
+
+ ))}
+
+
+ >
+ )
+ );
+};
+
+const AddItem = ({ dispatch }) => {
+ const [isOpen, setOpen] = useState(false);
+ const [item, setItem] = useState({
+ id: uuidv4(),
+ key: '',
+ value: 1,
+ });
+
+ const onChange = (key, value) => setItem(items => set({ ...items }, key, value));
+
+ const onSubmit = () => {
+ if (item.key === '') return;
+
+ addItem(dispatch, 'languages', item);
+
+ setItem({
+ id: uuidv4(),
+ key: '',
+ value: 1,
+ });
+
+ setOpen(false);
+ };
+
+ return (
+
+
setOpen(!isOpen)}
+ >
+
Add Language
+ {isOpen ? 'expand_less' : 'expand_more'}
+
+
+
+
onChange('key', v)}
+ />
+
+ item.value > 1 && onChange('value', item.value - 1)}
+ onIncrement={() => item.value < 5 && onChange('value', item.value + 1)}
+ />
+
+
+
+
+ );
+};
+
+const Item = ({ item, index, onChange, dispatch, first, last }) => {
+ const [isOpen, setOpen] = useState(false);
+ const identifier = `data.languages.items[${index}]`;
+
+ return (
+
+
setOpen(!isOpen)}
+ >
+
{item.key}
+ {isOpen ? 'expand_less' : 'expand_more'}
+
+
+
+
onChange(`${identifier}.key`, v)}
+ />
+
+ item.value > 1 && onChange(`${identifier}.value`, item.value - 1)}
+ onIncrement={() => item.value < 5 && onChange(`${identifier}.value`, item.value + 1)}
+ />
+
+
+
+
+
+ {!first && (
+
+ )}
+
+ {!last && (
+
+ )}
+
+
+
+
+ );
+};
+
+export default LanguagesTab;
diff --git a/src/components/LeftSidebar/tabs/References.js b/src/components/LeftSidebar/tabs/References.js
new file mode 100644
index 00000000..ec1749e2
--- /dev/null
+++ b/src/components/LeftSidebar/tabs/References.js
@@ -0,0 +1,268 @@
+import React, { useState, useEffect, useContext } from 'react';
+import { v4 as uuidv4 } from 'uuid';
+import set from 'lodash/set';
+
+import TextField from '../../../shared/TextField';
+import TextArea from '../../../shared/TextArea';
+import AppContext from '../../../context/AppContext';
+import Checkbox from '../../../shared/Checkbox';
+import { addItem, deleteItem, moveItemUp, moveItemDown } from '../../../utils';
+
+const ReferencesTab = ({ data, onChange }) => {
+ const context = useContext(AppContext);
+ const { dispatch } = context;
+
+ useEffect(() => {
+ if (!('references' in data)) {
+ dispatch({
+ type: 'migrate_section',
+ payload: {
+ key: 'references',
+ value: {
+ enable: false,
+ heading: 'References',
+ items: [],
+ },
+ },
+ });
+
+ dispatch({ type: 'save_data' });
+ }
+ }, [data, dispatch]);
+
+ return (
+ 'references' in data && (
+ <>
+
+
+ onChange('data.references.enable', v)}
+ />
+
+
+ onChange('data.references.heading', v)}
+ />
+
+
+
+
+
+ {data.references.items.map((x, index) => (
+
+ ))}
+
+
+ >
+ )
+ );
+};
+
+const AddItem = ({ dispatch }) => {
+ const [isOpen, setOpen] = useState(false);
+ const [item, setItem] = useState({
+ id: uuidv4(),
+ name: '',
+ position: '',
+ phone: '',
+ email: '',
+ description: '',
+ });
+
+ const onChange = (key, value) => setItem(set({ ...item }, key, value));
+
+ const onSubmit = () => {
+ if (item.name === '' || item.position === '') return;
+
+ addItem(dispatch, 'references', item);
+
+ setItem({
+ id: uuidv4(),
+ name: '',
+ position: '',
+ phone: '',
+ email: '',
+ description: '',
+ });
+
+ setOpen(false);
+ };
+
+ return (
+
+
setOpen(!isOpen)}
+ >
+
Add Reference
+ {isOpen ? 'expand_less' : 'expand_more'}
+
+
+
+
onChange('name', v)}
+ />
+
+ onChange('position', v)}
+ />
+
+ onChange('phone', v)}
+ />
+
+ onChange('email', v)}
+ />
+
+
+
+ );
+};
+
+const Item = ({ item, index, onChange, dispatch, first, last }) => {
+ const [isOpen, setOpen] = useState(false);
+ const identifier = `data.references.items[${index}]`;
+
+ return (
+
+
setOpen(!isOpen)}
+ >
+
{item.name}
+ {isOpen ? 'expand_less' : 'expand_more'}
+
+
+
+
onChange(`${identifier}.name`, v)}
+ />
+
+ onChange(`${identifier}.position`, v)}
+ />
+
+ onChange(`${identifier}.phone`, v)}
+ />
+
+ onChange(`${identifier}.email`, v)}
+ />
+
+
+
+ );
+};
+
+export default ReferencesTab;
diff --git a/src/components/LeftSidebar/tabs/Skills.js b/src/components/LeftSidebar/tabs/Skills.js
index 39aea3ea..08ada187 100644
--- a/src/components/LeftSidebar/tabs/Skills.js
+++ b/src/components/LeftSidebar/tabs/Skills.js
@@ -3,6 +3,7 @@ import React, { useState, useContext } from 'react';
import AppContext from '../../../context/AppContext';
import Checkbox from '../../../shared/Checkbox';
import TextField from '../../../shared/TextField';
+import { addItem, deleteItem } from '../../../utils';
const SkillsTab = ({ data, onChange }) => {
const context = useContext(AppContext);
@@ -29,7 +30,7 @@ const SkillsTab = ({ data, onChange }) => {
{data.skills.items.map((x, index) => (
-
+
))}
@@ -41,16 +42,10 @@ const AddItem = ({ dispatch }) => {
const [isOpen, setOpen] = useState(false);
const [item, setItem] = useState('');
- const addItem = () => {
+ const add = () => {
if (item === '') return;
- dispatch({
- type: 'add_item',
- payload: {
- key: 'skills',
- value: item,
- },
- });
+ addItem(dispatch, 'skills', item);
setItem('');
};
@@ -79,7 +74,7 @@ const AddItem = ({ dispatch }) => {