mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2025-11-24 05:32:03 +10:00
- implement i18n
- translation dynamic for sections - added articles for SEO
This commit is contained in:
@ -1,5 +1,6 @@
|
||||
import { Formik } from 'formik';
|
||||
import React, { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import * as Yup from 'yup';
|
||||
import Input from '../../components/shared/Input';
|
||||
import ModalEvents from '../../constants/ModalEvents';
|
||||
@ -13,14 +14,16 @@ const initialValues = {
|
||||
summary: '',
|
||||
};
|
||||
|
||||
const schema = Yup.object().shape({
|
||||
title: Yup.string().required('This is a required field.'),
|
||||
awarder: Yup.string().required('This is a required field.'),
|
||||
date: Yup.date().max(new Date()),
|
||||
summary: Yup.string(),
|
||||
});
|
||||
|
||||
const AwardModal = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const schema = Yup.object().shape({
|
||||
title: Yup.string().required(t('shared.forms.validation.required')),
|
||||
awarder: Yup.string().required(t('shared.forms.validation.required')),
|
||||
date: Yup.date().max(new Date()),
|
||||
summary: Yup.string(),
|
||||
});
|
||||
|
||||
return (
|
||||
<Formik
|
||||
validateOnBlur
|
||||
@ -29,33 +32,33 @@ const AwardModal = () => {
|
||||
>
|
||||
{(formik) => (
|
||||
<DataModal
|
||||
name="Award"
|
||||
name={t('builder.sections.award')}
|
||||
path="awards.items"
|
||||
event={ModalEvents.AWARD_MODAL}
|
||||
>
|
||||
<div className="grid grid-cols-2 gap-8">
|
||||
<Input
|
||||
label="Title"
|
||||
label={t('shared.forms.title')}
|
||||
className="col-span-2"
|
||||
placeholder="Intl. Flutter Hackathon '19"
|
||||
{...getFieldProps(formik, schema, 'title')}
|
||||
/>
|
||||
|
||||
<Input
|
||||
label="Awarder"
|
||||
label={t('builder.awards.awarder')}
|
||||
placeholder="Google"
|
||||
{...getFieldProps(formik, schema, 'awarder')}
|
||||
/>
|
||||
|
||||
<Input
|
||||
type="date"
|
||||
label="Date"
|
||||
label={t('shared.forms.date')}
|
||||
{...getFieldProps(formik, schema, 'date')}
|
||||
/>
|
||||
|
||||
<Input
|
||||
type="textarea"
|
||||
label="Summary"
|
||||
label={t('shared.forms.summary')}
|
||||
className="col-span-2"
|
||||
{...getFieldProps(formik, schema, 'summary')}
|
||||
/>
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { Formik } from 'formik';
|
||||
import React, { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import * as Yup from 'yup';
|
||||
import Input from '../../components/shared/Input';
|
||||
import ModalEvents from '../../constants/ModalEvents';
|
||||
@ -13,14 +14,16 @@ const initialValues = {
|
||||
summary: '',
|
||||
};
|
||||
|
||||
const schema = Yup.object().shape({
|
||||
title: Yup.string().required('This is a required field.'),
|
||||
issuer: Yup.string().required('This is a required field.'),
|
||||
date: Yup.date().max(new Date()),
|
||||
summary: Yup.string(),
|
||||
});
|
||||
|
||||
const CertificateModal = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const schema = Yup.object().shape({
|
||||
title: Yup.string().required(t('shared.forms.validation.required')),
|
||||
issuer: Yup.string().required(t('shared.forms.validation.required')),
|
||||
date: Yup.date().max(new Date()),
|
||||
summary: Yup.string(),
|
||||
});
|
||||
|
||||
return (
|
||||
<Formik
|
||||
validateOnBlur
|
||||
@ -29,33 +32,33 @@ const CertificateModal = () => {
|
||||
>
|
||||
{(formik) => (
|
||||
<DataModal
|
||||
name="Certificate"
|
||||
name={t('builder.sections.certification')}
|
||||
path="certifications.items"
|
||||
event={ModalEvents.CERTIFICATION_MODAL}
|
||||
>
|
||||
<div className="grid grid-cols-2 gap-8">
|
||||
<Input
|
||||
label="Title"
|
||||
label={t('shared.forms.title')}
|
||||
className="col-span-2"
|
||||
placeholder="CCNP"
|
||||
{...getFieldProps(formik, schema, 'title')}
|
||||
/>
|
||||
|
||||
<Input
|
||||
label="Issuer"
|
||||
label={t('builder.certifications.issuer')}
|
||||
placeholder="Cisco Systems"
|
||||
{...getFieldProps(formik, schema, 'issuer')}
|
||||
/>
|
||||
|
||||
<Input
|
||||
type="date"
|
||||
label="Date"
|
||||
label={t('shared.forms.date')}
|
||||
{...getFieldProps(formik, schema, 'date')}
|
||||
/>
|
||||
|
||||
<Input
|
||||
type="textarea"
|
||||
label="Summary"
|
||||
label={t('shared.forms.summary')}
|
||||
className="col-span-2"
|
||||
{...getFieldProps(formik, schema, 'summary')}
|
||||
/>
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { Formik } from 'formik';
|
||||
import React, { memo } from 'react';
|
||||
import * as Yup from 'yup';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import Input from '../../components/shared/Input';
|
||||
import ModalEvents from '../../constants/ModalEvents';
|
||||
import { getFieldProps } from '../../utils';
|
||||
@ -16,22 +17,27 @@ const initialValues = {
|
||||
summary: '',
|
||||
};
|
||||
|
||||
const schema = Yup.object().shape({
|
||||
institution: Yup.string().required('This is a required field.'),
|
||||
field: Yup.string().required('This is a required field.'),
|
||||
degree: Yup.string(),
|
||||
gpa: Yup.string(),
|
||||
startDate: Yup.date().required('This is a required field.'),
|
||||
endDate: Yup.date().when(
|
||||
'startDate',
|
||||
(startDate, yupSchema) =>
|
||||
startDate &&
|
||||
yupSchema.min(startDate, 'End Date must be later than Start Date'),
|
||||
),
|
||||
summary: Yup.string().min(10, 'Please enter at least 10 characters.'),
|
||||
});
|
||||
|
||||
const EducationModal = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const schema = Yup.object().shape({
|
||||
institution: Yup.string().required(t('shared.forms.validation.required')),
|
||||
field: Yup.string().required(t('shared.forms.validation.required')),
|
||||
degree: Yup.string(),
|
||||
gpa: Yup.string(),
|
||||
startDate: Yup.date().required(t('shared.forms.validation.required')),
|
||||
endDate: Yup.date().when(
|
||||
'startDate',
|
||||
(startDate, yupSchema) =>
|
||||
startDate &&
|
||||
yupSchema.min(startDate, t('shared.forms.validation.dateRange')),
|
||||
),
|
||||
summary: Yup.string().min(
|
||||
10,
|
||||
t('shared.forms.validation.min', { number: 10 }),
|
||||
),
|
||||
});
|
||||
|
||||
return (
|
||||
<Formik
|
||||
validateOnBlur
|
||||
@ -40,54 +46,54 @@ const EducationModal = () => {
|
||||
>
|
||||
{(formik) => (
|
||||
<DataModal
|
||||
name="Education"
|
||||
name={t('builder.sections.education')}
|
||||
path="education.items"
|
||||
event={ModalEvents.EDUCATION_MODAL}
|
||||
>
|
||||
<div className="grid grid-cols-2 gap-8">
|
||||
<Input
|
||||
label="Institution"
|
||||
label={t('builder.education.institution')}
|
||||
className="col-span-2"
|
||||
placeholder="Dayananda Sagar College of Engineering"
|
||||
{...getFieldProps(formik, schema, 'institution')}
|
||||
/>
|
||||
|
||||
<Input
|
||||
label="Field of Study"
|
||||
label={t('builder.education.field')}
|
||||
className="col-span-2"
|
||||
placeholder="Computer Science & Engineering"
|
||||
{...getFieldProps(formik, schema, 'field')}
|
||||
/>
|
||||
|
||||
<Input
|
||||
label="Degree Type"
|
||||
label={t('builder.education.degree')}
|
||||
placeholder="Bachelor's Degree"
|
||||
{...getFieldProps(formik, schema, 'degree')}
|
||||
/>
|
||||
|
||||
<Input
|
||||
label="GPA"
|
||||
label={t('builder.education.gpa')}
|
||||
placeholder="8.8"
|
||||
{...getFieldProps(formik, schema, 'gpa')}
|
||||
/>
|
||||
|
||||
<Input
|
||||
type="date"
|
||||
label="Start Date"
|
||||
label={t('shared.forms.startDate')}
|
||||
placeholder="6th August 208"
|
||||
{...getFieldProps(formik, schema, 'startDate')}
|
||||
/>
|
||||
|
||||
<Input
|
||||
type="date"
|
||||
label="End Date"
|
||||
label={t('shared.forms.endDate')}
|
||||
placeholder="6th August 208"
|
||||
{...getFieldProps(formik, schema, 'endDate')}
|
||||
/>
|
||||
|
||||
<Input
|
||||
type="textarea"
|
||||
label="Summary"
|
||||
label={t('shared.forms.summary')}
|
||||
className="col-span-2"
|
||||
{...getFieldProps(formik, schema, 'summary')}
|
||||
/>
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import firebase from 'gatsby-plugin-firebase';
|
||||
import { clone } from 'lodash';
|
||||
import React, { memo, useContext, useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { FaPrint } from 'react-icons/fa';
|
||||
import Button from '../../components/shared/Button';
|
||||
import ModalContext from '../../contexts/ModalContext';
|
||||
@ -10,6 +11,7 @@ import BaseModal from '../BaseModal';
|
||||
|
||||
const ExportModal = () => {
|
||||
const state = useSelector();
|
||||
const { t } = useTranslation();
|
||||
const [open, setOpen] = useState(false);
|
||||
const [isLoadingSingle, setLoadingSingle] = useState(false);
|
||||
const [isLoadingMulti, setLoadingMulti] = useState(false);
|
||||
@ -72,35 +74,31 @@ const ExportModal = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<BaseModal hideActions state={[open, setOpen]} title="Export Your Resume">
|
||||
<BaseModal
|
||||
hideActions
|
||||
state={[open, setOpen]}
|
||||
title={t('builder.actions.export.heading')}
|
||||
>
|
||||
<div>
|
||||
<h5 className="text-xl font-semibold mb-4">
|
||||
Use Browser's Print Dialog
|
||||
{t('modals.export.printDialog.heading')}
|
||||
</h5>
|
||||
|
||||
<p className="leading-loose">
|
||||
For those of you who want a quick solution, you need not look any
|
||||
further than your browser. All you have to do is press Ctrl/Cmd + P
|
||||
and open up the print dialog on your browser and get your resume
|
||||
printed immediately.
|
||||
</p>
|
||||
<p className="leading-loose">{t('modals.export.printDialog.text')}</p>
|
||||
|
||||
<Button icon={FaPrint} className="mt-5" onClick={handleOpenPrintDialog}>
|
||||
Print Resume
|
||||
{t('modals.export.printDialog.button')}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<hr className="my-8" />
|
||||
|
||||
<div>
|
||||
<h5 className="text-xl font-semibold mb-4">Download PDF</h5>
|
||||
<h5 className="text-xl font-semibold mb-4">
|
||||
{t('modals.export.downloadPDF.heading')}
|
||||
</h5>
|
||||
|
||||
<p className="leading-loose">
|
||||
These options allow you to print a single page, unconstrained version
|
||||
of your resume, perfect for those who have a lot of content.
|
||||
Alternatively, you could download a multi-page version of your resume
|
||||
as well with just one click.
|
||||
</p>
|
||||
<p className="leading-loose">{t('modals.export.downloadPDF.text')}</p>
|
||||
|
||||
<div className="mt-5 mb-4">
|
||||
<div className="flex">
|
||||
@ -108,14 +106,14 @@ const ExportModal = () => {
|
||||
isLoading={isLoadingSingle}
|
||||
onClick={handleSinglePageDownload}
|
||||
>
|
||||
Single Page Resume
|
||||
{t('modals.export.downloadPDF.buttons.single')}
|
||||
</Button>
|
||||
<Button
|
||||
className="ml-8"
|
||||
isLoading={isLoadingMulti}
|
||||
onClick={handleMultiPageDownload}
|
||||
>
|
||||
Multi Page Resume
|
||||
{t('modals.export.downloadPDF.buttons.multi')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
@ -124,18 +122,18 @@ const ExportModal = () => {
|
||||
<hr className="my-8" />
|
||||
|
||||
<div>
|
||||
<h5 className="text-xl font-semibold mb-4">Export to JSON Format</h5>
|
||||
<h5 className="text-xl font-semibold mb-4">
|
||||
{t('modals.export.jsonFormat.heading')}
|
||||
</h5>
|
||||
|
||||
<p className="leading-loose">
|
||||
You can also export your data into JSON format for safe keeping so
|
||||
that you can easily import it back into Reactive Resume whenever you
|
||||
want to edit or generate a resume.
|
||||
</p>
|
||||
<p className="leading-loose">{t('modals.export.jsonFormat.text')}</p>
|
||||
|
||||
<div className="mt-5">
|
||||
<Button onClick={handleExportToJson}>Export JSON</Button>
|
||||
<Button onClick={handleExportToJson}>
|
||||
{t('modals.export.jsonFormat.button')}
|
||||
</Button>
|
||||
<a id="downloadAnchor" className="hidden">
|
||||
Export JSON
|
||||
{t('modals.export.jsonFormat.button')}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { Formik } from 'formik';
|
||||
import React, { memo } from 'react';
|
||||
import * as Yup from 'yup';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import Input from '../../components/shared/Input';
|
||||
import ModalEvents from '../../constants/ModalEvents';
|
||||
import { getFieldProps } from '../../utils';
|
||||
@ -10,11 +11,13 @@ const initialValues = {
|
||||
name: '',
|
||||
};
|
||||
|
||||
const schema = Yup.object().shape({
|
||||
name: Yup.string().required('This is a required field.'),
|
||||
});
|
||||
|
||||
const HobbyModal = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const schema = Yup.object().shape({
|
||||
name: Yup.string().required(t('shared.forms.validation.required')),
|
||||
});
|
||||
|
||||
return (
|
||||
<Formik
|
||||
validateOnBlur
|
||||
@ -23,13 +26,13 @@ const HobbyModal = () => {
|
||||
>
|
||||
{(formik) => (
|
||||
<DataModal
|
||||
name="Hobby"
|
||||
name={t('builder.sections.hobby')}
|
||||
path="hobbies.items"
|
||||
event={ModalEvents.HOBBY_MODAL}
|
||||
>
|
||||
<div className="grid grid-cols-2 gap-8">
|
||||
<Input
|
||||
label="Name"
|
||||
label={t('shared.forms.name')}
|
||||
placeholder="Fishing"
|
||||
className="col-span-2"
|
||||
{...getFieldProps(formik, schema, 'name')}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { Tooltip } from '@material-ui/core';
|
||||
import Ajv from 'ajv';
|
||||
import React, { memo, useContext, useEffect, useRef, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { toast } from 'react-toastify';
|
||||
import Button from '../../components/shared/Button';
|
||||
import ModalContext from '../../contexts/ModalContext';
|
||||
@ -10,6 +11,7 @@ import BaseModal from '../BaseModal';
|
||||
|
||||
const ImportModal = () => {
|
||||
const ajv = new Ajv();
|
||||
const { t } = useTranslation();
|
||||
const fileInputRef = useRef(null);
|
||||
const [open, setOpen] = useState(false);
|
||||
const dispatch = useDispatch();
|
||||
@ -38,21 +40,22 @@ const ImportModal = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<BaseModal hideActions state={[open, setOpen]} title="Import Your Resume">
|
||||
<BaseModal
|
||||
hideActions
|
||||
state={[open, setOpen]}
|
||||
title={t('builder.actions.import.heading')}
|
||||
>
|
||||
<div>
|
||||
<h5 className="text-xl font-semibold mb-4">
|
||||
Import from Reactive Resume
|
||||
{t('modals.import.reactiveResume.heading')}
|
||||
</h5>
|
||||
|
||||
<p>
|
||||
Reactive Resume has it's own schema format to make the most of
|
||||
all the customizable capabilities it has to offer. If you'd like
|
||||
to import a backup of your resume made with this app, just upload the
|
||||
file using the button below.
|
||||
<p className="leading-loose">
|
||||
{t('modals.import.reactiveResume.text')}
|
||||
</p>
|
||||
|
||||
<Button className="mt-5" onClick={() => fileInputRef.current.click()}>
|
||||
Select File
|
||||
{t('modals.import.button')}
|
||||
</Button>
|
||||
<input
|
||||
ref={fileInputRef}
|
||||
@ -65,18 +68,15 @@ const ImportModal = () => {
|
||||
<hr className="my-8" />
|
||||
|
||||
<div>
|
||||
<h5 className="text-xl font-semibold mb-4">Import from JSON Resume</h5>
|
||||
<h5 className="text-xl font-semibold mb-4">
|
||||
{t('modals.import.jsonResume.heading')}
|
||||
</h5>
|
||||
|
||||
<p>
|
||||
<a href="https://jsonresume.org/">JSON Resume</a> is an open standard
|
||||
for resume schema structure. If you are one of the many enthusiasts
|
||||
who have their resume ready in this format, all it takes it just one
|
||||
click to get started with Reactive Resume.
|
||||
</p>
|
||||
<p className="leading-loose">{t('modals.import.jsonResume.text')}</p>
|
||||
|
||||
<Tooltip title="Coming Soon" placement="right" arrow>
|
||||
<div className="mt-5 inline-block">
|
||||
<Button className="opacity-50">Select File</Button>
|
||||
<Button className="opacity-50">{t('modals.import.button')}</Button>
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
@ -84,16 +84,15 @@ const ImportModal = () => {
|
||||
<hr className="my-8" />
|
||||
|
||||
<div>
|
||||
<h5 className="text-xl font-semibold mb-4">Import from LinkedIn</h5>
|
||||
<h5 className="text-xl font-semibold mb-4">
|
||||
{t('modals.import.linkedIn.heading')}
|
||||
</h5>
|
||||
|
||||
<p>
|
||||
You can import a JSON that was exported from Reactive Resume by
|
||||
clicking on the button below and selecting the appropriate file.
|
||||
</p>
|
||||
<p className="leading-loose">{t('modals.import.linkedIn.text')}</p>
|
||||
|
||||
<Tooltip title="Coming Soon" placement="right" arrow>
|
||||
<div className="mt-5 inline-block">
|
||||
<Button className="opacity-50">Select File</Button>
|
||||
<Button className="opacity-50">{t('modals.import.button')}</Button>
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { Formik } from 'formik';
|
||||
import React, { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import * as Yup from 'yup';
|
||||
import Input from '../../components/shared/Input';
|
||||
import ModalEvents from '../../constants/ModalEvents';
|
||||
@ -11,12 +12,14 @@ const initialValues = {
|
||||
fluency: '',
|
||||
};
|
||||
|
||||
const schema = Yup.object().shape({
|
||||
name: Yup.string().required('This is a required field.'),
|
||||
fluency: Yup.string().required('This is a required field.'),
|
||||
});
|
||||
|
||||
const LanguageModal = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const schema = Yup.object().shape({
|
||||
name: Yup.string().required(t('shared.forms.validation.required')),
|
||||
fluency: Yup.string().required(t('shared.forms.validation.required')),
|
||||
});
|
||||
|
||||
return (
|
||||
<Formik
|
||||
validateOnBlur
|
||||
@ -25,19 +28,19 @@ const LanguageModal = () => {
|
||||
>
|
||||
{(formik) => (
|
||||
<DataModal
|
||||
name="Language"
|
||||
name={t('builder.sections.language')}
|
||||
path="languages.items"
|
||||
event={ModalEvents.LANGUAGE_MODAL}
|
||||
>
|
||||
<div className="grid grid-cols-2 gap-8">
|
||||
<Input
|
||||
label="Name"
|
||||
label={t('shared.forms.name')}
|
||||
placeholder="German"
|
||||
{...getFieldProps(formik, schema, 'name')}
|
||||
/>
|
||||
|
||||
<Input
|
||||
label="Fluency"
|
||||
label={t('builder.languages.fluency')}
|
||||
placeholder="Native/B1"
|
||||
{...getFieldProps(formik, schema, 'fluency')}
|
||||
/>
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { Formik } from 'formik';
|
||||
import React, { memo } from 'react';
|
||||
import * as Yup from 'yup';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import Input from '../../components/shared/Input';
|
||||
import ModalEvents from '../../constants/ModalEvents';
|
||||
import { getFieldProps } from '../../utils';
|
||||
@ -13,14 +14,16 @@ const initialValues = {
|
||||
summary: '',
|
||||
};
|
||||
|
||||
const schema = Yup.object().shape({
|
||||
title: Yup.string().required('This is a required field.'),
|
||||
link: Yup.string().url('Must be a valid URL'),
|
||||
date: Yup.date().max(new Date()),
|
||||
summary: Yup.string(),
|
||||
});
|
||||
|
||||
const ProjectModal = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const schema = Yup.object().shape({
|
||||
title: Yup.string().required(t('shared.forms.validation.required')),
|
||||
link: Yup.string().url(t('shared.forms.validation.url')),
|
||||
date: Yup.date().max(new Date()),
|
||||
summary: Yup.string(),
|
||||
});
|
||||
|
||||
return (
|
||||
<Formik
|
||||
validateOnBlur
|
||||
@ -29,33 +32,33 @@ const ProjectModal = () => {
|
||||
>
|
||||
{(formik) => (
|
||||
<DataModal
|
||||
name="Project"
|
||||
name={t('builder.sections.project')}
|
||||
path="projects.items"
|
||||
event={ModalEvents.PROJECT_MODAL}
|
||||
>
|
||||
<div className="grid grid-cols-2 gap-8">
|
||||
<Input
|
||||
label="Title"
|
||||
label={t('shared.forms.title')}
|
||||
className="col-span-2"
|
||||
placeholder="Reactive Resume"
|
||||
{...getFieldProps(formik, schema, 'title')}
|
||||
/>
|
||||
|
||||
<Input
|
||||
label="Link"
|
||||
label={t('shared.forms.website')}
|
||||
placeholder="https://github.com/AmruthPillai/Reactive-Resume"
|
||||
{...getFieldProps(formik, schema, 'link')}
|
||||
/>
|
||||
|
||||
<Input
|
||||
type="date"
|
||||
label="Date"
|
||||
label={t('shared.forms.date')}
|
||||
{...getFieldProps(formik, schema, 'date')}
|
||||
/>
|
||||
|
||||
<Input
|
||||
type="textarea"
|
||||
label="Summary"
|
||||
label={t('shared.forms.summary')}
|
||||
className="col-span-2"
|
||||
{...getFieldProps(formik, schema, 'summary')}
|
||||
/>
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { Formik } from 'formik';
|
||||
import React, { memo } from 'react';
|
||||
import * as Yup from 'yup';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import Input from '../../components/shared/Input';
|
||||
import ModalEvents from '../../constants/ModalEvents';
|
||||
import { getFieldProps } from '../../utils';
|
||||
@ -14,15 +15,17 @@ const initialValues = {
|
||||
summary: '',
|
||||
};
|
||||
|
||||
const schema = Yup.object().shape({
|
||||
name: Yup.string().required('This is a required field.'),
|
||||
position: Yup.string().required('This is a required field.'),
|
||||
phone: Yup.string(),
|
||||
email: Yup.string().email('Must be a valid email address.'),
|
||||
summary: Yup.string(),
|
||||
});
|
||||
|
||||
const ReferenceModal = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const schema = Yup.object().shape({
|
||||
name: Yup.string().required(t('shared.forms.validation.required')),
|
||||
position: Yup.string().required(t('shared.forms.validation.required')),
|
||||
phone: Yup.string(),
|
||||
email: Yup.string().email(t('shared.forms.validation.email')),
|
||||
summary: Yup.string(),
|
||||
});
|
||||
|
||||
return (
|
||||
<Formik
|
||||
validateOnBlur
|
||||
@ -31,38 +34,38 @@ const ReferenceModal = () => {
|
||||
>
|
||||
{(formik) => (
|
||||
<DataModal
|
||||
name="Reference"
|
||||
name={t('builder.sections.reference')}
|
||||
path="references.items"
|
||||
event={ModalEvents.REFERENCE_MODAL}
|
||||
>
|
||||
<div className="grid grid-cols-2 gap-8">
|
||||
<Input
|
||||
label="Name"
|
||||
label={t('shared.forms.name')}
|
||||
placeholder="Jane Doe"
|
||||
{...getFieldProps(formik, schema, 'name')}
|
||||
/>
|
||||
|
||||
<Input
|
||||
label="position"
|
||||
label={t('shared.forms.position')}
|
||||
placeholder="Assistant Manager"
|
||||
{...getFieldProps(formik, schema, 'position')}
|
||||
/>
|
||||
|
||||
<Input
|
||||
label="Phone Number"
|
||||
label={t('shared.forms.phone')}
|
||||
placeholder="+1 (708) 756-6065"
|
||||
{...getFieldProps(formik, schema, 'phone')}
|
||||
/>
|
||||
|
||||
<Input
|
||||
label="Email Address"
|
||||
label={t('shared.forms.email')}
|
||||
placeholder="janedoe@example.com"
|
||||
{...getFieldProps(formik, schema, 'email')}
|
||||
/>
|
||||
|
||||
<Input
|
||||
type="textarea"
|
||||
label="Summary"
|
||||
label={t('shared.forms.summary')}
|
||||
className="col-span-2"
|
||||
{...getFieldProps(formik, schema, 'summary')}
|
||||
/>
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { Formik } from 'formik';
|
||||
import React, { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import * as Yup from 'yup';
|
||||
import Input from '../../components/shared/Input';
|
||||
import ModalEvents from '../../constants/ModalEvents';
|
||||
@ -19,14 +20,16 @@ const initialValues = {
|
||||
level: SKILL_LEVELS[0],
|
||||
};
|
||||
|
||||
const schema = Yup.object().shape({
|
||||
name: Yup.string().required('This is a required field.'),
|
||||
level: Yup.string()
|
||||
.oneOf(SKILL_LEVELS, 'Must be one of the options above.')
|
||||
.required('This is a required field.'),
|
||||
});
|
||||
|
||||
const SkillModal = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const schema = Yup.object().shape({
|
||||
name: Yup.string().required(t('shared.forms.validation.required')),
|
||||
level: Yup.string()
|
||||
.oneOf(SKILL_LEVELS)
|
||||
.required(t('shared.forms.validation.required')),
|
||||
});
|
||||
|
||||
return (
|
||||
<Formik
|
||||
validateOnBlur
|
||||
@ -35,19 +38,19 @@ const SkillModal = () => {
|
||||
>
|
||||
{(formik) => (
|
||||
<DataModal
|
||||
name="Skill"
|
||||
name={t('builder.sections.skill')}
|
||||
path="skills.items"
|
||||
event={ModalEvents.SKILL_MODAL}
|
||||
>
|
||||
<div className="grid grid-cols-2 gap-8">
|
||||
<Input
|
||||
label="Name"
|
||||
label={t('shared.forms.name')}
|
||||
placeholder="ReactJS"
|
||||
{...getFieldProps(formik, schema, 'name')}
|
||||
/>
|
||||
|
||||
<Input
|
||||
label="Level"
|
||||
label={t('builder.skills.level')}
|
||||
type="dropdown"
|
||||
options={SKILL_LEVELS}
|
||||
{...getFieldProps(formik, schema, 'level')}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { Formik } from 'formik';
|
||||
import React, { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import * as Yup from 'yup';
|
||||
import Input from '../../components/shared/Input';
|
||||
import ModalEvents from '../../constants/ModalEvents';
|
||||
@ -12,18 +13,20 @@ const initialValues = {
|
||||
username: '',
|
||||
};
|
||||
|
||||
const schema = Yup.object().shape({
|
||||
network: Yup.string()
|
||||
.min(5, 'Please enter at least 5 characters.')
|
||||
.required('This is a required field.'),
|
||||
username: Yup.string().required('This is a required field.'),
|
||||
url: Yup.string()
|
||||
.min(5, 'Please enter at least 5 characters.')
|
||||
.required('This is a required field.')
|
||||
.url('Must be a valid URL'),
|
||||
});
|
||||
|
||||
const SocialModal = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const schema = Yup.object().shape({
|
||||
network: Yup.string()
|
||||
.min(5, t('shared.forms.validation.min', { number: 5 }))
|
||||
.required(t('shared.forms.validation.required')),
|
||||
username: Yup.string().required(t('shared.forms.validation.required')),
|
||||
url: Yup.string()
|
||||
.min(5, t('shared.forms.validation.min', { number: 5 }))
|
||||
.required(t('shared.forms.validation.required'))
|
||||
.url(t('shared.forms.validation.url')),
|
||||
});
|
||||
|
||||
return (
|
||||
<Formik
|
||||
validateOnBlur
|
||||
@ -33,24 +36,24 @@ const SocialModal = () => {
|
||||
{(formik) => (
|
||||
<DataModal
|
||||
path="social.items"
|
||||
name="Social Network"
|
||||
name={t('builder.sections.social')}
|
||||
event={ModalEvents.SOCIAL_MODAL}
|
||||
>
|
||||
<div className="grid grid-cols-2 gap-8">
|
||||
<Input
|
||||
label="Network"
|
||||
label={t('builder.social.network')}
|
||||
placeholder="Twitter"
|
||||
{...getFieldProps(formik, schema, 'network')}
|
||||
/>
|
||||
|
||||
<Input
|
||||
label="Username"
|
||||
label={t('builder.social.username')}
|
||||
placeholder="KingOKings"
|
||||
{...getFieldProps(formik, schema, 'username')}
|
||||
/>
|
||||
|
||||
<Input
|
||||
label="URL"
|
||||
label={t('builder.social.url')}
|
||||
className="col-span-2"
|
||||
placeholder="https://twitter.com/KingOKings"
|
||||
{...getFieldProps(formik, schema, 'url')}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { Formik } from 'formik';
|
||||
import React, { memo } from 'react';
|
||||
import * as Yup from 'yup';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import Input from '../../components/shared/Input';
|
||||
import ModalEvents from '../../constants/ModalEvents';
|
||||
import { getFieldProps } from '../../utils';
|
||||
@ -15,21 +16,26 @@ const initialValues = {
|
||||
summary: '',
|
||||
};
|
||||
|
||||
const schema = Yup.object().shape({
|
||||
company: Yup.string().required('This is a required field.'),
|
||||
position: Yup.string().required('This is a required field.'),
|
||||
website: Yup.string().url('Must be a valid URL'),
|
||||
startDate: Yup.date().required('This is a required field.'),
|
||||
endDate: Yup.date().when(
|
||||
'startDate',
|
||||
(startDate, yupSchema) =>
|
||||
startDate &&
|
||||
yupSchema.min(startDate, 'End Date must be later than Start Date'),
|
||||
),
|
||||
summary: Yup.string().min(10, 'Please enter at least 10 characters.'),
|
||||
});
|
||||
|
||||
const WorkModal = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const schema = Yup.object().shape({
|
||||
company: Yup.string().required(t('shared.forms.validation.required')),
|
||||
position: Yup.string().required(t('shared.forms.validation.required')),
|
||||
website: Yup.string().url(t('shared.forms.validation.url')),
|
||||
startDate: Yup.date().required(t('shared.forms.validation.required')),
|
||||
endDate: Yup.date().when(
|
||||
'startDate',
|
||||
(startDate, yupSchema) =>
|
||||
startDate &&
|
||||
yupSchema.min(startDate, t('shared.forms.validation.dateRange')),
|
||||
),
|
||||
summary: Yup.string().min(
|
||||
10,
|
||||
t('shared.forms.validation.min', { number: 10 }),
|
||||
),
|
||||
});
|
||||
|
||||
return (
|
||||
<Formik
|
||||
validateOnBlur
|
||||
@ -39,46 +45,46 @@ const WorkModal = () => {
|
||||
{(formik) => (
|
||||
<DataModal
|
||||
path="work.items"
|
||||
name="Work Experience"
|
||||
name={t('builder.sections.work')}
|
||||
event={ModalEvents.WORK_MODAL}
|
||||
>
|
||||
<div className="grid grid-cols-2 gap-8">
|
||||
<Input
|
||||
label="Company"
|
||||
label={t('builder.work.company')}
|
||||
className="col-span-2"
|
||||
placeholder="Postdot Technologies Pvt. Ltd."
|
||||
{...getFieldProps(formik, schema, 'company')}
|
||||
/>
|
||||
|
||||
<Input
|
||||
label="Position"
|
||||
label={t('shared.forms.position')}
|
||||
placeholder="Full Stack Web Developer"
|
||||
{...getFieldProps(formik, schema, 'position')}
|
||||
/>
|
||||
|
||||
<Input
|
||||
label="Website"
|
||||
label={t('shared.forms.website')}
|
||||
placeholder="https://example.com/"
|
||||
{...getFieldProps(formik, schema, 'website')}
|
||||
/>
|
||||
|
||||
<Input
|
||||
type="date"
|
||||
label="Start Date"
|
||||
label={t('shared.forms.startDate')}
|
||||
placeholder="6th August 208"
|
||||
{...getFieldProps(formik, schema, 'startDate')}
|
||||
/>
|
||||
|
||||
<Input
|
||||
type="date"
|
||||
label="End Date"
|
||||
label={t('shared.forms.endDate')}
|
||||
placeholder="6th August 208"
|
||||
{...getFieldProps(formik, schema, 'endDate')}
|
||||
/>
|
||||
|
||||
<Input
|
||||
type="textarea"
|
||||
label="Summary"
|
||||
label={t('shared.forms.summary')}
|
||||
className="col-span-2"
|
||||
{...getFieldProps(formik, schema, 'summary')}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user