diff --git a/README.md b/README.md
index ccd3e969..a832f746 100644
--- a/README.md
+++ b/README.md
@@ -46,10 +46,11 @@ For those of you familiar with the Crowdin Platform, you could do that too and j
##### Languages Currently Supported
- 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)
+- 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
diff --git a/gatsby-config.js b/gatsby-config.js
index dcf8873f..37b34d19 100644
--- a/gatsby-config.js
+++ b/gatsby-config.js
@@ -5,7 +5,7 @@ module.exports = {
title: 'Reactive Resume',
siteUrl: 'https://rxresu.me',
description: 'A free and open source resume builder.',
- version: '2.0.1',
+ version: '2.0.2',
},
plugins: [
'gatsby-plugin-react-helmet',
diff --git a/package-lock.json b/package-lock.json
index 0fc6529f..5cc2a0b0 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -6704,9 +6704,9 @@
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
},
"eslint": {
- "version": "7.4.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.4.0.tgz",
- "integrity": "sha512-gU+lxhlPHu45H3JkEGgYhWhkR9wLHHEXC9FbWFnTlEkbKyZKWgWRLgf61E8zWmBuI6g5xKBph9ltg3NtZMVF8g==",
+ "version": "7.5.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.5.0.tgz",
+ "integrity": "sha512-vlUP10xse9sWt9SGRtcr1LAC67BENcQMFeV+w5EvLEoFe3xJ8cF1Skd0msziRx/VMC+72B4DxreCE+OR12OA6Q==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
@@ -6717,9 +6717,9 @@
"doctrine": "^3.0.0",
"enquirer": "^2.3.5",
"eslint-scope": "^5.1.0",
- "eslint-utils": "^2.0.0",
- "eslint-visitor-keys": "^1.2.0",
- "espree": "^7.1.0",
+ "eslint-utils": "^2.1.0",
+ "eslint-visitor-keys": "^1.3.0",
+ "espree": "^7.2.0",
"esquery": "^1.2.0",
"esutils": "^2.0.2",
"file-entry-cache": "^5.0.1",
@@ -6733,7 +6733,7 @@
"js-yaml": "^3.13.1",
"json-stable-stringify-without-jsonify": "^1.0.1",
"levn": "^0.4.1",
- "lodash": "^4.17.14",
+ "lodash": "^4.17.19",
"minimatch": "^3.0.4",
"natural-compare": "^1.4.0",
"optionator": "^0.9.1",
@@ -6809,14 +6809,14 @@
}
},
"espree": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/espree/-/espree-7.1.0.tgz",
- "integrity": "sha512-dcorZSyfmm4WTuTnE5Y7MEN1DyoPYy1ZR783QW1FJoenn7RailyWFsq/UL6ZAAA7uXurN9FIpYyUs3OfiIW+Qw==",
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-7.2.0.tgz",
+ "integrity": "sha512-H+cQ3+3JYRMEIOl87e7QdHX70ocly5iW4+dttuR8iYSPr/hXKFb+7dBsZ7+u1adC4VrnPlTkv0+OwuPnDop19g==",
"dev": true,
"requires": {
- "acorn": "^7.2.0",
+ "acorn": "^7.3.1",
"acorn-jsx": "^5.2.0",
- "eslint-visitor-keys": "^1.2.0"
+ "eslint-visitor-keys": "^1.3.0"
}
},
"glob-parent": {
diff --git a/package.json b/package.json
index 2c2653b8..a8e9ad5e 100644
--- a/package.json
+++ b/package.json
@@ -63,7 +63,7 @@
},
"devDependencies": {
"autoprefixer": "^9.8.5",
- "eslint": "^7.4.0",
+ "eslint": "^7.5.0",
"eslint-config-airbnb": "^18.2.0",
"eslint-config-prettier": "^6.11.0",
"eslint-loader": "^4.0.2",
diff --git a/src/components/builder/center/Artboard.js b/src/components/builder/center/Artboard.js
index 7a5f4c70..6651fcb5 100644
--- a/src/components/builder/center/Artboard.js
+++ b/src/components/builder/center/Artboard.js
@@ -1,4 +1,4 @@
-import React, { memo } from 'react';
+import React, { memo, useEffect, useState } from 'react';
import { Helmet } from 'react-helmet';
import { useTranslation } from 'react-i18next';
import { useSelector } from '../../../contexts/ResumeContext';
@@ -13,9 +13,14 @@ import styles from './Artboard.module.css';
const Artboard = () => {
const state = useSelector();
const { t } = useTranslation();
+ const [width, setWidth] = useState(0);
const { id, name, metadata } = state;
const { template } = metadata;
+ useEffect(() => {
+ setWidth(typeof window !== `undefined` && window && window.innerWidth);
+ }, [typeof window !== `undefined` && window && window.innerWidth]);
+
return (
<>
@@ -25,7 +30,12 @@ const Artboard = () => {
-
+
{template === 'onyx' &&
}
{template === 'pikachu' &&
}
{template === 'gengar' &&
}
diff --git a/src/components/builder/center/Artboard.module.css b/src/components/builder/center/Artboard.module.css
index 045ab997..5ad63bf9 100644
--- a/src/components/builder/center/Artboard.module.css
+++ b/src/components/builder/center/Artboard.module.css
@@ -1,22 +1,9 @@
@media screen {
.container {
- width: 210mm;
- height: 297mm;
- zoom: 0.5;
+ width: 794px;
+ min-height: 1122px;
overflow: scroll;
box-shadow: var(--shadow);
@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;
- }
-}
\ No newline at end of file
diff --git a/src/components/builder/left/LeftSidebar.module.css b/src/components/builder/left/LeftSidebar.module.css
index 65c96f6d..cc4dbcbe 100644
--- a/src/components/builder/left/LeftSidebar.module.css
+++ b/src/components/builder/left/LeftSidebar.module.css
@@ -1,6 +1,5 @@
.container {
z-index: 10;
- box-shadow: var(--left-shadow);
@apply w-full h-screen overflow-scroll p-8;
@apply grid gap-8;
}
\ No newline at end of file
diff --git a/src/components/builder/right/RightSidebar.module.css b/src/components/builder/right/RightSidebar.module.css
index de68bb23..7f0ccf8c 100644
--- a/src/components/builder/right/RightSidebar.module.css
+++ b/src/components/builder/right/RightSidebar.module.css
@@ -1,6 +1,5 @@
.container {
z-index: 10;
- box-shadow: var(--right-shadow);
@apply w-full h-screen overflow-scroll p-8;
@apply grid gap-8;
}
diff --git a/src/components/dashboard/ResumePreview.js b/src/components/dashboard/ResumePreview.js
index e651e140..bb47bb23 100644
--- a/src/components/dashboard/ResumePreview.js
+++ b/src/components/dashboard/ResumePreview.js
@@ -1,16 +1,16 @@
import { Menu, MenuItem } from '@material-ui/core';
import { navigate } from 'gatsby';
-import moment from 'moment';
+import moment from 'moment/min/moment-with-locales';
import React, { useContext, useState } from 'react';
+import { useTranslation } from 'react-i18next';
import { MdMoreHoriz, MdOpenInNew } from 'react-icons/md';
import { toast } from 'react-toastify';
-import { useTranslation } from 'react-i18next';
import DatabaseContext from '../../contexts/DatabaseContext';
import ModalContext from '../../contexts/ModalContext';
import styles from './ResumePreview.module.css';
const ResumePreview = ({ resume }) => {
- const { t } = useTranslation();
+ const { t, i18n } = useTranslation();
const [anchorEl, setAnchorEl] = useState(null);
const { emitter, events } = useContext(ModalContext);
const { duplicateResume, deleteResume } = useContext(DatabaseContext);
@@ -84,7 +84,9 @@ const ResumePreview = ({ resume }) => {
{resume.updatedAt && (
{t('dashboard.lastUpdated', {
- timestamp: moment(resume.updatedAt).fromNow(),
+ timestamp: moment(resume.updatedAt)
+ .locale(i18n.language.substr(0, 2))
+ .fromNow(),
})}
)}
diff --git a/src/i18n/index.js b/src/i18n/index.js
index 0a24620c..721dbded 100644
--- a/src/i18n/index.js
+++ b/src/i18n/index.js
@@ -8,20 +8,24 @@ const languages = [
name: 'English (US)',
},
{
- code: 'kn',
- name: 'Kannada (ಕನ್ನಡ)',
+ code: 'fi',
+ name: 'Finnish (Suomalainen)',
},
{
- code: 'es',
- name: 'Spanish (Español)',
+ code: 'fr',
+ name: 'French (Français)',
+ },
+ {
+ code: 'kn',
+ name: 'Kannada (ಕನ್ನಡ)',
},
{
code: 'ptBr',
name: 'Portuguese (Brazilian)',
},
{
- code: 'fi',
- name: 'Finnish (Suomalainen)',
+ code: 'es',
+ name: 'Spanish (Español)',
},
];
diff --git a/src/i18n/locales/index.js b/src/i18n/locales/index.js
index 9e669fcd..65e3588d 100644
--- a/src/i18n/locales/index.js
+++ b/src/i18n/locales/index.js
@@ -1,13 +1,15 @@
import en from './en.json';
-import kn from './kn.json';
import es from './es.json';
-import ptBr from './pt-br.json';
import fi from './fi.json';
+import fr from './fr.json';
+import kn from './kn.json';
+import ptBr from './pt-br.json';
export default {
en: { translation: en },
- kn: { translation: kn },
es: { translation: es },
- ptBr: { translation: ptBr },
fi: { translation: fi },
+ fr: { translation: fr },
+ kn: { translation: kn },
+ ptBr: { translation: ptBr },
};
diff --git a/src/pages/app/builder.module.css b/src/pages/app/builder.module.css
index c53f47c0..c475f80e 100644
--- a/src/pages/app/builder.module.css
+++ b/src/pages/app/builder.module.css
@@ -1,33 +1,19 @@
.container {
- @apply w-screen h-screen grid grid-cols-10;
+ @apply relative h-screen w-screen overflow-hidden flex items-start justify-center;
}
.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 {
- @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 {
- @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;
- }
-}
\ No newline at end of file
diff --git a/src/templates/blocks/Awards/AwardsA.js b/src/templates/blocks/Awards/AwardsA.js
index 4ea2c96e..2e54824f 100644
--- a/src/templates/blocks/Awards/AwardsA.js
+++ b/src/templates/blocks/Awards/AwardsA.js
@@ -1,27 +1,34 @@
-import moment from 'moment';
+import moment from 'moment/min/moment-with-locales';
import React, { memo, useContext } from 'react';
+import { useTranslation } from 'react-i18next';
import ReactMarkdown from 'react-markdown';
import PageContext from '../../../contexts/PageContext';
import { safetyCheck } from '../../../utils';
-const AwardItem = (x) => (
-
-
-
-
{x.title}
-
{x.awarder}
+const AwardItem = (x) => {
+ const { i18n } = useTranslation();
+
+ return (
+
+
+
+
{x.title}
+ {x.awarder}
+
+ {x.date && (
+
+ {moment(x.date)
+ .locale(i18n.language.substr(0, 2))
+ .format('MMMM YYYY')}
+
+ )}
- {x.date && (
-
- {moment(x.date).format('MMMM YYYY')}
-
+ {x.summary && (
+
)}
- {x.summary && (
-
- )}
-
-);
+ );
+};
const AwardsA = () => {
const { data, heading: Heading } = useContext(PageContext);
diff --git a/src/templates/blocks/Certifications/CertificationsA.js b/src/templates/blocks/Certifications/CertificationsA.js
index 08d9d2f2..52bcd2d9 100644
--- a/src/templates/blocks/Certifications/CertificationsA.js
+++ b/src/templates/blocks/Certifications/CertificationsA.js
@@ -1,27 +1,34 @@
-import moment from 'moment';
+import moment from 'moment/min/moment-with-locales';
import React, { memo, useContext } from 'react';
+import { useTranslation } from 'react-i18next';
import ReactMarkdown from 'react-markdown';
import PageContext from '../../../contexts/PageContext';
import { safetyCheck } from '../../../utils';
-const CertificationItem = (x) => (
-
-
-
-
{x.title}
-
{x.issuer}
+const CertificationItem = (x) => {
+ const { i18n } = useTranslation();
+
+ return (
+
+
+
+
{x.title}
+ {x.issuer}
+
+ {x.date && (
+
+ {moment(x.date)
+ .locale(i18n.language.substr(0, 2))
+ .format('MMMM YYYY')}
+
+ )}
- {x.date && (
-
- {moment(x.date).format('MMMM YYYY')}
-
+ {x.summary && (
+
)}
- {x.summary && (
-
- )}
-
-);
+ );
+};
const CertificationsA = () => {
const { data, heading: Heading } = useContext(PageContext);
diff --git a/src/templates/blocks/Projects/ProjectsA.js b/src/templates/blocks/Projects/ProjectsA.js
index f8a196a2..b92ff558 100644
--- a/src/templates/blocks/Projects/ProjectsA.js
+++ b/src/templates/blocks/Projects/ProjectsA.js
@@ -1,31 +1,38 @@
-import moment from 'moment';
+import moment from 'moment/min/moment-with-locales';
import React, { memo, useContext } from 'react';
+import { useTranslation } from 'react-i18next';
import ReactMarkdown from 'react-markdown';
import PageContext from '../../../contexts/PageContext';
import { safetyCheck } from '../../../utils';
-const ProjectItem = (x) => (
-
-
-
-
{x.title}
- {x.link && (
-
- {x.link}
-
+const ProjectItem = (x) => {
+ const { i18n } = useTranslation();
+
+ return (
+
+
+
+ {x.date && (
+
+ {moment(x.date)
+ .locale(i18n.language.substr(0, 2))
+ .format('MMMM YYYY')}
+
)}
- {x.date && (
-
- {moment(x.date).format('MMMM YYYY')}
-
+ {x.summary && (
+
)}
- {x.summary && (
-
- )}
-
-);
+ );
+};
const ProjectsA = () => {
const { data, heading: Heading } = useContext(PageContext);
diff --git a/src/utils/index.js b/src/utils/index.js
index 82e6d2e3..963a657c 100644
--- a/src/utils/index.js
+++ b/src/utils/index.js
@@ -1,5 +1,5 @@
import { get, isEmpty } from 'lodash';
-import moment from 'moment';
+import moment from 'moment/min/moment-with-locales';
import { useTranslation } from 'react-i18next';
export const getModalText = (isEditMode, type) => {
@@ -22,10 +22,19 @@ export const isFileImage = (file) => {
return file && acceptedImageTypes.includes(file.type);
};
-export const formatDateRange = ({ startDate, endDate }) =>
- `${moment(startDate).format('MMMM Y')} — ${
- moment(endDate).isValid() ? moment(endDate).format('MMMM Y') : 'Present'
- }`;
+export const formatDateRange = ({ startDate, endDate }) => {
+ const { i18n } = useTranslation();
+
+ 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) => ({
touched: get(formik, `touched.${name}`, false),