mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2025-11-14 08:42:08 +10:00
add enable/disable checkbox, and heading modifier
This commit is contained in:
@ -15,10 +15,12 @@
|
||||
"email": "hello@amruthpillai.com"
|
||||
},
|
||||
"objective": {
|
||||
"enable": true,
|
||||
"heading": "Objective",
|
||||
"body": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Quis deserunt fuga qui perspiciatis magni obcaecati libero ullam lorem, ipsum dolor sit amet consectetur adipisicing elit, voluptate dolores. Lorem ipsum dolor sit amet consectetur adipisicing elit. Assumenda maiores reiciendis, iusto cupiditate, laborum optio nesciunt corrupti, libero numquam a impedit totam magnam ipsum ducimus quas labore ea? Labore, eum."
|
||||
},
|
||||
"work": {
|
||||
"enable": true,
|
||||
"heading": "Work Experience",
|
||||
"items": [
|
||||
{
|
||||
@ -40,6 +42,7 @@
|
||||
]
|
||||
},
|
||||
"education": {
|
||||
"enable": true,
|
||||
"heading": "Education",
|
||||
"items": [
|
||||
{
|
||||
@ -63,6 +66,7 @@
|
||||
]
|
||||
},
|
||||
"awards": {
|
||||
"enable": true,
|
||||
"heading": "Honors & Awards",
|
||||
"items": [
|
||||
{
|
||||
@ -78,6 +82,7 @@
|
||||
]
|
||||
},
|
||||
"certifications": {
|
||||
"enable": true,
|
||||
"heading": "Certifications",
|
||||
"items": [
|
||||
{
|
||||
@ -93,6 +98,7 @@
|
||||
]
|
||||
},
|
||||
"skills": {
|
||||
"enable": true,
|
||||
"heading": "Skills & Hobbies",
|
||||
"items": [
|
||||
"Photography",
|
||||
@ -106,6 +112,7 @@
|
||||
]
|
||||
},
|
||||
"extras": {
|
||||
"enable": true,
|
||||
"heading": "Personal Information",
|
||||
"items": [
|
||||
{
|
||||
|
||||
@ -608,14 +608,6 @@ video {
|
||||
}
|
||||
}
|
||||
|
||||
.heading {
|
||||
font-size: 0.75rem;
|
||||
color: #718096;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.sr-only {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
|
||||
@ -27,7 +27,7 @@ const LeftSidebar = () => {
|
||||
const { state, dispatch } = context;
|
||||
const { data } = state;
|
||||
|
||||
const [currentTab, setCurrentTab] = useState('Extras');
|
||||
const [currentTab, setCurrentTab] = useState('Objective');
|
||||
const onChange = (key, value) => {
|
||||
dispatch({
|
||||
type: 'on_input',
|
||||
|
||||
@ -4,6 +4,7 @@ import set from 'lodash/set';
|
||||
|
||||
import TextField from '../../../shared/TextField';
|
||||
import AppContext from '../../../context/AppContext';
|
||||
import Checkbox from '../../../shared/Checkbox';
|
||||
|
||||
const AwardsTab = ({ data, onChange }) => {
|
||||
const context = useContext(AppContext);
|
||||
@ -11,6 +12,24 @@ const AwardsTab = ({ data, onChange }) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="grid grid-cols-6 items-center">
|
||||
<div className="col-span-1">
|
||||
<Checkbox
|
||||
checked={data.awards.enable}
|
||||
onChange={v => onChange('data.awards.enable', v)}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-span-5">
|
||||
<TextField
|
||||
placeholder="Heading"
|
||||
value={data.awards.heading}
|
||||
onChange={v => onChange('data.awards.heading', v)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr className="my-6" />
|
||||
|
||||
{data.awards.items.map((x, index) => (
|
||||
<Item
|
||||
item={x}
|
||||
|
||||
@ -4,6 +4,7 @@ import set from 'lodash/set';
|
||||
|
||||
import TextField from '../../../shared/TextField';
|
||||
import AppContext from '../../../context/AppContext';
|
||||
import Checkbox from '../../../shared/Checkbox';
|
||||
|
||||
const CertificationsTab = ({ data, onChange }) => {
|
||||
const context = useContext(AppContext);
|
||||
@ -11,6 +12,24 @@ const CertificationsTab = ({ data, onChange }) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="grid grid-cols-6 items-center">
|
||||
<div className="col-span-1">
|
||||
<Checkbox
|
||||
checked={data.certifications.enable}
|
||||
onChange={v => onChange('data.certifications.enable', v)}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-span-5">
|
||||
<TextField
|
||||
placeholder="Heading"
|
||||
value={data.certifications.heading}
|
||||
onChange={v => onChange('data.certifications.heading', v)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr className="my-6" />
|
||||
|
||||
{data.certifications.items.map((x, index) => (
|
||||
<Item
|
||||
item={x}
|
||||
|
||||
@ -5,6 +5,7 @@ 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';
|
||||
|
||||
const EducationTab = ({ data, onChange }) => {
|
||||
const context = useContext(AppContext);
|
||||
@ -12,6 +13,24 @@ const EducationTab = ({ data, onChange }) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="grid grid-cols-6 items-center">
|
||||
<div className="col-span-1">
|
||||
<Checkbox
|
||||
checked={data.education.enable}
|
||||
onChange={v => onChange('data.education.enable', v)}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-span-5">
|
||||
<TextField
|
||||
placeholder="Heading"
|
||||
value={data.education.heading}
|
||||
onChange={v => onChange('data.education.heading', v)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr className="my-6" />
|
||||
|
||||
{data.education.items.map((x, index) => (
|
||||
<Item
|
||||
item={x}
|
||||
|
||||
@ -4,6 +4,7 @@ import set from 'lodash/set';
|
||||
|
||||
import TextField from '../../../shared/TextField';
|
||||
import AppContext from '../../../context/AppContext';
|
||||
import Checkbox from '../../../shared/Checkbox';
|
||||
|
||||
const ExtrasTab = ({ data, onChange }) => {
|
||||
const context = useContext(AppContext);
|
||||
@ -11,6 +12,24 @@ const ExtrasTab = ({ data, onChange }) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="grid grid-cols-6 items-center">
|
||||
<div className="col-span-1">
|
||||
<Checkbox
|
||||
checked={data.extras.enable}
|
||||
onChange={v => onChange('data.extras.enable', v)}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-span-5">
|
||||
<TextField
|
||||
placeholder="Heading"
|
||||
value={data.extras.heading}
|
||||
onChange={v => onChange('data.extras.heading', v)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr className="my-6" />
|
||||
|
||||
{data.extras.items.map((x, index) => (
|
||||
<Item
|
||||
item={x}
|
||||
|
||||
@ -1,9 +1,29 @@
|
||||
import React from 'react';
|
||||
import TextArea from '../../../shared/TextArea';
|
||||
import TextField from '../../../shared/TextField';
|
||||
import Checkbox from '../../../shared/Checkbox';
|
||||
|
||||
const ObjectiveTab = ({ data, onChange }) => {
|
||||
return (
|
||||
<div>
|
||||
<div className="grid grid-cols-6 items-center">
|
||||
<div className="col-span-1">
|
||||
<Checkbox
|
||||
checked={data.objective.enable}
|
||||
onChange={v => onChange('data.objective.enable', v)}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-span-5">
|
||||
<TextField
|
||||
placeholder="Heading"
|
||||
value={data.objective.heading}
|
||||
onChange={v => onChange('data.objective.heading', v)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr className="my-6" />
|
||||
|
||||
<TextArea
|
||||
rows="15"
|
||||
label="Objective"
|
||||
|
||||
@ -4,6 +4,7 @@ import TextField from '../../../shared/TextField';
|
||||
const ProfileTab = ({ data, onChange }) => (
|
||||
<div>
|
||||
<TextField
|
||||
className="mb-4"
|
||||
label="Photo URL"
|
||||
placeholder="https://i.imgur.com/..."
|
||||
value={data.profile.photo}
|
||||
@ -12,6 +13,7 @@ const ProfileTab = ({ data, onChange }) => (
|
||||
|
||||
<div className="grid grid-cols-2 col-gap-4">
|
||||
<TextField
|
||||
className="mb-4"
|
||||
label="First Name"
|
||||
placeholder="Jane"
|
||||
value={data.profile.firstName}
|
||||
@ -19,6 +21,7 @@ const ProfileTab = ({ data, onChange }) => (
|
||||
/>
|
||||
|
||||
<TextField
|
||||
className="mb-4"
|
||||
label="Last Name"
|
||||
placeholder="Doe"
|
||||
value={data.profile.lastName}
|
||||
@ -27,6 +30,7 @@ const ProfileTab = ({ data, onChange }) => (
|
||||
</div>
|
||||
|
||||
<TextField
|
||||
className="mb-4"
|
||||
label="Subtitle"
|
||||
placeholder="Full Stack Web Developer"
|
||||
value={data.profile.subtitle}
|
||||
@ -36,6 +40,7 @@ const ProfileTab = ({ data, onChange }) => (
|
||||
<hr className="my-6" />
|
||||
|
||||
<TextField
|
||||
className="mb-4"
|
||||
label="Address Line 1"
|
||||
placeholder="Palladium Complex"
|
||||
value={data.profile.address.line1}
|
||||
@ -43,6 +48,7 @@ const ProfileTab = ({ data, onChange }) => (
|
||||
/>
|
||||
|
||||
<TextField
|
||||
className="mb-4"
|
||||
label="Address Line 2"
|
||||
placeholder="140 E 14th St"
|
||||
value={data.profile.address.line2}
|
||||
@ -50,6 +56,7 @@ const ProfileTab = ({ data, onChange }) => (
|
||||
/>
|
||||
|
||||
<TextField
|
||||
className="mb-4"
|
||||
label="Address Line 3"
|
||||
placeholder="New York, NY 10003 USA"
|
||||
value={data.profile.address.line3}
|
||||
@ -59,6 +66,7 @@ const ProfileTab = ({ data, onChange }) => (
|
||||
<hr className="my-6" />
|
||||
|
||||
<TextField
|
||||
className="mb-4"
|
||||
label="Phone Number"
|
||||
placeholder="+1 541 754 3010"
|
||||
value={data.profile.phone}
|
||||
@ -66,6 +74,7 @@ const ProfileTab = ({ data, onChange }) => (
|
||||
/>
|
||||
|
||||
<TextField
|
||||
className="mb-4"
|
||||
label="Website"
|
||||
placeholder="google.com"
|
||||
value={data.profile.website}
|
||||
@ -73,6 +82,7 @@ const ProfileTab = ({ data, onChange }) => (
|
||||
/>
|
||||
|
||||
<TextField
|
||||
className="mb-4"
|
||||
label="Email Address"
|
||||
placeholder="john.doe@example.com"
|
||||
value={data.profile.email}
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
import React, { useState, useContext } from 'react';
|
||||
|
||||
import AppContext from '../../../context/AppContext';
|
||||
import Checkbox from '../../../shared/Checkbox';
|
||||
import TextField from '../../../shared/TextField';
|
||||
|
||||
const SkillsTab = ({ data, onChange }) => {
|
||||
const context = useContext(AppContext);
|
||||
@ -8,6 +10,24 @@ const SkillsTab = ({ data, onChange }) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="grid grid-cols-6 items-center">
|
||||
<div className="col-span-1">
|
||||
<Checkbox
|
||||
checked={data.skills.enable}
|
||||
onChange={v => onChange('data.skills.enable', v)}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-span-5">
|
||||
<TextField
|
||||
placeholder="Heading"
|
||||
value={data.skills.heading}
|
||||
onChange={v => onChange('data.skills.heading', v)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr className="my-6" />
|
||||
|
||||
{data.skills.items.map((x, index) => (
|
||||
<Item item={x} key={x} index={index} onChange={onChange} dispatch={dispatch} />
|
||||
))}
|
||||
|
||||
@ -5,6 +5,7 @@ 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';
|
||||
|
||||
const WorkTab = ({ data, onChange }) => {
|
||||
const context = useContext(AppContext);
|
||||
@ -12,6 +13,21 @@ const WorkTab = ({ data, onChange }) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="grid grid-cols-6 items-center">
|
||||
<div className="col-span-1">
|
||||
<Checkbox checked={data.work.enable} onChange={v => onChange('data.work.enable', v)} />
|
||||
</div>
|
||||
<div className="col-span-5">
|
||||
<TextField
|
||||
placeholder="Heading"
|
||||
value={data.work.heading}
|
||||
onChange={v => onChange('data.work.heading', v)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr className="my-6" />
|
||||
|
||||
{data.work.items.map((x, index) => (
|
||||
<Item
|
||||
item={x}
|
||||
|
||||
@ -26,30 +26,37 @@ const initialState = {
|
||||
email: '',
|
||||
},
|
||||
objective: {
|
||||
enable: false,
|
||||
heading: 'Objective',
|
||||
body: '',
|
||||
},
|
||||
work: {
|
||||
enable: false,
|
||||
heading: 'Work Experience',
|
||||
items: [],
|
||||
},
|
||||
education: {
|
||||
enable: false,
|
||||
heading: 'Education',
|
||||
items: [],
|
||||
},
|
||||
awards: {
|
||||
enable: false,
|
||||
heading: 'Honors & Awards',
|
||||
items: [],
|
||||
},
|
||||
certifications: {
|
||||
enable: false,
|
||||
heading: 'Certifications',
|
||||
items: [],
|
||||
},
|
||||
skills: {
|
||||
enable: false,
|
||||
heading: 'Skills & Hobbies',
|
||||
items: [],
|
||||
},
|
||||
extras: {
|
||||
enable: false,
|
||||
heading: 'Personal Information',
|
||||
items: [],
|
||||
},
|
||||
|
||||
@ -8,6 +8,10 @@ body {
|
||||
}
|
||||
|
||||
@media screen {
|
||||
input:checked + i.material-icons {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#sidebar {
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
19
src/shared/Checkbox.js
Normal file
19
src/shared/Checkbox.js
Normal file
@ -0,0 +1,19 @@
|
||||
import React from 'react';
|
||||
|
||||
const Checkbox = ({ checked, onChange }) => {
|
||||
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">
|
||||
<input
|
||||
type="checkbox"
|
||||
className="w-8 h-8 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>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Checkbox;
|
||||
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
|
||||
const TextArea = ({ label, placeholder, value, onChange, rows = 5 }) => (
|
||||
<div className="my-4 w-full flex flex-col">
|
||||
const TextArea = ({ label, placeholder, value, onChange, className, rows = 5 }) => (
|
||||
<div className={`w-full flex flex-col ${className}`}>
|
||||
<label className="uppercase tracking-wide text-gray-600 text-xs font-semibold mb-2">
|
||||
{label}
|
||||
</label>
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
import React from 'react';
|
||||
|
||||
const TextField = ({ label, placeholder, value, onChange }) => (
|
||||
<div className="my-4 w-full flex flex-col">
|
||||
const TextField = ({ label, placeholder, value, onChange, className }) => (
|
||||
<div className={`w-full flex flex-col ${className}`}>
|
||||
{label && (
|
||||
<label className="uppercase tracking-wide text-gray-600 text-xs font-semibold mb-2">
|
||||
{label}
|
||||
</label>
|
||||
)}
|
||||
<input
|
||||
className="appearance-none block w-full bg-gray-200 text-gray-800 border border-gray-200 rounded py-3 px-4 leading-tight focus:outline-none focus:bg-white focus:border-gray-500"
|
||||
type="text"
|
||||
|
||||
@ -38,35 +38,53 @@ const Onyx = () => {
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-span-1 text-xs">
|
||||
{data.profile.phone && (
|
||||
<div className="flex items-center my-3">
|
||||
<span className="material-icons text-lg mr-2" style={{ color: theme.colors.accent }}>
|
||||
phone
|
||||
</span>
|
||||
<span className="font-medium">{data.profile.phone}</span>
|
||||
</div>
|
||||
)}
|
||||
{data.profile.website && (
|
||||
<div className="flex items-center my-3">
|
||||
<span className="material-icons text-lg mr-2" style={{ color: theme.colors.accent }}>
|
||||
language
|
||||
</span>
|
||||
<span className="font-medium">{data.profile.website}</span>
|
||||
</div>
|
||||
)}
|
||||
{data.profile.email && (
|
||||
<div className="flex items-center my-3">
|
||||
<span className="material-icons text-lg mr-2" style={{ color: theme.colors.accent }}>
|
||||
alternate_email
|
||||
</span>
|
||||
<span className="font-medium">{data.profile.email}</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr className="my-6" />
|
||||
|
||||
<h6 className="text-xs font-bold uppercase mt-6 mb-2" style={{ color: theme.colors.accent }}>
|
||||
{data.objective.enable && (
|
||||
<div>
|
||||
<h6
|
||||
className="text-xs font-bold uppercase mt-6 mb-2"
|
||||
style={{ color: theme.colors.accent }}
|
||||
>
|
||||
{data.objective.heading}
|
||||
</h6>
|
||||
<p className="text-sm">{data.objective.body}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<h6 className="text-xs font-bold uppercase mt-6 mb-2" style={{ color: theme.colors.accent }}>
|
||||
{data.work.enable && (
|
||||
<div>
|
||||
<h6
|
||||
className="text-xs font-bold uppercase mt-6 mb-2"
|
||||
style={{ color: theme.colors.accent }}
|
||||
>
|
||||
{data.work.heading}
|
||||
</h6>
|
||||
{data.work.items.map(exp => (
|
||||
@ -83,8 +101,15 @@ const Onyx = () => {
|
||||
<p className="mt-2 text-sm">{exp.description}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<h6 className="text-xs font-bold uppercase mt-6 mb-2" style={{ color: theme.colors.accent }}>
|
||||
{data.education.enable && (
|
||||
<div>
|
||||
<h6
|
||||
className="text-xs font-bold uppercase mt-6 mb-2"
|
||||
style={{ color: theme.colors.accent }}
|
||||
>
|
||||
{data.education.heading}
|
||||
</h6>
|
||||
{data.education.items.map(edu => (
|
||||
@ -104,8 +129,11 @@ const Onyx = () => {
|
||||
<p className="mt-2 text-sm">{edu.description}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="grid grid-cols-2">
|
||||
{data.awards.enable && (
|
||||
<div>
|
||||
<h6
|
||||
className="text-xs font-bold uppercase mt-6 mb-2"
|
||||
@ -120,7 +148,9 @@ const Onyx = () => {
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{data.certifications.enable && (
|
||||
<div>
|
||||
<h6
|
||||
className="text-xs font-bold uppercase mt-6 mb-2"
|
||||
@ -135,9 +165,15 @@ const Onyx = () => {
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<h6 className="text-xs font-bold uppercase mt-6 mb-2" style={{ color: theme.colors.accent }}>
|
||||
{data.skills.enable && (
|
||||
<div>
|
||||
<h6
|
||||
className="text-xs font-bold uppercase mt-6 mb-2"
|
||||
style={{ color: theme.colors.accent }}
|
||||
>
|
||||
{data.skills.heading}
|
||||
</h6>
|
||||
<div className="mt-1 flex flex-wrap">
|
||||
@ -151,8 +187,15 @@ const Onyx = () => {
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<h6 className="text-xs font-bold uppercase mt-6 mb-2" style={{ color: theme.colors.accent }}>
|
||||
{data.extras.enable && (
|
||||
<div>
|
||||
<h6
|
||||
className="text-xs font-bold uppercase mt-6 mb-2"
|
||||
style={{ color: theme.colors.accent }}
|
||||
>
|
||||
{data.extras.heading}
|
||||
</h6>
|
||||
<table className="w-2/3 table-auto">
|
||||
@ -166,6 +209,8 @@ const Onyx = () => {
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user