Merge branch 'develop' into l10n_develop

This commit is contained in:
Amruth Pillai
2020-07-20 07:52:26 +05:30
committed by GitHub
16 changed files with 148 additions and 128 deletions

View File

@ -46,10 +46,11 @@ For those of you familiar with the Crowdin Platform, you could do that too and j
##### Languages Currently Supported ##### Languages Currently Supported
- English - English
- Kannada (ಕನ್ನಡ)
- Spanish (Español) (by [@jrgonzalezrios](https://github.com/jrgonzalezrios))
- Portuguese (Brazilian) (by [Felipe CG](https://github.com/felcg))
- Finnish (Suomalainen) (by Ari Pikkarainen) - Finnish (Suomalainen) (by Ari Pikkarainen)
- French (Français) (by [MeisterLLD](https://github.com/MeisterLLD))
- Kannada (ಕನ್ನಡ)
- Portuguese (Brazilian) (by [Felipe CG](https://github.com/felcg))
- Spanish (Español) (by [@jrgonzalezrios](https://github.com/jrgonzalezrios))
### Building from Source ### Building from Source

View File

@ -5,7 +5,7 @@ module.exports = {
title: 'Reactive Resume', title: 'Reactive Resume',
siteUrl: 'https://rxresu.me', siteUrl: 'https://rxresu.me',
description: 'A free and open source resume builder.', description: 'A free and open source resume builder.',
version: '2.0.1', version: '2.0.2',
}, },
plugins: [ plugins: [
'gatsby-plugin-react-helmet', 'gatsby-plugin-react-helmet',

24
package-lock.json generated
View File

@ -6704,9 +6704,9 @@
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
}, },
"eslint": { "eslint": {
"version": "7.4.0", "version": "7.5.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-7.4.0.tgz", "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.5.0.tgz",
"integrity": "sha512-gU+lxhlPHu45H3JkEGgYhWhkR9wLHHEXC9FbWFnTlEkbKyZKWgWRLgf61E8zWmBuI6g5xKBph9ltg3NtZMVF8g==", "integrity": "sha512-vlUP10xse9sWt9SGRtcr1LAC67BENcQMFeV+w5EvLEoFe3xJ8cF1Skd0msziRx/VMC+72B4DxreCE+OR12OA6Q==",
"dev": true, "dev": true,
"requires": { "requires": {
"@babel/code-frame": "^7.0.0", "@babel/code-frame": "^7.0.0",
@ -6717,9 +6717,9 @@
"doctrine": "^3.0.0", "doctrine": "^3.0.0",
"enquirer": "^2.3.5", "enquirer": "^2.3.5",
"eslint-scope": "^5.1.0", "eslint-scope": "^5.1.0",
"eslint-utils": "^2.0.0", "eslint-utils": "^2.1.0",
"eslint-visitor-keys": "^1.2.0", "eslint-visitor-keys": "^1.3.0",
"espree": "^7.1.0", "espree": "^7.2.0",
"esquery": "^1.2.0", "esquery": "^1.2.0",
"esutils": "^2.0.2", "esutils": "^2.0.2",
"file-entry-cache": "^5.0.1", "file-entry-cache": "^5.0.1",
@ -6733,7 +6733,7 @@
"js-yaml": "^3.13.1", "js-yaml": "^3.13.1",
"json-stable-stringify-without-jsonify": "^1.0.1", "json-stable-stringify-without-jsonify": "^1.0.1",
"levn": "^0.4.1", "levn": "^0.4.1",
"lodash": "^4.17.14", "lodash": "^4.17.19",
"minimatch": "^3.0.4", "minimatch": "^3.0.4",
"natural-compare": "^1.4.0", "natural-compare": "^1.4.0",
"optionator": "^0.9.1", "optionator": "^0.9.1",
@ -6809,14 +6809,14 @@
} }
}, },
"espree": { "espree": {
"version": "7.1.0", "version": "7.2.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-7.1.0.tgz", "resolved": "https://registry.npmjs.org/espree/-/espree-7.2.0.tgz",
"integrity": "sha512-dcorZSyfmm4WTuTnE5Y7MEN1DyoPYy1ZR783QW1FJoenn7RailyWFsq/UL6ZAAA7uXurN9FIpYyUs3OfiIW+Qw==", "integrity": "sha512-H+cQ3+3JYRMEIOl87e7QdHX70ocly5iW4+dttuR8iYSPr/hXKFb+7dBsZ7+u1adC4VrnPlTkv0+OwuPnDop19g==",
"dev": true, "dev": true,
"requires": { "requires": {
"acorn": "^7.2.0", "acorn": "^7.3.1",
"acorn-jsx": "^5.2.0", "acorn-jsx": "^5.2.0",
"eslint-visitor-keys": "^1.2.0" "eslint-visitor-keys": "^1.3.0"
} }
}, },
"glob-parent": { "glob-parent": {

View File

@ -63,7 +63,7 @@
}, },
"devDependencies": { "devDependencies": {
"autoprefixer": "^9.8.5", "autoprefixer": "^9.8.5",
"eslint": "^7.4.0", "eslint": "^7.5.0",
"eslint-config-airbnb": "^18.2.0", "eslint-config-airbnb": "^18.2.0",
"eslint-config-prettier": "^6.11.0", "eslint-config-prettier": "^6.11.0",
"eslint-loader": "^4.0.2", "eslint-loader": "^4.0.2",

View File

@ -1,4 +1,4 @@
import React, { memo } from 'react'; import React, { memo, useEffect, useState } from 'react';
import { Helmet } from 'react-helmet'; import { Helmet } from 'react-helmet';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useSelector } from '../../../contexts/ResumeContext'; import { useSelector } from '../../../contexts/ResumeContext';
@ -13,9 +13,14 @@ import styles from './Artboard.module.css';
const Artboard = () => { const Artboard = () => {
const state = useSelector(); const state = useSelector();
const { t } = useTranslation(); const { t } = useTranslation();
const [width, setWidth] = useState(0);
const { id, name, metadata } = state; const { id, name, metadata } = state;
const { template } = metadata; const { template } = metadata;
useEffect(() => {
setWidth(typeof window !== `undefined` && window && window.innerWidth);
}, [typeof window !== `undefined` && window && window.innerWidth]);
return ( return (
<> <>
<Helmet> <Helmet>
@ -25,7 +30,12 @@ const Artboard = () => {
<link rel="canonical" href={`https://rxresu.me/app/builder/${id}`} /> <link rel="canonical" href={`https://rxresu.me/app/builder/${id}`} />
</Helmet> </Helmet>
<div className={styles.container}> <div
className={styles.container}
style={{
transform: `scale(${width / 1680})`,
}}
>
{template === 'onyx' && <Onyx data={state} />} {template === 'onyx' && <Onyx data={state} />}
{template === 'pikachu' && <Pikachu data={state} />} {template === 'pikachu' && <Pikachu data={state} />}
{template === 'gengar' && <Gengar data={state} />} {template === 'gengar' && <Gengar data={state} />}

View File

@ -1,22 +1,9 @@
@media screen { @media screen {
.container { .container {
width: 210mm; width: 794px;
height: 297mm; min-height: 1122px;
zoom: 0.5;
overflow: scroll; overflow: scroll;
box-shadow: var(--shadow); box-shadow: var(--shadow);
@apply my-16 bg-white rounded; @apply my-16 bg-white rounded;
} }
} }
@media screen and (min-width: 1366px) {
.container {
zoom: 0.65;
}
}
@media screen and (min-width: 1440px) {
.container {
zoom: 0.8;
}
}

View File

@ -1,6 +1,5 @@
.container { .container {
z-index: 10; z-index: 10;
box-shadow: var(--left-shadow);
@apply w-full h-screen overflow-scroll p-8; @apply w-full h-screen overflow-scroll p-8;
@apply grid gap-8; @apply grid gap-8;
} }

View File

@ -1,6 +1,5 @@
.container { .container {
z-index: 10; z-index: 10;
box-shadow: var(--right-shadow);
@apply w-full h-screen overflow-scroll p-8; @apply w-full h-screen overflow-scroll p-8;
@apply grid gap-8; @apply grid gap-8;
} }

View File

@ -1,16 +1,16 @@
import { Menu, MenuItem } from '@material-ui/core'; import { Menu, MenuItem } from '@material-ui/core';
import { navigate } from 'gatsby'; import { navigate } from 'gatsby';
import moment from 'moment'; import moment from 'moment/min/moment-with-locales';
import React, { useContext, useState } from 'react'; import React, { useContext, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { MdMoreHoriz, MdOpenInNew } from 'react-icons/md'; import { MdMoreHoriz, MdOpenInNew } from 'react-icons/md';
import { toast } from 'react-toastify'; import { toast } from 'react-toastify';
import { useTranslation } from 'react-i18next';
import DatabaseContext from '../../contexts/DatabaseContext'; import DatabaseContext from '../../contexts/DatabaseContext';
import ModalContext from '../../contexts/ModalContext'; import ModalContext from '../../contexts/ModalContext';
import styles from './ResumePreview.module.css'; import styles from './ResumePreview.module.css';
const ResumePreview = ({ resume }) => { const ResumePreview = ({ resume }) => {
const { t } = useTranslation(); const { t, i18n } = useTranslation();
const [anchorEl, setAnchorEl] = useState(null); const [anchorEl, setAnchorEl] = useState(null);
const { emitter, events } = useContext(ModalContext); const { emitter, events } = useContext(ModalContext);
const { duplicateResume, deleteResume } = useContext(DatabaseContext); const { duplicateResume, deleteResume } = useContext(DatabaseContext);
@ -84,7 +84,9 @@ const ResumePreview = ({ resume }) => {
{resume.updatedAt && ( {resume.updatedAt && (
<span> <span>
{t('dashboard.lastUpdated', { {t('dashboard.lastUpdated', {
timestamp: moment(resume.updatedAt).fromNow(), timestamp: moment(resume.updatedAt)
.locale(i18n.language.substr(0, 2))
.fromNow(),
})} })}
</span> </span>
)} )}

View File

@ -8,20 +8,24 @@ const languages = [
name: 'English (US)', name: 'English (US)',
}, },
{ {
code: 'kn', code: 'fi',
name: 'Kannada (ಕನ್ನಡ)', name: 'Finnish (Suomalainen)',
}, },
{ {
code: 'es', code: 'fr',
name: 'Spanish (Español)', name: 'French (Français)',
},
{
code: 'kn',
name: 'Kannada (ಕನ್ನಡ)',
}, },
{ {
code: 'ptBr', code: 'ptBr',
name: 'Portuguese (Brazilian)', name: 'Portuguese (Brazilian)',
}, },
{ {
code: 'fi', code: 'es',
name: 'Finnish (Suomalainen)', name: 'Spanish (Español)',
}, },
]; ];

View File

@ -1,13 +1,15 @@
import en from './en.json'; import en from './en.json';
import kn from './kn.json';
import es from './es.json'; import es from './es.json';
import ptBr from './pt-br.json';
import fi from './fi.json'; import fi from './fi.json';
import fr from './fr.json';
import kn from './kn.json';
import ptBr from './pt-br.json';
export default { export default {
en: { translation: en }, en: { translation: en },
kn: { translation: kn },
es: { translation: es }, es: { translation: es },
ptBr: { translation: ptBr },
fi: { translation: fi }, fi: { translation: fi },
fr: { translation: fr },
kn: { translation: kn },
ptBr: { translation: ptBr },
}; };

View File

@ -1,33 +1,19 @@
.container { .container {
@apply w-screen h-screen grid grid-cols-10; @apply relative h-screen w-screen overflow-hidden flex items-start justify-center;
} }
.left { .left {
@apply col-span-3; width: calc(100vw / 4);
box-shadow: var(--left-shadow);
@apply bg-primary-50 absolute top-0 bottom-0 left-0 z-10;
} }
.center { .center {
@apply col-span-4 h-screen overflow-scroll bg-primary-100 grid justify-center items-center; @apply relative z-0 h-screen overflow-scroll;
} }
.right { .right {
@apply col-span-3; width: calc(100vw / 4);
} box-shadow: var(--right-shadow);
@apply bg-primary-50 absolute top-0 bottom-0 right-0 z-10;
@media screen and (min-width: 1440px) {
.container {
@apply grid-cols-11;
}
.left {
@apply col-span-3;
}
.center {
@apply col-span-5;
}
.right {
@apply col-span-3;
}
} }

View File

@ -1,27 +1,34 @@
import moment from 'moment'; import moment from 'moment/min/moment-with-locales';
import React, { memo, useContext } from 'react'; import React, { memo, useContext } from 'react';
import { useTranslation } from 'react-i18next';
import ReactMarkdown from 'react-markdown'; import ReactMarkdown from 'react-markdown';
import PageContext from '../../../contexts/PageContext'; import PageContext from '../../../contexts/PageContext';
import { safetyCheck } from '../../../utils'; import { safetyCheck } from '../../../utils';
const AwardItem = (x) => ( const AwardItem = (x) => {
<div key={x.id}> const { i18n } = useTranslation();
<div className="flex justify-between items-center">
<div className="flex flex-col text-left mr-2"> return (
<h6 className="font-semibold">{x.title}</h6> <div key={x.id}>
<span className="text-xs">{x.awarder}</span> <div className="flex justify-between items-center">
<div className="flex flex-col text-left mr-2">
<h6 className="font-semibold">{x.title}</h6>
<span className="text-xs">{x.awarder}</span>
</div>
{x.date && (
<h6 className="text-xs font-medium text-right">
{moment(x.date)
.locale(i18n.language.substr(0, 2))
.format('MMMM YYYY')}
</h6>
)}
</div> </div>
{x.date && ( {x.summary && (
<h6 className="text-xs font-medium text-right"> <ReactMarkdown className="markdown mt-2 text-sm" source={x.summary} />
{moment(x.date).format('MMMM YYYY')}
</h6>
)} )}
</div> </div>
{x.summary && ( );
<ReactMarkdown className="markdown mt-2 text-sm" source={x.summary} /> };
)}
</div>
);
const AwardsA = () => { const AwardsA = () => {
const { data, heading: Heading } = useContext(PageContext); const { data, heading: Heading } = useContext(PageContext);

View File

@ -1,27 +1,34 @@
import moment from 'moment'; import moment from 'moment/min/moment-with-locales';
import React, { memo, useContext } from 'react'; import React, { memo, useContext } from 'react';
import { useTranslation } from 'react-i18next';
import ReactMarkdown from 'react-markdown'; import ReactMarkdown from 'react-markdown';
import PageContext from '../../../contexts/PageContext'; import PageContext from '../../../contexts/PageContext';
import { safetyCheck } from '../../../utils'; import { safetyCheck } from '../../../utils';
const CertificationItem = (x) => ( const CertificationItem = (x) => {
<div key={x.id}> const { i18n } = useTranslation();
<div className="flex justify-between items-center">
<div className="flex flex-col text-left mr-2"> return (
<h6 className="font-semibold">{x.title}</h6> <div key={x.id}>
<span className="text-xs">{x.issuer}</span> <div className="flex justify-between items-center">
<div className="flex flex-col text-left mr-2">
<h6 className="font-semibold">{x.title}</h6>
<span className="text-xs">{x.issuer}</span>
</div>
{x.date && (
<h6 className="text-xs font-medium text-right">
{moment(x.date)
.locale(i18n.language.substr(0, 2))
.format('MMMM YYYY')}
</h6>
)}
</div> </div>
{x.date && ( {x.summary && (
<h6 className="text-xs font-medium text-right"> <ReactMarkdown className="markdown mt-2 text-sm" source={x.summary} />
{moment(x.date).format('MMMM YYYY')}
</h6>
)} )}
</div> </div>
{x.summary && ( );
<ReactMarkdown className="markdown mt-2 text-sm" source={x.summary} /> };
)}
</div>
);
const CertificationsA = () => { const CertificationsA = () => {
const { data, heading: Heading } = useContext(PageContext); const { data, heading: Heading } = useContext(PageContext);

View File

@ -1,31 +1,38 @@
import moment from 'moment'; import moment from 'moment/min/moment-with-locales';
import React, { memo, useContext } from 'react'; import React, { memo, useContext } from 'react';
import { useTranslation } from 'react-i18next';
import ReactMarkdown from 'react-markdown'; import ReactMarkdown from 'react-markdown';
import PageContext from '../../../contexts/PageContext'; import PageContext from '../../../contexts/PageContext';
import { safetyCheck } from '../../../utils'; import { safetyCheck } from '../../../utils';
const ProjectItem = (x) => ( const ProjectItem = (x) => {
<div key={x.id}> const { i18n } = useTranslation();
<div className="flex justify-between items-center">
<div className="flex flex-col text-left mr-2"> return (
<h6 className="font-semibold">{x.title}</h6> <div key={x.id}>
{x.link && ( <div className="flex justify-between items-center">
<a href={x.link} className="text-xs"> <div className="flex flex-col text-left mr-2">
{x.link} <h6 className="font-semibold">{x.title}</h6>
</a> {x.link && (
<a href={x.link} className="text-xs">
{x.link}
</a>
)}
</div>
{x.date && (
<h6 className="text-xs font-medium text-right">
{moment(x.date)
.locale(i18n.language.substr(0, 2))
.format('MMMM YYYY')}
</h6>
)} )}
</div> </div>
{x.date && ( {x.summary && (
<h6 className="text-xs font-medium text-right"> <ReactMarkdown className="markdown mt-2 text-sm" source={x.summary} />
{moment(x.date).format('MMMM YYYY')}
</h6>
)} )}
</div> </div>
{x.summary && ( );
<ReactMarkdown className="markdown mt-2 text-sm" source={x.summary} /> };
)}
</div>
);
const ProjectsA = () => { const ProjectsA = () => {
const { data, heading: Heading } = useContext(PageContext); const { data, heading: Heading } = useContext(PageContext);

View File

@ -1,5 +1,5 @@
import { get, isEmpty } from 'lodash'; import { get, isEmpty } from 'lodash';
import moment from 'moment'; import moment from 'moment/min/moment-with-locales';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
export const getModalText = (isEditMode, type) => { export const getModalText = (isEditMode, type) => {
@ -22,10 +22,19 @@ export const isFileImage = (file) => {
return file && acceptedImageTypes.includes(file.type); return file && acceptedImageTypes.includes(file.type);
}; };
export const formatDateRange = ({ startDate, endDate }) => export const formatDateRange = ({ startDate, endDate }) => {
`${moment(startDate).format('MMMM Y')}${ const { i18n } = useTranslation();
moment(endDate).isValid() ? moment(endDate).format('MMMM Y') : 'Present'
}`; const start = `${moment(startDate)
.locale(i18n.language.substr(0, 2))
.format('MMMM Y')}`;
const end = moment(endDate).isValid()
? `${moment(endDate).locale(i18n.language.substr(0, 2)).format('MMMM Y')}`
: 'Present';
return `${start} - ${end}`;
};
export const getFieldProps = (formik, schema, name) => ({ export const getFieldProps = (formik, schema, name) => ({
touched: get(formik, `touched.${name}`, false), touched: get(formik, `touched.${name}`, false),