diff --git a/.eslintrc b/.eslintrc index 8ce58012..60904185 100644 --- a/.eslintrc +++ b/.eslintrc @@ -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 diff --git a/src/assets/dummy/data.json b/src/assets/dummy/data.json index 648dde50..836a5c59 100644 --- a/src/assets/dummy/data.json +++ b/src/assets/dummy/data.json @@ -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" }, diff --git a/src/components/LeftSidebar/tabs/Awards.js b/src/components/LeftSidebar/tabs/Awards.js index 85606fa3..d2935933 100644 --- a/src/components/LeftSidebar/tabs/Awards.js +++ b/src/components/LeftSidebar/tabs/Awards.js @@ -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)} /> -
- - -
- {!first && ( - - )} - - {!last && ( - - )} -
-
+ ); diff --git a/src/components/LeftSidebar/tabs/Certifications.js b/src/components/LeftSidebar/tabs/Certifications.js index 7a683660..5cdd5f83 100644 --- a/src/components/LeftSidebar/tabs/Certifications.js +++ b/src/components/LeftSidebar/tabs/Certifications.js @@ -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)} /> -
- - -
- {!first && ( - - )} - - {!last && ( - - )} -
-
+ ); diff --git a/src/components/LeftSidebar/tabs/Education.js b/src/components/LeftSidebar/tabs/Education.js index ae6fea35..1363ee7f 100644 --- a/src/components/LeftSidebar/tabs/Education.js +++ b/src/components/LeftSidebar/tabs/Education.js @@ -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)} /> -
- - -
- {!first && ( - - )} - - {!last && ( - - )} -
-
+ ); diff --git a/src/components/LeftSidebar/tabs/Extras.js b/src/components/LeftSidebar/tabs/Extras.js index cab64b69..bed67fb9 100644 --- a/src/components/LeftSidebar/tabs/Extras.js +++ b/src/components/LeftSidebar/tabs/Extras.js @@ -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)} /> -
- - -
- {!first && ( - - )} - - {!last && ( - - )} -
-
+ ); diff --git a/src/components/LeftSidebar/tabs/Languages.js b/src/components/LeftSidebar/tabs/Languages.js index 3a7f5bca..d6b92536 100644 --- a/src/components/LeftSidebar/tabs/Languages.js +++ b/src/components/LeftSidebar/tabs/Languages.js @@ -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)} /> -
- - -
- {!first && ( - - )} - - {!last && ( - - )} -
-
+ ); diff --git a/src/components/LeftSidebar/tabs/References.js b/src/components/LeftSidebar/tabs/References.js index ec1749e2..8e4d2b37 100644 --- a/src/components/LeftSidebar/tabs/References.js +++ b/src/components/LeftSidebar/tabs/References.js @@ -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)} /> -
- - -
- {!first && ( - - )} - - {!last && ( - - )} -
-
+ ); diff --git a/src/components/LeftSidebar/tabs/Work.js b/src/components/LeftSidebar/tabs/Work.js index 0622b817..250f4f69 100644 --- a/src/components/LeftSidebar/tabs/Work.js +++ b/src/components/LeftSidebar/tabs/Work.js @@ -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)} > -
{item.title}
+
{item.title}
{isOpen ? 'expand_less' : 'expand_more'} @@ -203,44 +206,18 @@ const Item = ({ item, index, onChange, dispatch, first, last }) => { onChange={v => onChange(`${identifier}.description`, v)} /> -
- - -
- {!first && ( - - )} - - {!last && ( - - )} -
-
+ ); diff --git a/src/context/AppContext.js b/src/context/AppContext.js index c895c282..d3077584 100644 --- a/src/context/AppContext.js +++ b/src/context/AppContext.js @@ -1,4 +1,3 @@ -/* eslint-disable no-case-declarations */ import React, { createContext, useReducer } from 'react'; import get from 'lodash/get'; import set from 'lodash/set'; @@ -113,12 +112,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, diff --git a/src/shared/Checkbox.js b/src/shared/Checkbox.js index 9edf7054..48fbaeb3 100644 --- a/src/shared/Checkbox.js +++ b/src/shared/Checkbox.js @@ -1,16 +1,20 @@ import React from 'react'; -const Checkbox = ({ checked, onChange }) => { +const Checkbox = ({ checked, onChange, icon = 'check', size = '2rem' }) => { return ( -
+
onChange(e.target.checked)} /> - - check + + {icon}
); diff --git a/src/shared/ItemActions.js b/src/shared/ItemActions.js new file mode 100644 index 00000000..a603ba9a --- /dev/null +++ b/src/shared/ItemActions.js @@ -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 ( +
+
+ { + onChange(`${identifier}.enable`, v); + }} + /> + + +
+ +
+ {!first && ( + + )} + + {!last && ( + + )} +
+
+ ); +}; + +export default ItemActions; diff --git a/src/templates/castform/Castform.js b/src/templates/castform/Castform.js index 68b1d817..7e2842c6 100644 --- a/src/templates/castform/Castform.js +++ b/src/templates/castform/Castform.js @@ -116,7 +116,7 @@ const Castform = () => { data.work.enable && (
- {data.work.items.map(WorkItem)} + {data.work.items.filter(x => x.enable).map(WorkItem)}
); @@ -136,7 +136,7 @@ const Castform = () => {
- {data.references.items.map(ReferenceItem)} + {data.references.items.filter(x => x.enable).map(ReferenceItem)}
); @@ -167,7 +167,9 @@ const Castform = () => { data.languages.enable && (
-
{data.languages.items.map(LanguageItem)}
+
+ {data.languages.items.filter(x => x.enable).map(LanguageItem)} +
); @@ -194,7 +196,7 @@ const Castform = () => { data.education.enable && (
- {data.education.items.map(EducationItem)} + {data.education.items.filter(x => x.enable).map(EducationItem)}
); @@ -211,7 +213,7 @@ const Castform = () => { data.awards.enable && (
- {data.awards.items.map(AwardItem)} + {data.awards.items.filter(x => x.enable).map(AwardItem)}
); @@ -228,7 +230,7 @@ const Castform = () => { data.certifications.enable && (
- {data.certifications.items.map(CertificationItem)} + {data.certifications.items.filter(x => x.enable).map(CertificationItem)}
); @@ -244,7 +246,7 @@ const Castform = () => { data.extras.enable && (
- {data.extras.items.map(ExtraItem)} + {data.extras.items.filter(x => x.enable).map(ExtraItem)}
); diff --git a/src/templates/gengar/Gengar.js b/src/templates/gengar/Gengar.js index 7d418ae6..1b25177c 100644 --- a/src/templates/gengar/Gengar.js +++ b/src/templates/gengar/Gengar.js @@ -109,7 +109,7 @@ const Gengar = () => { data.education.enable && (
- {data.education.items.map(EducationItem)} + {data.education.items.filter(x => x.enable).map(EducationItem)}
); @@ -126,7 +126,7 @@ const Gengar = () => { data.certifications.enable && (
- {data.certifications.items.map(CertificationItem)} + {data.certifications.items.filter(x => x.enable).map(CertificationItem)}
); @@ -143,7 +143,7 @@ const Gengar = () => { data.awards.enable && (
- {data.awards.items.map(AwardItem)} + {data.awards.items.filter(x => x.enable).map(AwardItem)}
); @@ -162,7 +162,9 @@ const Gengar = () => { data.references.enable && (
-
{data.references.items.map(ReferenceItem)}
+
+ {data.references.items.filter(x => x.enable).map(ReferenceItem)} +
); @@ -186,7 +188,7 @@ const Gengar = () => { data.work.enable && (
- {data.work.items.map(WorkItem)} + {data.work.items.filter(x => x.enable).map(WorkItem)}
); @@ -208,7 +210,7 @@ const Gengar = () => { data.languages.enable && (
-
{data.languages.items.map(LanguageItem)}
+
{data.languages.items.filter(x => x.enable).map(LanguageItem)}
); @@ -224,7 +226,9 @@ const Gengar = () => { data.extras.enable && (
-
{data.extras.items.map(ExtraItem)}
+
+ {data.extras.items.filter(x => x.enable).map(ExtraItem)} +
); diff --git a/src/templates/onyx/Onyx.js b/src/templates/onyx/Onyx.js index 3d94bbcd..3b7a91f4 100644 --- a/src/templates/onyx/Onyx.js +++ b/src/templates/onyx/Onyx.js @@ -80,7 +80,7 @@ const Onyx = () => { data.work.enable && (
- {data.work.items.map(WorkItem)} + {data.work.items.filter(x => x.enable).map(WorkItem)}
); @@ -107,7 +107,7 @@ const Onyx = () => { data.education.enable && (
- {data.education.items.map(EducationItem)} + {data.education.items.filter(x => x.enable).map(EducationItem)}
); @@ -124,7 +124,7 @@ const Onyx = () => { data.awards.enable && (
- {data.awards.items.map(AwardItem)} + {data.awards.items.filter(x => x.enable).map(AwardItem)}
); @@ -141,7 +141,7 @@ const Onyx = () => { data.certifications.enable && (
- {data.certifications.items.map(CertificationItem)} + {data.certifications.items.filter(x => x.enable).map(CertificationItem)}
); @@ -185,7 +185,7 @@ const Onyx = () => { data.languages.enable && (
-
{data.languages.items.map(LanguageItem)}
+
{data.languages.items.filter(x => x.enable).map(LanguageItem)}
); @@ -204,7 +204,9 @@ const Onyx = () => { data.references.enable && (
-
{data.references.items.map(ReferenceItem)}
+
+ {data.references.items.filter(x => x.enable).map(ReferenceItem)} +
); @@ -221,7 +223,7 @@ const Onyx = () => {
- {data.extras.items.map(ExtraItem)} + {data.extras.items.filter(x => x.enable).map(ExtraItem)}
); diff --git a/src/templates/pikachu/Pikachu.js b/src/templates/pikachu/Pikachu.js index ff849bbd..2fabc7e9 100644 --- a/src/templates/pikachu/Pikachu.js +++ b/src/templates/pikachu/Pikachu.js @@ -91,7 +91,9 @@ const Pikachu = () => { data.references.enable && (
-
{data.references.items.map(ReferenceItem)}
+
+ {data.references.items.filter(x => x.enable).map(ReferenceItem)} +
); @@ -113,7 +115,7 @@ const Pikachu = () => { data.languages.enable && (
-
{data.languages.items.map(LanguageItem)}
+
{data.languages.items.filter(x => x.enable).map(LanguageItem)}
); @@ -129,7 +131,9 @@ const Pikachu = () => { data.extras.enable && (
-
{data.extras.items.map(ExtraItem)}
+
+ {data.extras.items.filter(x => x.enable).map(ExtraItem)} +
); @@ -153,7 +157,9 @@ const Pikachu = () => { data.work.enable && (
-
{data.work.items.map(WorkItem)}
+
+ {data.work.items.filter(x => x.enable).map(WorkItem)} +
); @@ -182,7 +188,9 @@ const Pikachu = () => { data.education.enable && (
-
{data.education.items.map(EducationItem)}
+
+ {data.education.items.filter(x => x.enable).map(EducationItem)} +
); @@ -199,7 +207,9 @@ const Pikachu = () => { data.awards.enable && (
-
{data.awards.items.map(AwardItem)}
+
+ {data.awards.items.filter(x => x.enable).map(AwardItem)} +
); @@ -216,7 +226,9 @@ const Pikachu = () => { data.certifications.enable && (
-
{data.certifications.items.map(CertificationItem)}
+
+ {data.certifications.items.filter(x => x.enable).map(CertificationItem)} +
);