- {data.metadata.layout[0] &&
- data.metadata.layout[0].map((x) => {
+ {layout[0] &&
+ layout[0].map((x) => {
const Component = Blocks[x];
return Component &&
;
})}
- {data.metadata.layout[1] &&
- data.metadata.layout[1].map((x) => {
+ {layout[1] &&
+ layout[1].map((x) => {
const Component = Blocks[x];
return Component && ;
})}
- {data.metadata.layout[2] &&
- data.metadata.layout[2].map((x) => {
+ {layout[2] &&
+ layout[2].map((x) => {
const Component = Blocks[x];
return Component &&
;
})}
diff --git a/src/templates/Pikachu.js b/src/templates/Pikachu.js
index 86a26513..9bb1b239 100644
--- a/src/templates/Pikachu.js
+++ b/src/templates/Pikachu.js
@@ -1,339 +1,116 @@
-import React, { useContext } from 'react';
+import React from 'react';
import ReactMarkdown from 'react-markdown';
+import PageContext from '../contexts/PageContext';
+import ContactA from './blocks/Contact/ContactA';
+import HeadingB from './blocks/Heading/HeadingB';
+import AwardsA from './blocks/Awards/AwardsA';
+import CertificationsA from './blocks/Certifications/CertificationsA';
+import EducationA from './blocks/Education/EducationA';
+import HobbiesA from './blocks/Hobbies/HobbiesA';
+import LanguagesA from './blocks/Languages/LanguagesA';
+import ProjectsA from './blocks/Projects/ProjectsA';
+import ReferencesA from './blocks/References/ReferencesA';
+import SkillsA from './blocks/Skills/SkillsA';
+import WorkA from './blocks/Work/WorkA';
-const Pikachu = () => {
- const context = useContext(AppContext);
- const { state } = context;
- const { data, theme } = state;
+const Blocks = {
+ work: WorkA,
+ education: EducationA,
+ projects: ProjectsA,
+ awards: AwardsA,
+ certifications: CertificationsA,
+ skills: SkillsA,
+ hobbies: HobbiesA,
+ languages: LanguagesA,
+ references: ReferencesA,
+};
- const Photo = () =>
- data.profile.photo !== '' && (
-
-

-
- );
-
- const Header = () => (
-
-
-
- {data.profile.firstName} {data.profile.lastName}
-
-
- {data.profile.subtitle}
-
-
-
-
-
-
-
- );
-
- const ContactItem = ({ icon, value, link = '#' }) =>
- value && (
-
- );
-
- const Heading = ({ title }) => (
-
- {title}
-
- );
-
- const SkillItem = (x) => (
-
- {x.skill}
-
- );
-
- const Skills = () =>
- data.skills &&
- data.skills.enable && (
-
-
-
- {data.skills.items.map(SkillItem)}
-
-
- );
-
- const HobbyItem = (x) => (
-
- {x.hobby}
-
- );
-
- const Hobbies = () =>
- data.hobbies &&
- data.hobbies.enable && (
-
-
-
- {data.hobbies.items.map(HobbyItem)}
-
-
- );
-
- const ReferenceItem = (x) => (
-
-
{x.name}
- {x.position}
- {x.phone}
- {x.email}
-
-
- );
-
- const References = () =>
- data.references &&
- data.references.enable && (
-
-
-
- {data.references.items.filter((x) => x.enable).map(ReferenceItem)}
-
-
- );
-
- const LanguageItem = (x) => (
-
-
{x.key}
-
- {x.level &&
{x.level}
}
- {x.rating !== 0 && (
-
- {Array.from(Array(x.rating)).map((_, i) => (
-
- star
-
- ))}
-
- )}
-
-
- );
-
- const Languages = () =>
- data.languages &&
- data.languages.enable && (
-
-
-
- {data.languages.items.filter((x) => x.enable).map(LanguageItem)}
-
-
- );
-
- const ExtraItem = (x) => (
-
-
{x.key}
- {x.value}
-
- );
-
- const Extras = () =>
- data.extras &&
- data.extras.enable && (
-
-
-
- {data.extras.items.filter((x) => x.enable).map(ExtraItem)}
-
-
- );
-
- const WorkItem = (x) => (
-
-
-
-
- ({x.start} - {x.end})
-
-
-
-
- );
-
- const Work = () =>
- data.work &&
- data.work.enable && (
-
-
-
- {data.work.items.filter((x) => x.enable).map(WorkItem)}
-
-
- );
-
- const EducationItem = (x) => (
-
-
-
-
-
- {x.grade}
-
-
- ({x.start} - {x.end})
-
-
-
-
-
- );
-
- const Education = () =>
- data.education &&
- data.education.enable && (
-
-
-
- {data.education.items.filter((x) => x.enable).map(EducationItem)}
-
-
- );
-
- const AwardItem = (x) => (
-
-
{x.title}
-
{x.subtitle}
-
-
- );
-
- const Awards = () =>
- data.awards &&
- data.awards.enable && (
-
-
-
- {data.awards.items.filter((x) => x.enable).map(AwardItem)}
-
-
- );
-
- const CertificationItem = (x) => (
-
-
{x.title}
-
{x.subtitle}
-
-
- );
-
- const Certifications = () =>
- data.certifications &&
- data.certifications.enable && (
-
-
-
- {data.certifications.items
- .filter((x) => x.enable)
- .map(CertificationItem)}
-
-
- );
+const Pikachu = ({ data }) => {
+ const layout = data.metadata.layout.pikachu;
return (
-
-
-
+
+
+
+ {data.profile.photograph && (
+
+

+
+ )}
-
-
-
+
+
+
+
+ {data.profile.firstName} {data.profile.lastName}
+
+
+ {data.profile.subtitle}
+
-
-
-
-
-
-
+ {data.objective.body && (
+
+
+
+
+
+ )}
+
+
-
-
-
-
-
+
+
+
-
-
-
-
-
-
+ {layout[0] &&
+ layout[0].map((x) => {
+ const Component = Blocks[x];
+ return Component &&
;
+ })}
+
+
+
+
+
+ {layout[1] &&
+ layout[1].map((x) => {
+ const Component = Blocks[x];
+ return Component && ;
+ })}
+
+
-
+
);
};
diff --git a/src/templates/blocks/Awards/AwardsA.js b/src/templates/blocks/Awards/AwardsA.js
index 98b2fe39..a8221b1d 100644
--- a/src/templates/blocks/Awards/AwardsA.js
+++ b/src/templates/blocks/Awards/AwardsA.js
@@ -12,7 +12,7 @@ const AwardItem = (x) => (
{x.awarder}
{x.date && (
-
+
{moment(x.date).format('MMMM YYYY')}
)}
diff --git a/src/templates/blocks/Certifications/CertificationsA.js b/src/templates/blocks/Certifications/CertificationsA.js
index 69e31069..62dccd42 100644
--- a/src/templates/blocks/Certifications/CertificationsA.js
+++ b/src/templates/blocks/Certifications/CertificationsA.js
@@ -12,7 +12,7 @@ const CertificationItem = (x) => (
{x.issuer}
{x.date && (
-
+
{moment(x.date).format('MMMM YYYY')}
)}
diff --git a/src/templates/blocks/Contact/ContactB.js b/src/templates/blocks/Contact/ContactB.js
new file mode 100644
index 00000000..118a50a2
--- /dev/null
+++ b/src/templates/blocks/Contact/ContactB.js
@@ -0,0 +1,64 @@
+import { get } from 'lodash';
+import React, { memo, useContext } from 'react';
+import { FaCaretRight } from 'react-icons/fa';
+import PageContext from '../../../contexts/PageContext';
+import { safetyCheck } from '../../../utils';
+import Icons from '../Icons';
+
+const ContactItem = ({ value, icon, link }) => {
+ const { data } = useContext(PageContext);
+ const Icon = get(Icons, icon.toLowerCase(), FaCaretRight);
+
+ return value ? (
+
+ ) : null;
+};
+
+const ContactA = () => {
+ const { data } = useContext(PageContext);
+
+ return (
+
+
+
+
+
+ {safetyCheck(data.social) &&
+ data.social.items.map((x) => (
+
+ ))}
+
+ );
+};
+
+export default memo(ContactA);
diff --git a/src/templates/blocks/Education/EducationA.js b/src/templates/blocks/Education/EducationA.js
index aee2cc33..25cfec08 100644
--- a/src/templates/blocks/Education/EducationA.js
+++ b/src/templates/blocks/Education/EducationA.js
@@ -12,9 +12,9 @@ const EducationItem = (x) => (
{x.degree} {x.field}
-
+
{x.startDate && (
-
+
({formatDateRange({ startDate: x.startDate, endDate: x.endDate })})
)}
diff --git a/src/templates/blocks/Heading/HeadingB.js b/src/templates/blocks/Heading/HeadingB.js
new file mode 100644
index 00000000..d7ad21f9
--- /dev/null
+++ b/src/templates/blocks/Heading/HeadingB.js
@@ -0,0 +1,20 @@
+import React, { memo, useContext } from 'react';
+import PageContext from '../../../contexts/PageContext';
+
+const HeadingB = ({ children }) => {
+ const { data } = useContext(PageContext);
+
+ return (
+
+ {children}
+
+ );
+};
+
+export default memo(HeadingB);
diff --git a/src/templates/blocks/Heading/HeadingC.js b/src/templates/blocks/Heading/HeadingC.js
new file mode 100644
index 00000000..f9b85d9c
--- /dev/null
+++ b/src/templates/blocks/Heading/HeadingC.js
@@ -0,0 +1,11 @@
+import React, { memo } from 'react';
+
+const HeadingC = ({ children }) => {
+ return (
+
+ {children}
+
+ );
+};
+
+export default memo(HeadingC);
diff --git a/src/templates/blocks/Projects/ProjectsA.js b/src/templates/blocks/Projects/ProjectsA.js
index f150d1fc..93529647 100644
--- a/src/templates/blocks/Projects/ProjectsA.js
+++ b/src/templates/blocks/Projects/ProjectsA.js
@@ -16,7 +16,7 @@ const ProjectItem = (x) => (
)}
{x.date && (
-
+
{moment(x.date).format('MMMM YYYY')}
)}
diff --git a/src/templates/blocks/References/ReferencesB.js b/src/templates/blocks/References/ReferencesB.js
new file mode 100644
index 00000000..b5de74fd
--- /dev/null
+++ b/src/templates/blocks/References/ReferencesB.js
@@ -0,0 +1,31 @@
+import React, { memo, useContext } from 'react';
+import ReactMarkdown from 'react-markdown';
+import PageContext from '../../../contexts/PageContext';
+import { safetyCheck } from '../../../utils';
+
+const ReferenceItem = (x) => (
+
+
{x.name}
+ {x.position}
+ {x.phone}
+ {x.email}
+ {x.summary && (
+
+ )}
+
+);
+
+const ReferencesB = () => {
+ const { data, heading: Heading } = useContext(PageContext);
+
+ return safetyCheck(data.references) ? (
+
+
{data.references.heading}
+
+ {data.references.items.map(ReferenceItem)}
+
+
+ ) : null;
+};
+
+export default memo(ReferencesB);
diff --git a/src/templates/blocks/Skills/SkillsB.js b/src/templates/blocks/Skills/SkillsB.js
new file mode 100644
index 00000000..32c39ed4
--- /dev/null
+++ b/src/templates/blocks/Skills/SkillsB.js
@@ -0,0 +1,22 @@
+import React, { memo, useContext } from 'react';
+import PageContext from '../../../contexts/PageContext';
+import { safetyCheck } from '../../../utils';
+
+const SkillItem = (x) => (
+
+ {x.skill}
+
+);
+
+const SkillsA = () => {
+ const { data, heading: Heading } = useContext(PageContext);
+
+ return safetyCheck(data.skills) ? (
+
+
{data.skills.heading}
+
{data.skills.items.map(SkillItem)}
+
+ ) : null;
+};
+
+export default memo(SkillsA);
diff --git a/src/templates/blocks/Work/WorkA.js b/src/templates/blocks/Work/WorkA.js
index bc5d108c..0f6fa830 100644
--- a/src/templates/blocks/Work/WorkA.js
+++ b/src/templates/blocks/Work/WorkA.js
@@ -11,7 +11,7 @@ const WorkItem = (x) => (
{x.position}
{x.startDate && (
-
+
({formatDateRange({ startDate: x.startDate, endDate: x.endDate })})
)}
diff --git a/src/utils/index.js b/src/utils/index.js
index c33eb328..86b25647 100644
--- a/src/utils/index.js
+++ b/src/utils/index.js
@@ -30,6 +30,19 @@ export const getFieldProps = (formik, schema, name) => ({
...formik.getFieldProps(name),
});
+export const hexToRgb = (hex) => {
+ const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
+ hex = hex.replace(shorthandRegex, (m, r, g, b) => r + r + g + g + b + b);
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
+ return result
+ ? {
+ r: parseInt(result[1], 16),
+ g: parseInt(result[2], 16),
+ b: parseInt(result[3], 16),
+ }
+ : null;
+};
+
export const reorder = (list, startIndex, endIndex) => {
const result = Array.from(list);
const [removed] = result.splice(startIndex, 1);