mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2025-11-14 00:32:35 +10:00
implement functionality to hide/show individual items
This commit is contained in:
@ -21,6 +21,7 @@
|
||||
"jsx-a11y/label-has-associated-control": 0,
|
||||
"react/jsx-filename-extension": 0,
|
||||
"react/no-array-index-key": 0,
|
||||
"no-restricted-syntax": 0,
|
||||
"no-param-reassign": 0,
|
||||
"react/prop-types": 0,
|
||||
"no-plusplus": 0
|
||||
|
||||
@ -30,7 +30,9 @@
|
||||
"role": "Customer Service Representative",
|
||||
"start": "Jan 2013",
|
||||
"end": "July 2018",
|
||||
"description": "- Organized customer information and account data for business planning and customer service purposes.\n- Created excel spreadsheets to track customer data and perform intense reconciliation process.\n- Received 97% positive customer survey results.\n- Speed on calls was 10% above team average. \n**Key Achievement:** Designed and executed an automatized system for following up with customers, increasing customer retention by 22%."
|
||||
"description": "- Organized customer information and account data for business planning and customer service purposes.\n- Created excel spreadsheets to track customer data and perform intense reconciliation process.\n- Received 97% positive customer survey results.\n- Speed on calls was 10% above team average. \n**Key Achievement:** Designed and executed an automatized system for following up with customers, increasing customer retention by 22%.",
|
||||
"enabled": true,
|
||||
"enable": true
|
||||
},
|
||||
{
|
||||
"id": "bd8649f2-42d1-4424-acaf-a02c08c3322c",
|
||||
@ -38,7 +40,9 @@
|
||||
"role": "Customer Service Representative",
|
||||
"start": "Oct 2009",
|
||||
"end": "Dec 2012",
|
||||
"description": "- Worked as a full time customer service rep in a high volume call center.\n- Received \"Associate of the Month\" award six times.\n- Chosen as an example for other associates in trainings. \n**Key Achievement:** Received Customer Appreciation bonus in three of four years."
|
||||
"description": "- Worked as a full time customer service rep in a high volume call center.\n- Received \"Associate of the Month\" award six times.\n- Chosen as an example for other associates in trainings. \n**Key Achievement:** Received Customer Appreciation bonus in three of four years.",
|
||||
"enabled": true,
|
||||
"enable": true
|
||||
},
|
||||
{
|
||||
"id": "dde47711-a7a6-424f-9751-73483a0ef4ed",
|
||||
@ -46,7 +50,9 @@
|
||||
"role": "Waitress",
|
||||
"start": "Aug 2005",
|
||||
"end": "Sep 2009",
|
||||
"description": "- Worked passionately in customer service in a high volume restaurant.\n- Completed the FAST customer service training class.\n- Maintained a high tip average thanks to consistent customer satisfaction."
|
||||
"description": "- Worked passionately in customer service in a high volume restaurant.\n- Completed the FAST customer service training class.\n- Maintained a high tip average thanks to consistent customer satisfaction.",
|
||||
"enabled": true,
|
||||
"enable": true
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -61,7 +67,9 @@
|
||||
"start": "Sep 2001",
|
||||
"end": "Aug 2002",
|
||||
"grade": "",
|
||||
"description": ""
|
||||
"description": "",
|
||||
"enabled": true,
|
||||
"enable": true
|
||||
},
|
||||
{
|
||||
"id": "71a9852f-ed14-4281-bff2-4db9a2275978",
|
||||
@ -70,7 +78,9 @@
|
||||
"start": "Sep 1997",
|
||||
"end": "Aug 2001",
|
||||
"grade": "",
|
||||
"description": ""
|
||||
"description": "",
|
||||
"enabled": true,
|
||||
"enable": true
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -82,19 +92,22 @@
|
||||
"id": "121f0976-18cb-4e46-921d-0e156b6bf7fb",
|
||||
"title": "Cast Member of a Musical - Oklahoma",
|
||||
"subtitle": "Winter, 2007",
|
||||
"description": ""
|
||||
"description": "",
|
||||
"enable": true
|
||||
},
|
||||
{
|
||||
"id": "e5f27346-72ad-4d4f-bab3-726a111e4932",
|
||||
"title": "Class Representative to ASB",
|
||||
"subtitle": "Fall, 2008",
|
||||
"description": ""
|
||||
"description": "",
|
||||
"enable": true
|
||||
},
|
||||
{
|
||||
"id": "f71ba9bc-8c14-46b5-99dd-e1333e9aceb9",
|
||||
"title": "Most Improved - Varsity Soccer",
|
||||
"subtitle": "Fall, 2007",
|
||||
"description": ""
|
||||
"description": "",
|
||||
"enable": true
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -106,19 +119,22 @@
|
||||
"id": "e5170d99-b21d-4131-a7dc-26a4670037f5",
|
||||
"title": "CCNP",
|
||||
"subtitle": "Cisco Systems",
|
||||
"description": ""
|
||||
"description": "",
|
||||
"enable": true
|
||||
},
|
||||
{
|
||||
"id": "788e4042-9ecb-40c5-849d-7688b4e23888",
|
||||
"title": "VCP6-DCV",
|
||||
"subtitle": "VMWare",
|
||||
"description": ""
|
||||
"description": "",
|
||||
"enable": true
|
||||
},
|
||||
{
|
||||
"id": "97a1a8d9-3c03-47fb-93ab-e84f864ffe17",
|
||||
"title": "DCUCI Exam",
|
||||
"subtitle": "",
|
||||
"description": ""
|
||||
"description": "",
|
||||
"enable": true
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -141,22 +157,26 @@
|
||||
{
|
||||
"id": "9d34cfcb-c9f0-4d25-ab27-cf81652dd1d0",
|
||||
"key": "English (US)",
|
||||
"value": 5
|
||||
"value": 5,
|
||||
"enable": true
|
||||
},
|
||||
{
|
||||
"id": "3511a86b-7ea9-44ac-8144-6acc7f3bd54f",
|
||||
"key": "Spanish",
|
||||
"value": 4
|
||||
"value": 4,
|
||||
"enable": true
|
||||
},
|
||||
{
|
||||
"id": "d1e17542-f7cc-473a-aa0e-978765907454",
|
||||
"key": "French",
|
||||
"value": 4
|
||||
"value": 4,
|
||||
"enable": true
|
||||
},
|
||||
{
|
||||
"id": "b1e8442a-7059-4c6f-8a9c-415383133b0e",
|
||||
"key": "German",
|
||||
"value": 3
|
||||
"value": 3,
|
||||
"enable": true
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -170,7 +190,8 @@
|
||||
"position": "Head of HR, Carson Logistics",
|
||||
"phone": "+1 661-808-4188",
|
||||
"email": "l.beasley@carsonlogistics.com",
|
||||
"description": ""
|
||||
"description": "",
|
||||
"enable": true
|
||||
},
|
||||
{
|
||||
"id": "62fd3293-0e93-4242-882b-ae19b7865fef",
|
||||
@ -178,7 +199,8 @@
|
||||
"position": "Assistant Manager, Bullseye",
|
||||
"phone": "+1 661-808-4188",
|
||||
"email": "mikhail@bullseyemart.nyc",
|
||||
"description": ""
|
||||
"description": "",
|
||||
"enable": true
|
||||
},
|
||||
{
|
||||
"id": "eaab2e32-8591-497c-8676-d122cf3a4798",
|
||||
@ -186,7 +208,8 @@
|
||||
"position": "CEO , DownToPlay",
|
||||
"phone": "+1 661-808-4188",
|
||||
"email": "k.rose@downtoplay.xyz",
|
||||
"description": ""
|
||||
"description": "",
|
||||
"enable": true
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -197,28 +220,45 @@
|
||||
{
|
||||
"id": "3834a270-2c01-4105-b670-80863c955347",
|
||||
"key": "Skype",
|
||||
"value": "@NancyJack5436"
|
||||
"value": "@NancyJack5436",
|
||||
"enable": true
|
||||
},
|
||||
{
|
||||
"id": "b0c4fd85-cfda-421e-bd31-008b9aad1dfe",
|
||||
"key": "Hometown",
|
||||
"value": "New Jersey, NY"
|
||||
"value": "New Jersey, NY",
|
||||
"enable": true
|
||||
},
|
||||
{
|
||||
"id": "7f0a4971-9770-4ca7-b135-2b0ccd867879",
|
||||
"key": "Hobbies",
|
||||
"value": "Playing Soccer & Guitar"
|
||||
"value": "Playing Soccer & Guitar",
|
||||
"enable": true
|
||||
},
|
||||
{
|
||||
"id": "e17552a2-e7e9-4605-8145-795e2b62c30e",
|
||||
"key": "Valid Work Visas",
|
||||
"value": "US, UK, EU"
|
||||
"value": "US, UK, EU",
|
||||
"enable": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"languages": {
|
||||
"items": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
{
|
||||
"items": []
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"theme": {
|
||||
"layout": "Pikachu",
|
||||
"layout": "Gengar",
|
||||
"font": {
|
||||
"family": "Montserrat"
|
||||
},
|
||||
|
||||
@ -7,6 +7,7 @@ import AppContext from '../../../context/AppContext';
|
||||
import Checkbox from '../../../shared/Checkbox';
|
||||
import TextArea from '../../../shared/TextArea';
|
||||
import { addItem, deleteItem, moveItemUp, moveItemDown } from '../../../utils';
|
||||
import ItemActions from '../../../shared/ItemActions';
|
||||
|
||||
const AwardsTab = ({ data, onChange }) => {
|
||||
const context = useContext(AppContext);
|
||||
@ -53,6 +54,7 @@ const AddItem = ({ dispatch }) => {
|
||||
const [isOpen, setOpen] = useState(false);
|
||||
const [item, setItem] = useState({
|
||||
id: uuidv4(),
|
||||
enable: true,
|
||||
title: '',
|
||||
subtitle: '',
|
||||
description: '',
|
||||
@ -67,6 +69,7 @@ const AddItem = ({ dispatch }) => {
|
||||
|
||||
setItem({
|
||||
id: uuidv4(),
|
||||
enable: true,
|
||||
title: '',
|
||||
subtitle: '',
|
||||
description: '',
|
||||
@ -162,44 +165,18 @@ const Item = ({ item, index, onChange, dispatch, first, last }) => {
|
||||
onChange={v => onChange(`${identifier}.description`, v)}
|
||||
/>
|
||||
|
||||
<div className="flex justify-between">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => deleteItem(dispatch, 'awards', item)}
|
||||
className="bg-red-600 hover:bg-red-700 text-white text-sm font-medium py-2 px-5 rounded"
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<i className="material-icons mr-2 font-bold text-base">delete</i>
|
||||
<span className="text-sm">Delete</span>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<div className="flex">
|
||||
{!first && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => moveItemUp(dispatch, 'awards', item)}
|
||||
className="bg-gray-600 hover:bg-gray-700 text-white text-sm font-medium py-2 px-4 rounded mr-2"
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<i className="material-icons font-bold text-base">arrow_upward</i>
|
||||
</div>
|
||||
</button>
|
||||
)}
|
||||
|
||||
{!last && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => moveItemDown(dispatch, 'awards', item)}
|
||||
className="bg-gray-600 hover:bg-gray-700 text-white text-sm font-medium py-2 px-4 rounded"
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<i className="material-icons font-bold text-base">arrow_downward</i>
|
||||
</div>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<ItemActions
|
||||
item={item}
|
||||
onChange={onChange}
|
||||
type="awards"
|
||||
identifier={identifier}
|
||||
dispatch={dispatch}
|
||||
deleteItem={deleteItem}
|
||||
first={first}
|
||||
moveItemUp={moveItemUp}
|
||||
last={last}
|
||||
moveItemDown={moveItemDown}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -7,6 +7,7 @@ import AppContext from '../../../context/AppContext';
|
||||
import Checkbox from '../../../shared/Checkbox';
|
||||
import TextArea from '../../../shared/TextArea';
|
||||
import { addItem, deleteItem, moveItemUp, moveItemDown } from '../../../utils';
|
||||
import ItemActions from '../../../shared/ItemActions';
|
||||
|
||||
const CertificationsTab = ({ data, onChange }) => {
|
||||
const context = useContext(AppContext);
|
||||
@ -53,6 +54,7 @@ const AddItem = ({ dispatch }) => {
|
||||
const [isOpen, setOpen] = useState(false);
|
||||
const [item, setItem] = useState({
|
||||
id: uuidv4(),
|
||||
enable: true,
|
||||
title: '',
|
||||
subtitle: '',
|
||||
description: '',
|
||||
@ -67,6 +69,7 @@ const AddItem = ({ dispatch }) => {
|
||||
|
||||
setItem({
|
||||
id: uuidv4(),
|
||||
enable: true,
|
||||
title: '',
|
||||
subtitle: '',
|
||||
description: '',
|
||||
@ -162,44 +165,18 @@ const Item = ({ item, index, onChange, dispatch, first, last }) => {
|
||||
onChange={v => onChange(`${identifier}.description`, v)}
|
||||
/>
|
||||
|
||||
<div className="flex justify-between">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => deleteItem(dispatch, 'certifications', item)}
|
||||
className="bg-red-600 hover:bg-red-700 text-white text-sm font-medium py-2 px-5 rounded"
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<i className="material-icons mr-2 font-bold text-base">delete</i>
|
||||
<span className="text-sm">Delete</span>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<div className="flex">
|
||||
{!first && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => moveItemUp(dispatch, 'certifications', item)}
|
||||
className="bg-gray-600 hover:bg-gray-700 text-white text-sm font-medium py-2 px-4 rounded mr-2"
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<i className="material-icons font-bold text-base">arrow_upward</i>
|
||||
</div>
|
||||
</button>
|
||||
)}
|
||||
|
||||
{!last && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => moveItemDown(dispatch, 'certifications', item)}
|
||||
className="bg-gray-600 hover:bg-gray-700 text-white text-sm font-medium py-2 px-4 rounded"
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<i className="material-icons font-bold text-base">arrow_downward</i>
|
||||
</div>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<ItemActions
|
||||
item={item}
|
||||
onChange={onChange}
|
||||
type="certifications"
|
||||
identifier={identifier}
|
||||
dispatch={dispatch}
|
||||
deleteItem={deleteItem}
|
||||
first={first}
|
||||
moveItemUp={moveItemUp}
|
||||
last={last}
|
||||
moveItemDown={moveItemDown}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -7,6 +7,7 @@ import TextArea from '../../../shared/TextArea';
|
||||
import AppContext from '../../../context/AppContext';
|
||||
import Checkbox from '../../../shared/Checkbox';
|
||||
import { addItem, deleteItem, moveItemUp, moveItemDown } from '../../../utils';
|
||||
import ItemActions from '../../../shared/ItemActions';
|
||||
|
||||
const EducationTab = ({ data, onChange }) => {
|
||||
const context = useContext(AppContext);
|
||||
@ -53,6 +54,7 @@ const AddItem = ({ dispatch }) => {
|
||||
const [isOpen, setOpen] = useState(false);
|
||||
const [item, setItem] = useState({
|
||||
id: uuidv4(),
|
||||
enable: true,
|
||||
name: '',
|
||||
major: '',
|
||||
start: '',
|
||||
@ -70,6 +72,7 @@ const AddItem = ({ dispatch }) => {
|
||||
|
||||
setItem({
|
||||
id: uuidv4(),
|
||||
enable: true,
|
||||
title: '',
|
||||
role: '',
|
||||
start: '',
|
||||
@ -224,44 +227,18 @@ const Item = ({ item, index, onChange, dispatch, first, last }) => {
|
||||
onChange={v => onChange(`${identifier}.description`, v)}
|
||||
/>
|
||||
|
||||
<div className="flex justify-between">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => deleteItem(dispatch, 'education', item)}
|
||||
className="bg-red-600 hover:bg-red-700 text-white text-sm font-medium py-2 px-5 rounded"
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<i className="material-icons mr-2 font-bold text-base">delete</i>
|
||||
<span className="text-sm">Delete</span>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<div className="flex">
|
||||
{!first && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => moveItemUp(dispatch, 'education', item)}
|
||||
className="bg-gray-600 hover:bg-gray-700 text-white text-sm font-medium py-2 px-4 rounded mr-2"
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<i className="material-icons font-bold text-base">arrow_upward</i>
|
||||
</div>
|
||||
</button>
|
||||
)}
|
||||
|
||||
{!last && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => moveItemDown(dispatch, 'education', item)}
|
||||
className="bg-gray-600 hover:bg-gray-700 text-white text-sm font-medium py-2 px-4 rounded"
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<i className="material-icons font-bold text-base">arrow_downward</i>
|
||||
</div>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<ItemActions
|
||||
item={item}
|
||||
onChange={onChange}
|
||||
type="education"
|
||||
identifier={identifier}
|
||||
dispatch={dispatch}
|
||||
deleteItem={deleteItem}
|
||||
first={first}
|
||||
moveItemUp={moveItemUp}
|
||||
last={last}
|
||||
moveItemDown={moveItemDown}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -6,6 +6,7 @@ import TextField from '../../../shared/TextField';
|
||||
import AppContext from '../../../context/AppContext';
|
||||
import Checkbox from '../../../shared/Checkbox';
|
||||
import { addItem, deleteItem, moveItemUp, moveItemDown } from '../../../utils';
|
||||
import ItemActions from '../../../shared/ItemActions';
|
||||
|
||||
const ExtrasTab = ({ data, onChange }) => {
|
||||
const context = useContext(AppContext);
|
||||
@ -52,6 +53,7 @@ const AddItem = ({ dispatch }) => {
|
||||
const [isOpen, setOpen] = useState(false);
|
||||
const [item, setItem] = useState({
|
||||
id: uuidv4(),
|
||||
enable: true,
|
||||
key: '',
|
||||
value: '',
|
||||
});
|
||||
@ -65,6 +67,7 @@ const AddItem = ({ dispatch }) => {
|
||||
|
||||
setItem({
|
||||
id: uuidv4(),
|
||||
enable: true,
|
||||
key: '',
|
||||
value: '',
|
||||
});
|
||||
@ -145,44 +148,18 @@ const Item = ({ item, index, onChange, dispatch, first, last }) => {
|
||||
onChange={v => onChange(`${identifier}.value`, v)}
|
||||
/>
|
||||
|
||||
<div className="mt-6 flex justify-between">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => deleteItem(dispatch, 'extras', item)}
|
||||
className="bg-red-600 hover:bg-red-700 text-white text-sm font-medium py-2 px-5 rounded"
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<i className="material-icons mr-2 font-bold text-base">delete</i>
|
||||
<span className="text-sm">Delete</span>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<div className="flex">
|
||||
{!first && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => moveItemUp(dispatch, 'extras', item)}
|
||||
className="bg-gray-600 hover:bg-gray-700 text-white text-sm font-medium py-2 px-4 rounded mr-2"
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<i className="material-icons font-bold text-base">arrow_upward</i>
|
||||
</div>
|
||||
</button>
|
||||
)}
|
||||
|
||||
{!last && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => moveItemDown(dispatch, 'extras', item)}
|
||||
className="bg-gray-600 hover:bg-gray-700 text-white text-sm font-medium py-2 px-4 rounded"
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<i className="material-icons font-bold text-base">arrow_downward</i>
|
||||
</div>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<ItemActions
|
||||
item={item}
|
||||
onChange={onChange}
|
||||
type="extras"
|
||||
identifier={identifier}
|
||||
dispatch={dispatch}
|
||||
deleteItem={deleteItem}
|
||||
first={first}
|
||||
moveItemUp={moveItemUp}
|
||||
last={last}
|
||||
moveItemDown={moveItemDown}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -7,6 +7,7 @@ import AppContext from '../../../context/AppContext';
|
||||
import Checkbox from '../../../shared/Checkbox';
|
||||
import Counter from '../../../shared/Counter';
|
||||
import { addItem, deleteItem, moveItemUp, moveItemDown } from '../../../utils';
|
||||
import ItemActions from '../../../shared/ItemActions';
|
||||
|
||||
const LanguagesTab = ({ data, onChange }) => {
|
||||
const context = useContext(AppContext);
|
||||
@ -73,6 +74,7 @@ const AddItem = ({ dispatch }) => {
|
||||
const [isOpen, setOpen] = useState(false);
|
||||
const [item, setItem] = useState({
|
||||
id: uuidv4(),
|
||||
enable: true,
|
||||
key: '',
|
||||
value: 1,
|
||||
});
|
||||
@ -86,6 +88,7 @@ const AddItem = ({ dispatch }) => {
|
||||
|
||||
setItem({
|
||||
id: uuidv4(),
|
||||
enable: true,
|
||||
key: '',
|
||||
value: 1,
|
||||
});
|
||||
@ -166,44 +169,18 @@ const Item = ({ item, index, onChange, dispatch, first, last }) => {
|
||||
onIncrement={() => item.value < 5 && onChange(`${identifier}.value`, item.value + 1)}
|
||||
/>
|
||||
|
||||
<div className="mt-6 flex justify-between">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => deleteItem(dispatch, 'languages', item)}
|
||||
className="bg-red-600 hover:bg-red-700 text-white text-sm font-medium py-2 px-5 rounded"
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<i className="material-icons mr-2 font-bold text-base">delete</i>
|
||||
<span className="text-sm">Delete</span>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<div className="flex">
|
||||
{!first && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => moveItemUp(dispatch, 'languages', item)}
|
||||
className="bg-gray-600 hover:bg-gray-700 text-white text-sm font-medium py-2 px-4 rounded mr-2"
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<i className="material-icons font-bold text-base">arrow_upward</i>
|
||||
</div>
|
||||
</button>
|
||||
)}
|
||||
|
||||
{!last && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => moveItemDown(dispatch, 'languages', item)}
|
||||
className="bg-gray-600 hover:bg-gray-700 text-white text-sm font-medium py-2 px-4 rounded"
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<i className="material-icons font-bold text-base">arrow_downward</i>
|
||||
</div>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<ItemActions
|
||||
item={item}
|
||||
onChange={onChange}
|
||||
type="languages"
|
||||
identifier={identifier}
|
||||
dispatch={dispatch}
|
||||
deleteItem={deleteItem}
|
||||
first={first}
|
||||
moveItemUp={moveItemUp}
|
||||
last={last}
|
||||
moveItemDown={moveItemDown}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -7,6 +7,7 @@ import TextArea from '../../../shared/TextArea';
|
||||
import AppContext from '../../../context/AppContext';
|
||||
import Checkbox from '../../../shared/Checkbox';
|
||||
import { addItem, deleteItem, moveItemUp, moveItemDown } from '../../../utils';
|
||||
import ItemActions from '../../../shared/ItemActions';
|
||||
|
||||
const ReferencesTab = ({ data, onChange }) => {
|
||||
const context = useContext(AppContext);
|
||||
@ -73,6 +74,7 @@ const AddItem = ({ dispatch }) => {
|
||||
const [isOpen, setOpen] = useState(false);
|
||||
const [item, setItem] = useState({
|
||||
id: uuidv4(),
|
||||
enable: true,
|
||||
name: '',
|
||||
position: '',
|
||||
phone: '',
|
||||
@ -89,6 +91,7 @@ const AddItem = ({ dispatch }) => {
|
||||
|
||||
setItem({
|
||||
id: uuidv4(),
|
||||
enable: true,
|
||||
name: '',
|
||||
position: '',
|
||||
phone: '',
|
||||
@ -222,44 +225,18 @@ const Item = ({ item, index, onChange, dispatch, first, last }) => {
|
||||
onChange={v => onChange(`${identifier}.description`, v)}
|
||||
/>
|
||||
|
||||
<div className="flex justify-between">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => deleteItem(dispatch, 'references', item)}
|
||||
className="bg-red-600 hover:bg-red-700 text-white text-sm font-medium py-2 px-5 rounded"
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<i className="material-icons mr-2 font-bold text-base">delete</i>
|
||||
<span className="text-sm">Delete</span>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<div className="flex">
|
||||
{!first && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => moveItemUp(dispatch, 'references', item)}
|
||||
className="bg-gray-600 hover:bg-gray-700 text-white text-sm font-medium py-2 px-4 rounded mr-2"
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<i className="material-icons font-bold text-base">arrow_upward</i>
|
||||
</div>
|
||||
</button>
|
||||
)}
|
||||
|
||||
{!last && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => moveItemDown(dispatch, 'references', item)}
|
||||
className="bg-gray-600 hover:bg-gray-700 text-white text-sm font-medium py-2 px-4 rounded"
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<i className="material-icons font-bold text-base">arrow_downward</i>
|
||||
</div>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<ItemActions
|
||||
item={item}
|
||||
onChange={onChange}
|
||||
type="references"
|
||||
identifier={identifier}
|
||||
dispatch={dispatch}
|
||||
deleteItem={deleteItem}
|
||||
first={first}
|
||||
moveItemUp={moveItemUp}
|
||||
last={last}
|
||||
moveItemDown={moveItemDown}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -7,6 +7,7 @@ import TextArea from '../../../shared/TextArea';
|
||||
import AppContext from '../../../context/AppContext';
|
||||
import Checkbox from '../../../shared/Checkbox';
|
||||
import { addItem, deleteItem, moveItemUp, moveItemDown } from '../../../utils';
|
||||
import ItemActions from '../../../shared/ItemActions';
|
||||
|
||||
const WorkTab = ({ data, onChange }) => {
|
||||
const context = useContext(AppContext);
|
||||
@ -50,6 +51,7 @@ const AddItem = ({ dispatch }) => {
|
||||
const [isOpen, setOpen] = useState(false);
|
||||
const [item, setItem] = useState({
|
||||
id: uuidv4(),
|
||||
enable: true,
|
||||
title: '',
|
||||
role: '',
|
||||
start: '',
|
||||
@ -66,6 +68,7 @@ const AddItem = ({ dispatch }) => {
|
||||
|
||||
setItem({
|
||||
id: uuidv4(),
|
||||
enable: true,
|
||||
title: '',
|
||||
role: '',
|
||||
start: '',
|
||||
@ -155,7 +158,7 @@ const Item = ({ item, index, onChange, dispatch, first, last }) => {
|
||||
className="flex justify-between items-center cursor-pointer"
|
||||
onClick={() => setOpen(!isOpen)}
|
||||
>
|
||||
<h6 className="text-sm font-medium">{item.title}</h6>
|
||||
<h6 className="ml-2 text-sm font-medium">{item.title}</h6>
|
||||
<i className="material-icons">{isOpen ? 'expand_less' : 'expand_more'}</i>
|
||||
</div>
|
||||
|
||||
@ -203,44 +206,18 @@ const Item = ({ item, index, onChange, dispatch, first, last }) => {
|
||||
onChange={v => onChange(`${identifier}.description`, v)}
|
||||
/>
|
||||
|
||||
<div className="flex justify-between">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => deleteItem(dispatch, 'work', item)}
|
||||
className="bg-red-600 hover:bg-red-700 text-white text-sm font-medium py-2 px-5 rounded"
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<i className="material-icons mr-2 font-bold text-base">delete</i>
|
||||
<span className="text-sm">Delete</span>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<div className="flex">
|
||||
{!first && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => moveItemUp(dispatch, 'work', item)}
|
||||
className="bg-gray-600 hover:bg-gray-700 text-white text-sm font-medium py-2 px-4 rounded mr-2"
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<i className="material-icons font-bold text-base">arrow_upward</i>
|
||||
</div>
|
||||
</button>
|
||||
)}
|
||||
|
||||
{!last && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => moveItemDown(dispatch, 'work', item)}
|
||||
className="bg-gray-600 hover:bg-gray-700 text-white text-sm font-medium py-2 px-4 rounded"
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<i className="material-icons font-bold text-base">arrow_downward</i>
|
||||
</div>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<ItemActions
|
||||
item={item}
|
||||
onChange={onChange}
|
||||
type="work"
|
||||
identifier={identifier}
|
||||
dispatch={dispatch}
|
||||
deleteItem={deleteItem}
|
||||
first={first}
|
||||
moveItemUp={moveItemUp}
|
||||
last={last}
|
||||
moveItemDown={moveItemDown}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -113,12 +113,12 @@ const reducer = (state, { type, payload }) => {
|
||||
case 'import_data':
|
||||
if (payload === null) return initialState;
|
||||
|
||||
for(const section of Object.keys(initialState.data)){
|
||||
if(!(section in payload.data)){
|
||||
for (const section of Object.keys(initialState.data)) {
|
||||
if (!(section in payload.data)) {
|
||||
payload.data[section] = initialState.data[section];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
...state,
|
||||
data: payload.data,
|
||||
|
||||
@ -1,16 +1,20 @@
|
||||
import React from 'react';
|
||||
|
||||
const Checkbox = ({ checked, onChange }) => {
|
||||
const Checkbox = ({ checked, onChange, icon = 'check', size = '2rem' }) => {
|
||||
return (
|
||||
<div className="bg-white border-2 rounded border-gray-400 hover:border-gray-500 w-8 h-8 flex flex-shrink-0 justify-center items-center mr-2 focus-within:border-blue-500 cursor-pointer">
|
||||
<div
|
||||
className="bg-white border-2 rounded border-gray-400 hover:border-gray-500 flex flex-shrink-0 justify-center items-center mr-2 focus-within:border-blue-500 cursor-pointer"
|
||||
style={{ width: size, height: size }}
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
className="w-8 h-8 opacity-0 absolute cursor-pointer"
|
||||
style={{ width: size, height: size }}
|
||||
className="opacity-0 absolute cursor-pointer"
|
||||
checked={checked}
|
||||
onChange={e => onChange(e.target.checked)}
|
||||
/>
|
||||
<i className="material-icons fill-current hidden text-lg font-bold text-gray-800 cursor-pointer">
|
||||
check
|
||||
<i className="material-icons fill-current hidden text-sm font-bold text-gray-800 cursor-pointer">
|
||||
{icon}
|
||||
</i>
|
||||
</div>
|
||||
);
|
||||
|
||||
68
src/shared/ItemActions.js
Normal file
68
src/shared/ItemActions.js
Normal file
@ -0,0 +1,68 @@
|
||||
import React from 'react';
|
||||
import Checkbox from './Checkbox';
|
||||
|
||||
const ItemActions = ({
|
||||
item,
|
||||
onChange,
|
||||
type,
|
||||
identifier,
|
||||
dispatch,
|
||||
deleteItem,
|
||||
first,
|
||||
moveItemUp,
|
||||
last,
|
||||
moveItemDown,
|
||||
}) => {
|
||||
return (
|
||||
<div className="flex justify-between">
|
||||
<div className="flex items-center">
|
||||
<Checkbox
|
||||
size="2.25rem"
|
||||
checked={item.enable}
|
||||
onChange={v => {
|
||||
onChange(`${identifier}.enable`, v);
|
||||
}}
|
||||
/>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => deleteItem(dispatch, type, item)}
|
||||
className="ml-2 bg-red-600 hover:bg-red-700 text-white text-sm font-medium py-2 px-5 rounded"
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<i className="material-icons mr-2 font-bold text-base">delete</i>
|
||||
<span className="text-sm">Delete</span>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="flex">
|
||||
{!first && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => moveItemUp(dispatch, type, item)}
|
||||
className="bg-gray-600 hover:bg-gray-700 text-white text-sm font-medium py-2 px-4 rounded mr-2"
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<i className="material-icons font-bold text-base">arrow_upward</i>
|
||||
</div>
|
||||
</button>
|
||||
)}
|
||||
|
||||
{!last && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => moveItemDown(dispatch, type, item)}
|
||||
className="bg-gray-600 hover:bg-gray-700 text-white text-sm font-medium py-2 px-4 rounded"
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<i className="material-icons font-bold text-base">arrow_downward</i>
|
||||
</div>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ItemActions;
|
||||
@ -116,7 +116,7 @@ const Castform = () => {
|
||||
data.work.enable && (
|
||||
<div>
|
||||
<Heading light title={data.work.heading} />
|
||||
{data.work.items.map(WorkItem)}
|
||||
{data.work.items.filter(x => x.enable).map(WorkItem)}
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -136,7 +136,7 @@ const Castform = () => {
|
||||
<div>
|
||||
<Heading light title={data.references.heading} />
|
||||
<div className="grid grid-cols-2 gap-6 px-5">
|
||||
{data.references.items.map(ReferenceItem)}
|
||||
{data.references.items.filter(x => x.enable).map(ReferenceItem)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@ -167,7 +167,9 @@ const Castform = () => {
|
||||
data.languages.enable && (
|
||||
<div>
|
||||
<Heading title={data.languages.heading} />
|
||||
<div className="px-5 mb-6">{data.languages.items.map(LanguageItem)}</div>
|
||||
<div className="px-5 mb-6">
|
||||
{data.languages.items.filter(x => x.enable).map(LanguageItem)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -194,7 +196,7 @@ const Castform = () => {
|
||||
data.education.enable && (
|
||||
<div>
|
||||
<Heading light title={data.education.heading} />
|
||||
{data.education.items.map(EducationItem)}
|
||||
{data.education.items.filter(x => x.enable).map(EducationItem)}
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -211,7 +213,7 @@ const Castform = () => {
|
||||
data.awards.enable && (
|
||||
<div>
|
||||
<Heading light title={data.awards.heading} />
|
||||
{data.awards.items.map(AwardItem)}
|
||||
{data.awards.items.filter(x => x.enable).map(AwardItem)}
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -228,7 +230,7 @@ const Castform = () => {
|
||||
data.certifications.enable && (
|
||||
<div>
|
||||
<Heading title={data.certifications.heading} />
|
||||
{data.certifications.items.map(CertificationItem)}
|
||||
{data.certifications.items.filter(x => x.enable).map(CertificationItem)}
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -244,7 +246,7 @@ const Castform = () => {
|
||||
data.extras.enable && (
|
||||
<div>
|
||||
<Heading title={data.extras.heading} />
|
||||
{data.extras.items.map(ExtraItem)}
|
||||
{data.extras.items.filter(x => x.enable).map(ExtraItem)}
|
||||
</div>
|
||||
);
|
||||
|
||||
|
||||
@ -109,7 +109,7 @@ const Gengar = () => {
|
||||
data.education.enable && (
|
||||
<div className="mb-6">
|
||||
<Heading title={data.education.heading} />
|
||||
{data.education.items.map(EducationItem)}
|
||||
{data.education.items.filter(x => x.enable).map(EducationItem)}
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -126,7 +126,7 @@ const Gengar = () => {
|
||||
data.certifications.enable && (
|
||||
<div className="mb-6">
|
||||
<Heading title={data.certifications.heading} />
|
||||
{data.certifications.items.map(CertificationItem)}
|
||||
{data.certifications.items.filter(x => x.enable).map(CertificationItem)}
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -143,7 +143,7 @@ const Gengar = () => {
|
||||
data.awards.enable && (
|
||||
<div className="mb-6">
|
||||
<Heading title={data.awards.heading} />
|
||||
{data.awards.items.map(AwardItem)}
|
||||
{data.awards.items.filter(x => x.enable).map(AwardItem)}
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -162,7 +162,9 @@ const Gengar = () => {
|
||||
data.references.enable && (
|
||||
<div>
|
||||
<Heading title={data.references.heading} />
|
||||
<div className="grid grid-cols-2 gap-6">{data.references.items.map(ReferenceItem)}</div>
|
||||
<div className="grid grid-cols-2 gap-6">
|
||||
{data.references.items.filter(x => x.enable).map(ReferenceItem)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -186,7 +188,7 @@ const Gengar = () => {
|
||||
data.work.enable && (
|
||||
<div className="mb-6">
|
||||
<Heading title={data.work.heading} />
|
||||
{data.work.items.map(WorkItem)}
|
||||
{data.work.items.filter(x => x.enable).map(WorkItem)}
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -208,7 +210,7 @@ const Gengar = () => {
|
||||
data.languages.enable && (
|
||||
<div>
|
||||
<Heading title={data.languages.heading} />
|
||||
<div className="mb-6">{data.languages.items.map(LanguageItem)}</div>
|
||||
<div className="mb-6">{data.languages.items.filter(x => x.enable).map(LanguageItem)}</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -224,7 +226,9 @@ const Gengar = () => {
|
||||
data.extras.enable && (
|
||||
<div>
|
||||
<Heading title={data.extras.heading} />
|
||||
<div className="grid grid-cols-2">{data.extras.items.map(ExtraItem)}</div>
|
||||
<div className="grid grid-cols-2">
|
||||
{data.extras.items.filter(x => x.enable).map(ExtraItem)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
||||
@ -80,7 +80,7 @@ const Onyx = () => {
|
||||
data.work.enable && (
|
||||
<div>
|
||||
<Heading title={data.work.heading} />
|
||||
{data.work.items.map(WorkItem)}
|
||||
{data.work.items.filter(x => x.enable).map(WorkItem)}
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -107,7 +107,7 @@ const Onyx = () => {
|
||||
data.education.enable && (
|
||||
<div>
|
||||
<Heading title={data.education.heading} />
|
||||
{data.education.items.map(EducationItem)}
|
||||
{data.education.items.filter(x => x.enable).map(EducationItem)}
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -124,7 +124,7 @@ const Onyx = () => {
|
||||
data.awards.enable && (
|
||||
<div>
|
||||
<Heading title={data.awards.heading} />
|
||||
{data.awards.items.map(AwardItem)}
|
||||
{data.awards.items.filter(x => x.enable).map(AwardItem)}
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -141,7 +141,7 @@ const Onyx = () => {
|
||||
data.certifications.enable && (
|
||||
<div>
|
||||
<Heading title={data.certifications.heading} />
|
||||
{data.certifications.items.map(CertificationItem)}
|
||||
{data.certifications.items.filter(x => x.enable).map(CertificationItem)}
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -185,7 +185,7 @@ const Onyx = () => {
|
||||
data.languages.enable && (
|
||||
<div>
|
||||
<Heading title={data.languages.heading} />
|
||||
<div className="w-3/4">{data.languages.items.map(LanguageItem)}</div>
|
||||
<div className="w-3/4">{data.languages.items.filter(x => x.enable).map(LanguageItem)}</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -204,7 +204,9 @@ const Onyx = () => {
|
||||
data.references.enable && (
|
||||
<div>
|
||||
<Heading title={data.references.heading} />
|
||||
<div className="grid grid-cols-3 gap-6">{data.references.items.map(ReferenceItem)}</div>
|
||||
<div className="grid grid-cols-3 gap-6">
|
||||
{data.references.items.filter(x => x.enable).map(ReferenceItem)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -221,7 +223,7 @@ const Onyx = () => {
|
||||
<div>
|
||||
<Heading title={data.extras.heading} />
|
||||
<table className="w-2/3 table-auto">
|
||||
<tbody>{data.extras.items.map(ExtraItem)}</tbody>
|
||||
<tbody>{data.extras.items.filter(x => x.enable).map(ExtraItem)}</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -91,7 +91,9 @@ const Pikachu = () => {
|
||||
data.references.enable && (
|
||||
<div>
|
||||
<Heading title={data.references.heading} />
|
||||
<div className="grid grid-cols-2 gap-6">{data.references.items.map(ReferenceItem)}</div>
|
||||
<div className="grid grid-cols-2 gap-6">
|
||||
{data.references.items.filter(x => x.enable).map(ReferenceItem)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -113,7 +115,7 @@ const Pikachu = () => {
|
||||
data.languages.enable && (
|
||||
<div>
|
||||
<Heading title={data.languages.heading} />
|
||||
<div className="mb-6">{data.languages.items.map(LanguageItem)}</div>
|
||||
<div className="mb-6">{data.languages.items.filter(x => x.enable).map(LanguageItem)}</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -129,7 +131,9 @@ const Pikachu = () => {
|
||||
data.extras.enable && (
|
||||
<div>
|
||||
<Heading title={data.extras.heading} />
|
||||
<div className="flex flex-col mb-6">{data.extras.items.map(ExtraItem)}</div>
|
||||
<div className="flex flex-col mb-6">
|
||||
{data.extras.items.filter(x => x.enable).map(ExtraItem)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -153,7 +157,9 @@ const Pikachu = () => {
|
||||
data.work.enable && (
|
||||
<div>
|
||||
<Heading title={data.work.heading} />
|
||||
<div className="flex flex-col mb-4">{data.work.items.map(WorkItem)}</div>
|
||||
<div className="flex flex-col mb-4">
|
||||
{data.work.items.filter(x => x.enable).map(WorkItem)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -182,7 +188,9 @@ const Pikachu = () => {
|
||||
data.education.enable && (
|
||||
<div>
|
||||
<Heading title={data.education.heading} />
|
||||
<div className="flex flex-col mb-4">{data.education.items.map(EducationItem)}</div>
|
||||
<div className="flex flex-col mb-4">
|
||||
{data.education.items.filter(x => x.enable).map(EducationItem)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -199,7 +207,9 @@ const Pikachu = () => {
|
||||
data.awards.enable && (
|
||||
<div>
|
||||
<Heading title={data.awards.heading} />
|
||||
<div className="flex flex-col mb-2">{data.awards.items.map(AwardItem)}</div>
|
||||
<div className="flex flex-col mb-2">
|
||||
{data.awards.items.filter(x => x.enable).map(AwardItem)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -216,7 +226,9 @@ const Pikachu = () => {
|
||||
data.certifications.enable && (
|
||||
<div>
|
||||
<Heading title={data.certifications.heading} />
|
||||
<div className="flex flex-col mb-2">{data.certifications.items.map(CertificationItem)}</div>
|
||||
<div className="flex flex-col mb-2">
|
||||
{data.certifications.items.filter(x => x.enable).map(CertificationItem)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user