Merge remote-tracking branch 'upstream/develop' into develop

This commit is contained in:
gianantoniopini
2021-01-08 09:38:13 +01:00
15 changed files with 850 additions and 5387 deletions

View File

@ -46,6 +46,7 @@ For those of you familiar with the Crowdin Platform, you could do that too and j
##### Languages Currently Supported
- Arabic (عربى)
- Czech (čeština)
- Chinese Simplified (简体中文)
- Danish (Dansk)
- Dutch (Nederlands)

View File

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

5878
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -7,47 +7,46 @@
"scripts": {
"lint": "eslint .",
"lint:fix": "eslint --fix .",
"prebuild": "npm run test",
"build": "gatsby build",
"develop": "gatsby develop",
"format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,md}\"",
"start": "npm run develop",
"serve": "gatsby serve",
"clean": "gatsby clean",
"test": "jest"
"test": "echo \"Write tests! -> https://gatsby.dev/unit-testing\" && exit 1"
},
"dependencies": {
"@material-ui/core": "^4.11.2",
"@reach/router": "^1.3.4",
"animate.css": "^4.1.1",
"array-move": "^3.0.1",
"autoprefixer": "^10.1.0",
"autoprefixer": "^10.2.1",
"classnames": "^2.2.6",
"dayjs": "^1.9.8",
"dayjs": "^1.10.2",
"dotenv": "^8.2.0",
"downloadjs": "^1.4.7",
"firebase": "^8.2.1",
"firebase": "^8.2.2",
"formik": "^2.2.6",
"gatsby": "^2.29.3",
"gatsby-image": "^2.8.0",
"gatsby-plugin-create-client-paths": "^2.7.0",
"gatsby": "^2.30.1",
"gatsby-image": "^2.9.0",
"gatsby-plugin-create-client-paths": "^2.8.0",
"gatsby-plugin-firebase": "^0.2.0-beta.4",
"gatsby-plugin-manifest": "^2.9.1",
"gatsby-plugin-manifest": "^2.10.0",
"gatsby-plugin-material-ui": "^2.1.10",
"gatsby-plugin-offline": "^3.7.1",
"gatsby-plugin-postcss": "^3.4.0",
"gatsby-plugin-react-helmet": "^3.7.0",
"gatsby-plugin-sharp": "^2.11.2",
"gatsby-plugin-sitemap": "^2.9.0",
"gatsby-plugin-webfonts": "^1.1.3",
"gatsby-source-filesystem": "^2.8.1",
"gatsby-plugin-offline": "^3.8.0",
"gatsby-plugin-postcss": "^3.5.0",
"gatsby-plugin-react-helmet": "^3.8.0",
"gatsby-plugin-sharp": "^2.12.0",
"gatsby-plugin-sitemap": "^2.10.0",
"gatsby-plugin-webfonts": "^1.1.4",
"gatsby-source-filesystem": "^2.9.0",
"gatsby-source-gravatar": "^1.0.0",
"gatsby-transformer-remark": "^2.13.1",
"gatsby-transformer-sharp": "^2.9.0",
"gatsby-transformer-remark": "^2.14.0",
"gatsby-transformer-sharp": "^2.10.0",
"i18next": "^19.8.4",
"lodash": "^4.17.20",
"nanoevents": "^5.1.10",
"postcss": "^8.2.2",
"postcss": "^8.2.3",
"react": "^17.0.1",
"react-beautiful-dnd": "^13.0.0",
"react-dom": "^17.0.1",
@ -62,21 +61,14 @@
"yup": "^0.32.8"
},
"devDependencies": {
"@testing-library/jest-dom": "^5.11.8",
"@testing-library/react": "^11.2.2",
"babel-jest": "^26.6.3",
"babel-preset-gatsby": "^0.9.1",
"eslint": "^7.17.0",
"eslint-config-airbnb": "^18.2.1",
"eslint-config-prettier": "^7.1.0",
"eslint-loader": "^4.0.2",
"eslint-plugin-jest": "^24.1.3",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-prettier": "^3.3.0",
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-react": "^7.22.0",
"gatsby-plugin-eslint": "^2.0.8",
"identity-obj-proxy": "^3.0.0",
"jest": "^26.6.3",
"prettier": "2.2.1",
"stylelint": "^13.8.0",
"stylelint-config-standard": "^20.0.0",

View File

@ -2,42 +2,31 @@
import React, { memo, useEffect, useState } from 'react';
import { useDispatch, useSelector } from '../../../../contexts/ResumeContext';
import fontSizeOptions from '../../../../data/fontSizeOptions';
import { scaler } from '../../../../utils';
import Heading from '../../../shared/Heading';
const FontSizes = ({ id }) => {
// precompute some stuff for the logarithmic slider
const logMax = 2.5;
const logDefault = 1;
const logMin = 0.6;
const steps = 20;
const logRange = logMax / logMin;
const logStepSize = logRange ** (1 / steps);
const min = 0;
const max = min + steps - 1;
const scaleDefault = Math.log(logDefault / logMin) / Math.log(logStepSize);
const dispatch = useDispatch();
const fontSize = useSelector('metadata.fontSize');
const [fontScale, setFontScale] = useState(fontSize || scaleDefault);
// translate a linearly scaled value from the slider into a scale factor
const scale = (value) => logStepSize ** (value - min) * logMin;
const [scale, setScale] = useState(fontSize || 7);
useEffect(() => {
/* loop through the css variables we need to set and set them to the default
for that variable multiplied by the scale factor */
for (const [key, sizeDefault] of Object.entries(fontSizeOptions)) {
document.documentElement.style.setProperty(
key,
`${scale(fontScale) * sizeDefault}rem`,
`${scaler(scale) * sizeDefault}rem`,
);
}
}, [fontScale]);
}, [scale]);
const onChange = (event) => {
const { value } = event.target;
setFontScale(value);
setScale(value);
dispatch({
type: 'on_input',
@ -58,7 +47,7 @@ const FontSizes = ({ id }) => {
max={max}
type="range"
onChange={onChange}
defaultValue={fontScale}
defaultValue={scale}
className="rounded-lg overflow-hidden appearance-none bg-gray-400 h-4 w-full"
/>
</section>

View File

@ -7,6 +7,10 @@ const languages = [
code: 'ar',
name: 'Arabic (عربى)',
},
{
code: 'cs',
name: 'Czech (čeština)',
},
{
code: 'zh',
name: 'Chinese Simplified (简体中文)',

253
src/i18n/locales/cs.json Normal file
View File

@ -0,0 +1,253 @@
{
"shared": {
"appName": "Reactive Resume",
"shortDescription": "Svobodný a open source životopis online.",
"forms": {
"name": "Jméno",
"title": "Název",
"subtitle": "Podtitul",
"required": "požadované",
"website": "Webová stránka",
"date": "Datum",
"present": "Současnost",
"position": "Pozice",
"startDate": "Počáteční datum",
"endDate": "Datum ukončení",
"address": "Adresa",
"phone": "Telefonní číslo",
"email": "E-mailová adresa",
"summary": "Shrnutí",
"markdown": "Tento textový blok podporuje <1>markdown</1>.",
"validation": {
"min": "Zadejte alespoň {{number}} znaků.",
"dateRange": "Koncové datum musí být pozdější než počáteční datum.",
"email": "Musí obsahovat platnou emailovou adresu.",
"required": "Toto pole je povinné.",
"url": "Musí být platná URL adresa."
}
},
"buttons": {
"add": "Přidat",
"edit": "Upravit",
"cancel": "Zrušit",
"delete": "Odstranit",
"loading": "Načítání...",
"confirmation": "Opravdu?",
"login": "Přihlásit se",
"logout": "Odhlásit se"
}
},
"landing": {
"hero": {
"goToApp": "Přejít do aplikace"
}
},
"dashboard": {
"title": "Hlavní nabídka",
"createResume": "Vytvořit životopis",
"editResume": "Upravit životopis",
"lastUpdated": "Poslední aktualizace {{timestamp}}",
"toasts": {
"deleted": "{{name}} byl úspěšně smazán"
},
"buttons": {
"duplicate": "Duplikovat",
"rename": "Přejmenovat"
},
"helpText": "Budete vytvářet nový životopis od nuly, ale nejprve mu dejte jméno. To může být název pozice, na kterou chcete zažádat, nebo pokud děláte životopis pro přítele, můžete to nazvat Frantův životopis."
},
"builder": {
"toasts": {
"formErrors": "Možná budete muset vyplnit všechna povinná pole před odesláním tohoto formuláře.",
"doesNotExist": "Životopis, který jste hledali, již neexistuje... nebo možná nikdy neexistoval?",
"loadDemoData": "Nejste si jisti, kde začít? Zkuste načíst demo data a uvidíte, co může Reactive Resume nabídnout.",
"printError": "U cloudové funkce dochází k potížím, zkuste to prosím později nebo použijte funkci tisku v prohlížeči."
},
"sections": {
"heading": "Hlavička",
"profile": "Profil",
"social": "Sociální sítě",
"objective": "Cíl",
"work": "Pracovní zkušenosti",
"education": "Vzdělání",
"project": "Projekt",
"projects": "Projekty",
"award": "Ocenění",
"awards": "Ocenění",
"certification": "Certifikace",
"certifications": "Certifikace",
"skill": "Dovednost",
"skills": "Dovednosti",
"hobby": "Koníček",
"hobbies": "Koníčky",
"language": "Jazyk",
"languages": "Jazyky",
"reference": "Reference",
"references": "Reference",
"templates": "Šablony",
"layout": "Rozvržení",
"colors": "Barvy",
"font-size": "Velikost písma",
"fonts": "Písma",
"actions": "Akce",
"settings": "Nastavení",
"about": "O aplikaci"
},
"profile": {
"photograph": "Fotografie",
"firstName": "Jméno",
"lastName": "Příjmení",
"birthDate": "Datum narození",
"address": {
"line1": "Adresní řádek 1",
"line2": "Adresní řádek 2",
"city": "Město",
"pincode": "PSČ"
}
},
"social": {
"network": "Síť",
"username": "Uživatelské jméno",
"url": "Adresa URL"
},
"work": {
"company": "Společnost"
},
"education": {
"institution": "Instituce",
"field": "Studijní obor",
"degree": "Druh titulu",
"gpa": "GPA"
},
"awards": {
"awarder": "Ocenění"
},
"certifications": {
"issuer": "Vydavatel"
},
"skills": {
"level": "Úroveň"
},
"languages": {
"fluency": "Plynulost"
},
"layout": {
"block": "Blok",
"reset": "Resetovat rozložení",
"text": "Tato šablona podporuje {{count}} bloků."
},
"colors": {
"primary": "Primární Barva",
"text": "Barva textu",
"background": "Barva pozadí"
},
"actions": {
"import": {
"heading": "Nahrejte svůj životopis",
"text": "Můžete importovat své informace z různých zdrojů, jako je JSON Resume nebo LinkedIn, abyste mohli automaticky vyplnit většinu dat pro váš životopis.",
"button": "Nahrát"
},
"export": {
"heading": "Exportujte svůj životopis",
"text": "Exportujte svůj životopis jako PDF a sdílejte s náborovými pracovníky nebo JSON, který budete moci importovat zpět do této aplikace na jiném počítači.",
"button": "Exportovat"
},
"share": {
"heading": "Sdílejte svůj životopis",
"text": "Odkaz níže bude veřejně přístupný, pokud se ho rozhodnete sdílet, lidem se zobrazí nejnovější verze vašeho životopisu."
},
"loadDemoData": {
"text": "Nejste si jisti, co dělat s novou prázdnou stránkou? Načtěte ukázková data, abyste viděli, jak by měl životopis vypadat, a odtud můžete začít upravovat.",
"button": "Načíst ukázková data"
},
"resetEverything": {
"text": "Máte pocit, že jste udělali příliš mnoho chyb? Žádné starosti, vše vymažte jediným kliknutím, ale buďte opatrní, pokud neexistují žádné zálohy.",
"button": "Obnovit vše"
}
},
"settings": {
"theme": "Motiv",
"language": "Jazyk",
"translate": "Pokud chcete přispět poskytnutím překladů do vašeho jazyka, <1> navštivte tento odkaz </1>.",
"dangerZone": {
"heading": "Nebezpečná zóna",
"text": "Pokud chcete smazat svůj účet a vymazat všechny své životopisy, zmáčkněte tlačítko. Buďte opatrní, protože se jedná o nevratný proces.",
"button": "Smazat účet"
}
},
"about": {
"donate": {
"heading": "Přispějte na Reactive Resume",
"text": "Snažím se dělat, co můžu, ale pokud vám aplikace přišla užitečná, nebo jste v lepší pozici než ostatní, kteří jsou závislí na tomto projektu při svém prvním zaměstnání, <1> zvažte prosím darování pouhých 5 $, které vám pomohou udržet projekt naživu </1> :)",
"button": "Kup mi kávu!"
},
"bugFeature": {
"heading": "Chyba? Požadavek na funkci?",
"text": "Něco brzdí tvůj postup k vytvoření životopisu? Našli jste otravnou chybu, která prostě nepřestane? Promluvte si o tom v sekci GitHub Issues pomocí tlačítka níže.",
"button": "Nahlásit problém"
},
"appreciate": {
"heading": "Líbí se vám Reactive Resume?",
"text": "Nikdy mě neomrzí poslouchat příběhy o tom, jak tato aplikace pomohla lidem, a pokud vám pomohla, nebo jste právě našli Reactive Resume jako úžasný nástroj, dejte mi vědět. Můžete mě kontaktovat na mých webových stránkách."
},
"sourceCode": {
"heading": "Zdrojový kód",
"text": "Chcete spustit projekt z jeho zdroje? Jste vývojář ochotný přispět k vývoji open-source tohoto projektu? Klikněte na tlačítko níže.",
"button": "GitHub repozitář"
},
"footer": "Vyrobil s láskou <1> Amruth Pillai </1>"
},
"tooltips": {
"uploadPhotograph": "Nahrát fotografii",
"backToDashboard": "Přejít zpět na řídicí panel"
},
"emptyList": "Tento seznam je prázdný."
},
"modals": {
"auth": {
"whoAreYou": "Kdo jsi?",
"welcome": "Vítej, {{name}}!",
"loggedOutText": "Reactive Resume potřebuje vědět, kdo jste, aby vás mohl bezpečně ověřit do aplikace a zobrazit pouze vaše informace. Jakmile se nacházíte, můžete začít budovat svůj životopis, upravovat jej a přidávat nové dovednosti nebo jej sdílet se světem!",
"loggedInText": "Skvělé. Nyní, když jste se ověřili, můžeme pokračovat se skutečným důvodem, proč jste tu. Kliknutím na tlačítko Přejít na aplikaci zahájíte vytváření životopisu!",
"buttons": {
"google": "Přihlaste se pomocí Google",
"anonymous": "Přihlásit se anonymně"
}
},
"import": {
"button": "Vybrat soubor",
"reactiveResume": {
"heading": "Importovat z Reactive Resume",
"text": "Reactive Resume má svůj vlastní formát schémat, aby co nejvíce využil všech nastavitelných možností, které může nabídnout. Pokud chcete importovat zálohu svého pokračování, vytvořenou pomocí této aplikace, stačí nahrát soubor pomocí tlačítka níže."
},
"jsonResume": {
"heading": "Importovat z JSON Resume",
"text": "JSON Resume je otevřený standard pro strukturu schématu životopisu. Pokud jste jedním z mnoha nadšenců, kteří mají svůj životopis připravený v tomto formátu, stačí pouze jedno kliknutí a můžete začít s Reactive Resume."
},
"linkedIn": {
"heading": "Importovat z LinkedIn",
"text": "JSON exportovaný z LinkedIn můžete importovat kliknutím na tlačítko níže a výběrem příslušného souboru."
}
},
"export": {
"printDialog": {
"heading": "Použít tiskový dialog prohlížeče",
"text": "Pro ty z vás, kteří chtějí rychlé řešení, se nemusíte dívat dále než váš prohlížeč. Vše, co musíte udělat, je stiskněte Ctrl/Cmd + P a otevřete dialogové okno s tiskem ve vašem prohlížeči a můžete jej ihned vytisknout.",
"button": "Vytisknout životopis"
},
"downloadPDF": {
"heading": "Stáhnout PDF",
"text": "Tyto možnosti vám umožní vytisknout neomezenou verzi vašeho životopisu na jednu stránku, ideální pro ty, kteří mají hodně obsahu. Alternativně si můžete jediným kliknutím stáhnout také vícestránkovou verzi vašeho životopisu.",
"buttons": {
"single": "Životopis na jednu stránku",
"multi": "Životopis na více stránek"
}
},
"jsonFormat": {
"heading": "Exportovat do formátu JSON",
"text": "Můžete také exportovat svá data do formátu JSON pro bezpečné uchování, abyste je mohli snadno importovat zpět do Reactive Resume, kdykoli budete chtít upravit nebo vygenerovat životopis.",
"button": "Exportovat JSON"
}
}
}
}

View File

@ -87,6 +87,7 @@
"templates": "Skabeloner",
"layout": "Layout",
"colors": "Farver",
"font-size": "Skriftstørrelse",
"fonts": "Skrifttyper",
"actions": "Handlinger",
"settings": "Indstillinger",

View File

@ -87,6 +87,7 @@
"templates": "Mallit",
"layout": "Ulkoasu",
"colors": "Värit",
"font-size": "Fontin koko",
"fonts": "Kirjasin",
"actions": "Toiminnot",
"settings": "Asetukset",

View File

@ -87,6 +87,7 @@
"templates": "Modèles",
"layout": "Disposition",
"colors": "Couleurs",
"font-size": "Taille de la police",
"fonts": "Polices",
"actions": "Actions",
"settings": "Options",

View File

@ -1,4 +1,5 @@
import ar from './ar.json';
import cs from './cs.json';
import da from './da.json';
import de from './de.json';
import en from './en.json';
@ -23,6 +24,7 @@ import zh from './zh.json';
export default {
ar: { translation: ar },
cs: { translation: cs },
da: { translation: da },
de: { translation: de },
en: { translation: en },

View File

@ -87,6 +87,7 @@
"templates": "Templates",
"layout": "Layout",
"colors": "Kleuren",
"font-size": "Lettergrootte",
"fonts": "Lettertypes",
"actions": "Acties",
"settings": "Instellingen",

View File

@ -12,6 +12,8 @@ import Onyx from '../../templates/Onyx';
import Pikachu from '../../templates/Pikachu';
import styles from './view.module.css';
import Celebi from '../../templates/Celebi';
import fontSizeOptions from '../../data/fontSizeOptions';
import { scaler } from '../../utils';
const ResumeViewer = ({ id }) => {
const { t, i18n } = useTranslation();
@ -33,6 +35,14 @@ const ResumeViewer = ({ id }) => {
setResume(data);
i18n.changeLanguage(data.metadata.language || 'en');
for (const [key, sizeDefault] of Object.entries(fontSizeOptions)) {
document.documentElement.style.setProperty(
key,
`${scaler(data.metadata.fontSize) * sizeDefault}rem`,
);
}
return setLoading(false);
})();
}, [id]);

View File

@ -1,6 +1,6 @@
import dayjs from 'dayjs';
import 'dayjs/locale/ar';
import 'dayjs/locale/zh';
import 'dayjs/locale/cs';
import 'dayjs/locale/da';
import 'dayjs/locale/de';
import 'dayjs/locale/en';
@ -17,6 +17,7 @@ import 'dayjs/locale/pl';
import 'dayjs/locale/pt';
import 'dayjs/locale/tr';
import 'dayjs/locale/uk';
import 'dayjs/locale/zh';
import relativeTime from 'dayjs/plugin/relativeTime';
dayjs.extend(relativeTime);

View File

@ -18,6 +18,17 @@ export const isFileImage = (file) => {
return file && acceptedImageTypes.includes(file.type);
};
export const scaler = (value) => {
const logMax = 2.5;
const logMin = 0.6;
const steps = 20;
const logRange = logMax / logMin;
const logStepSize = logRange ** (1 / steps);
const min = 0;
return logStepSize ** (value - min) * logMin;
};
export const formatDate = ({ date, language = 'en', includeDay = false }) => {
const template = includeDay ? 'DD MMMM YYYY' : 'MMMM YYYY';