mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2025-11-10 04:22:27 +10:00
Compare commits
44 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a037a091e7 | |||
| f3a4c17cb4 | |||
| f06f7ad2e5 | |||
| aab2e5c8a9 | |||
| 4318dbe762 | |||
| ae3ff274ee | |||
| 164403c495 | |||
| 8595c92fb7 | |||
| 8f75f32f88 | |||
| 0d44189a5f | |||
| cd16a6d360 | |||
| 7b795bfaa4 | |||
| 8f78d47661 | |||
| 0b5e5a2ece | |||
| 9eade9514c | |||
| d744e06e96 | |||
| 9657c199d2 | |||
| 2dbe737b73 | |||
| f624699efa | |||
| e46f473754 | |||
| 767f4bf4bc | |||
| 1c5d025c15 | |||
| 8de8d89290 | |||
| 83662122a5 | |||
| 126482a760 | |||
| b04c22a27b | |||
| 63f88a3d1c | |||
| bd519db14f | |||
| a49aa42176 | |||
| 1a382db4d9 | |||
| c68f75dc8c | |||
| c12de0c013 | |||
| 4cafaf306a | |||
| 0238cf18a5 | |||
| 2f6072a7ba | |||
| 55dd2c5925 | |||
| a3e25f87fa | |||
| 9e82ea11c3 | |||
| 62fd63e41f | |||
| b91c175352 | |||
| 898e2314fc | |||
| bca2aa2fe5 | |||
| 427fdb717a | |||
| ee5b0187e2 |
12
.github/workflows/docker-build-push.yml
vendored
12
.github/workflows/docker-build-push.yml
vendored
@ -18,20 +18,20 @@ jobs:
|
||||
run: echo ::set-output name=tag::${GITHUB_REF#refs/*/}
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v1.14.1
|
||||
uses: docker/login-action@v2.0.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v1.14.1
|
||||
uses: docker/login-action@v2.0.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: $GITHUB_REPOSITORY_OWNER
|
||||
password: ${{ secrets.GH_TOKEN }}
|
||||
|
||||
- name: Build and Push Client Image
|
||||
uses: docker/build-push-action@v2.10.0
|
||||
uses: docker/build-push-action@v3.0.0
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
@ -55,20 +55,20 @@ jobs:
|
||||
run: echo ::set-output name=tag::${GITHUB_REF#refs/*/}
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v1.14.1
|
||||
uses: docker/login-action@v2.0.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v1.14.1
|
||||
uses: docker/login-action@v2.0.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: $GITHUB_REPOSITORY_OWNER
|
||||
password: ${{ secrets.GH_TOKEN }}
|
||||
|
||||
- name: Build and Push Server Image
|
||||
uses: docker/build-push-action@v2.10.0
|
||||
uses: docker/build-push-action@v3.0.0
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
|
||||
37
CHANGELOG.md
37
CHANGELOG.md
@ -2,6 +2,43 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||
|
||||
### [3.4.6](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.4.5...v3.4.6) (2022-06-19)
|
||||
|
||||
## [3.6.0](https://github.com/dvd741-a/Reactive-Resume/compare/v3.3.4...v3.6.0) (2022-06-05)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **all:** upgrade to v3.4.0 ([87d381f](https://github.com/dvd741-a/Reactive-Resume/commit/87d381fe8eab9ca4624df5de6e8b9ab18a072b67))
|
||||
* **i18n:** add Hungrarian (Magyar) language ([35fe4e2](https://github.com/dvd741-a/Reactive-Resume/commit/35fe4e27744b6f7325b25db2cf3b626ed8598623))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **i18n:** fix language mismatch in exported pdf ([62fd63e](https://github.com/dvd741-a/Reactive-Resume/commit/62fd63e41fe10fba843a40fb08191f5944f2b2fc))
|
||||
* **typeorm:** update typeorm to latest 0.2.x for secpatch ([5bdb92b](https://github.com/dvd741-a/Reactive-Resume/commit/5bdb92b1cff9e56879f9bbf31801d6554a00a8d5))
|
||||
|
||||
## [3.5.0](https://github.com/dvd741-a/Reactive-Resume/compare/v3.3.4...v3.5.0) (2022-06-05)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **all:** upgrade to v3.4.0 ([87d381f](https://github.com/dvd741-a/Reactive-Resume/commit/87d381fe8eab9ca4624df5de6e8b9ab18a072b67))
|
||||
* **i18n:** add Hungrarian (Magyar) language ([35fe4e2](https://github.com/dvd741-a/Reactive-Resume/commit/35fe4e27744b6f7325b25db2cf3b626ed8598623))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **i18n:** fix language mismatch in exported pdf ([62fd63e](https://github.com/dvd741-a/Reactive-Resume/commit/62fd63e41fe10fba843a40fb08191f5944f2b2fc))
|
||||
* **typeorm:** update typeorm to latest 0.2.x for secpatch ([5bdb92b](https://github.com/dvd741-a/Reactive-Resume/commit/5bdb92b1cff9e56879f9bbf31801d6554a00a8d5))
|
||||
|
||||
### [3.4.5](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.4.4...v3.4.5) (2022-05-24)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **i18n:** fix language mismatch in exported pdf ([62fd63e](https://github.com/AmruthPillai/Reactive-Resume/commit/62fd63e41fe10fba843a40fb08191f5944f2b2fc))
|
||||
|
||||
## [3.4.4](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.4.3...v3.4.4) (2022-05-02)
|
||||
|
||||
### Features
|
||||
|
||||
@ -64,12 +64,15 @@ You have complete control over what goes into your resume, how it looks, what co
|
||||
- French (Français)
|
||||
- German (Deutsch)
|
||||
- Greek (Ελληνικά)
|
||||
- Hebrew (Ivrit)
|
||||
- Hindi (हिन्दी)
|
||||
- Hungarian (Magyar)
|
||||
- Indonesian (Bahasa Indonesia)
|
||||
- Italian (Italiano)
|
||||
- Kannada (ಕನ್ನಡ)
|
||||
- Malayalam (മലയാളം)
|
||||
- Odia (ଓଡ଼ିଆ)
|
||||
- Persian (Farsi)
|
||||
- Polish (Polski)
|
||||
- Portuguese (Português)
|
||||
- Russian (русский)
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
plugins {
|
||||
id 'com.android.application' version '7.1.2' apply false
|
||||
id 'com.android.library' version '7.1.2' apply false
|
||||
id 'org.jetbrains.kotlin.android' version '1.6.21' apply false
|
||||
id 'org.jetbrains.kotlin.android' version '1.7.0' apply false
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
|
||||
@ -14,13 +14,16 @@ export const languages: Language[] = [
|
||||
{ code: 'en', name: 'English' },
|
||||
{ code: 'es', name: 'Spanish', localName: 'Español' },
|
||||
{ code: 'fr', name: 'French', localName: 'Français' },
|
||||
{ code: 'he', name: 'Hebrew', localName: 'Ivrit' },
|
||||
{ code: 'hi', name: 'Hindi', localName: 'हिन्दी' },
|
||||
{ code: 'hu', name: 'Hungarian', localName: 'Magyar' },
|
||||
{ code: 'id', name: 'Indonesian', localName: 'Bahasa Indonesia' },
|
||||
{ code: 'it', name: 'Italian', localName: 'Italiano' },
|
||||
{ code: 'kn', name: 'Kannada', localName: 'ಕನ್ನಡ' },
|
||||
{ code: 'ml', name: 'Malayalam', localName: 'മലയാളം' },
|
||||
{ code: 'nl', name: 'Dutch', localName: 'Nederlands' },
|
||||
{ code: 'or', name: 'Odia', localName: 'ଓଡ଼ିଆ' },
|
||||
{ code: 'fa', name: 'Persian', localName: 'Farsi' },
|
||||
{ code: 'pl', name: 'Polish', localName: 'Polski' },
|
||||
{ code: 'pt', name: 'Portuguese', localName: 'Português' },
|
||||
{ code: 'ru', name: 'Russian', localName: 'русский' },
|
||||
|
||||
@ -12,9 +12,12 @@ const i18nConfig = {
|
||||
'el',
|
||||
'en',
|
||||
'es',
|
||||
'fa',
|
||||
'fr',
|
||||
'he',
|
||||
'hi',
|
||||
'hu',
|
||||
'id',
|
||||
'it',
|
||||
'kn',
|
||||
'ml',
|
||||
|
||||
@ -9,70 +9,74 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@beam-australia/react-env": "^3.1.1",
|
||||
"@date-io/dayjs": "^2.14.0",
|
||||
"@emotion/css": "^11.9.0",
|
||||
"@emotion/react": "^11.9.0",
|
||||
"@emotion/styled": "^11.8.1",
|
||||
"@hookform/resolvers": "2.8.8",
|
||||
"@monaco-editor/react": "^4.4.4",
|
||||
"@mui/icons-material": "^5.6.2",
|
||||
"@mui/lab": "^5.0.0-alpha.79",
|
||||
"@mui/material": "^5.6.3",
|
||||
"@reduxjs/toolkit": "^1.8.1",
|
||||
"@emotion/react": "^11.9.3",
|
||||
"@emotion/styled": "^11.9.3",
|
||||
"@hookform/resolvers": "2.9.1",
|
||||
"@monaco-editor/react": "^4.4.5",
|
||||
"@mui/icons-material": "^5.8.4",
|
||||
"@mui/lab": "^5.0.0-alpha.86",
|
||||
"@mui/material": "^5.8.4",
|
||||
"@mui/system": "^5.8.4",
|
||||
"@mui/x-date-pickers": "5.0.0-alpha.6",
|
||||
"@next/env": "^12.1.6",
|
||||
"@reduxjs/toolkit": "^1.8.2",
|
||||
"axios": "^0.27.2",
|
||||
"clsx": "^1.1.1",
|
||||
"dayjs": "^1.11.1",
|
||||
"dayjs": "^1.11.3",
|
||||
"downloadjs": "^1.4.7",
|
||||
"joi": "^17.6.0",
|
||||
"lodash": "^4.17.21",
|
||||
"md5-hex": "^4.0.0",
|
||||
"monaco-editor": "^0.33.0",
|
||||
"nanoid": "^3.3.3",
|
||||
"next": "12.1.5",
|
||||
"nanoid": "^3.3.4",
|
||||
"next": "12.1.6",
|
||||
"next-i18next": "^11.0.0",
|
||||
"react": "17.0.2",
|
||||
"react": "18.2.0",
|
||||
"react-beautiful-dnd": "^13.1.0",
|
||||
"react-colorful": "^5.5.1",
|
||||
"react-dnd": "15.1.2",
|
||||
"react-dnd-html5-backend": "15.1.3",
|
||||
"react-dom": "17.0.2",
|
||||
"react-hook-form": "^7.30.0",
|
||||
"react-dnd": "16.0.1",
|
||||
"react-dnd-html5-backend": "16.0.1",
|
||||
"react-dom": "18.2.0",
|
||||
"react-hook-form": "^7.32.2",
|
||||
"react-hot-toast": "2.2.0",
|
||||
"react-hotkeys-hook": "^3.4.4",
|
||||
"react-icons": "^4.3.1",
|
||||
"react-hotkeys-hook": "^3.4.6",
|
||||
"react-icons": "^4.4.0",
|
||||
"react-markdown": "^8.0.3",
|
||||
"react-query": "^3.38.1",
|
||||
"react-redux": "^8.0.1",
|
||||
"react-query": "^3.39.1",
|
||||
"react-redux": "^8.0.2",
|
||||
"react-zoom-pan-pinch": "^2.1.3",
|
||||
"redux": "^4.2.0",
|
||||
"redux-persist": "^6.0.0",
|
||||
"redux-saga": "^1.1.3",
|
||||
"remark-gfm": "^3.0.1",
|
||||
"sharp": "^0.30.4",
|
||||
"sharp": "^0.30.6",
|
||||
"uuid": "^8.3.2",
|
||||
"webfontloader": "^1.6.28"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.17.10",
|
||||
"@babel/core": "^7.18.5",
|
||||
"@reactive-resume/schema": "workspace:*",
|
||||
"@tailwindcss/typography": "^0.5.2",
|
||||
"@types/downloadjs": "^1.4.3",
|
||||
"@types/lodash": "^4.14.182",
|
||||
"@types/node": "17.0.31",
|
||||
"@types/react": "17.0.2",
|
||||
"@types/node": "18.0.0",
|
||||
"@types/react": "18.0.14",
|
||||
"@types/react-beautiful-dnd": "^13.1.2",
|
||||
"@types/react-redux": "^7.1.24",
|
||||
"@types/tailwindcss": "^3.0.10",
|
||||
"@types/uuid": "^8.3.4",
|
||||
"@types/webfontloader": "^1.6.34",
|
||||
"autoprefixer": "^10.4.6",
|
||||
"csstype": "^3.0.11",
|
||||
"eslint": "^8.14.0",
|
||||
"eslint-config-next": "12.1.5",
|
||||
"next-sitemap": "^2.5.20",
|
||||
"postcss": "^8.4.13",
|
||||
"prettier": "^2.6.2",
|
||||
"sass": "^1.51.0",
|
||||
"tailwindcss": "^3.0.24",
|
||||
"typescript": "^4.6.4"
|
||||
"autoprefixer": "^10.4.7",
|
||||
"csstype": "^3.1.0",
|
||||
"eslint": "^8.18.0",
|
||||
"eslint-config-next": "12.1.6",
|
||||
"next-sitemap": "^3.1.1",
|
||||
"postcss": "^8.4.14",
|
||||
"prettier": "^2.7.1",
|
||||
"sass": "^1.52.3",
|
||||
"tailwindcss": "^3.1.3",
|
||||
"typescript": "^4.7.4"
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,6 +59,14 @@ const Preview: NextPage<Props> = ({ username, slug, resume: initialData }) => {
|
||||
}
|
||||
}, [dispatch, initialData]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isEmpty(resume) && router.locale !== resume.metadata.locale) {
|
||||
const { pathname, asPath, query } = router;
|
||||
|
||||
router.push({ pathname, query }, asPath, { locale: resume.metadata.locale });
|
||||
}
|
||||
}, [resume, router]);
|
||||
|
||||
useQuery<Resume>(`resume/${username}/${slug}`, () => fetchResumeByIdentifier({ username, slug }), {
|
||||
initialData,
|
||||
retry: false,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import '@/styles/globals.scss';
|
||||
|
||||
import DateAdapter from '@mui/lab/AdapterDayjs';
|
||||
import LocalizationProvider from '@mui/lab/LocalizationProvider';
|
||||
import DayjsAdapter from '@date-io/dayjs';
|
||||
import { LocalizationProvider } from '@mui/lab';
|
||||
import type { AppProps } from 'next/app';
|
||||
import Head from 'next/head';
|
||||
import Script from 'next/script';
|
||||
@ -32,7 +32,7 @@ const App: React.FC<AppProps> = ({ Component, pageProps }) => {
|
||||
</Head>
|
||||
|
||||
<ReduxProvider store={store}>
|
||||
<LocalizationProvider dateAdapter={DateAdapter}>
|
||||
<LocalizationProvider dateAdapter={DayjsAdapter}>
|
||||
<PersistGate loading={null} persistor={persistor}>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<WrapperRegistry>
|
||||
|
||||
@ -7,6 +7,7 @@ import get from 'lodash/get';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
import { GetServerSideProps, NextPage } from 'next';
|
||||
import Link from 'next/link';
|
||||
import { useRouter } from 'next/router';
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
|
||||
import { useEffect } from 'react';
|
||||
import toast from 'react-hot-toast';
|
||||
@ -35,6 +36,8 @@ export const getServerSideProps: GetServerSideProps<Props> = async ({ query, loc
|
||||
};
|
||||
|
||||
const Preview: NextPage<Props> = ({ shortId }) => {
|
||||
const router = useRouter();
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const { data: resume } = useQuery<Resume>(`resume/${shortId}`, () => fetchResumeByShortId({ shortId }), {
|
||||
@ -52,6 +55,14 @@ const Preview: NextPage<Props> = ({ shortId }) => {
|
||||
if (resume) dispatch(setResume(resume));
|
||||
}, [resume, dispatch]);
|
||||
|
||||
useEffect(() => {
|
||||
if (resume && !isEmpty(resume) && router.locale !== resume.metadata.locale) {
|
||||
const { pathname, asPath, query } = router;
|
||||
|
||||
router.push({ pathname, query }, asPath, { locale: resume.metadata.locale });
|
||||
}
|
||||
}, [resume, router]);
|
||||
|
||||
if (!resume || isEmpty(resume)) return null;
|
||||
|
||||
const layout: string[][][] = get(resume, 'metadata.layout', []);
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
{
|
||||
"common": {
|
||||
"actions": {
|
||||
"add": "إضافة {{فقرة}} جديدة",
|
||||
"delete": "حذة {{الفقرة}}",
|
||||
"edit": "تحرير {{الفقرة}}"
|
||||
"add": "إضافة {{token}} جديدة",
|
||||
"delete": "حذف {{token}}",
|
||||
"edit": "تحرير {{token}}"
|
||||
},
|
||||
"columns": {
|
||||
"heading": "الأعمدة",
|
||||
@ -24,13 +24,13 @@
|
||||
"label": "تاريخ الانتهاء"
|
||||
},
|
||||
"keywords": {
|
||||
"label": "الكلمات الرئيسية"
|
||||
"label": "الكلمات الدالة"
|
||||
},
|
||||
"level": {
|
||||
"label": "مستوى"
|
||||
},
|
||||
"levelNum": {
|
||||
"label": "المستوى (Number)"
|
||||
"label": "المستوى (العدد)"
|
||||
},
|
||||
"name": {
|
||||
"label": "الاسم"
|
||||
@ -42,7 +42,7 @@
|
||||
"label": "المنصب"
|
||||
},
|
||||
"start-date": {
|
||||
"label": "تاريخ البداية"
|
||||
"label": "تاريخ البدء"
|
||||
},
|
||||
"subtitle": {
|
||||
"label": "العنوان الفرعي"
|
||||
|
||||
361
client/public/locales/fa/builder.json
Normal file
361
client/public/locales/fa/builder.json
Normal file
@ -0,0 +1,361 @@
|
||||
{
|
||||
"common": {
|
||||
"actions": {
|
||||
"add": "{{token}} جدید اضافه کنید",
|
||||
"delete": "حذف {{token}}",
|
||||
"edit": "ویرایش {{token}}"
|
||||
},
|
||||
"columns": {
|
||||
"heading": "ستونها",
|
||||
"tooltip": "تغییر تعداد ستونها"
|
||||
},
|
||||
"form": {
|
||||
"date": {
|
||||
"label": "تاریخ"
|
||||
},
|
||||
"description": {
|
||||
"label": "توضیحات"
|
||||
},
|
||||
"email": {
|
||||
"label": "آدرس ایمیل"
|
||||
},
|
||||
"end-date": {
|
||||
"help-text": "اگر هنوز پایان نیافته، این قسمت را خالی بگذارید",
|
||||
"label": "تاریخ پایان"
|
||||
},
|
||||
"keywords": {
|
||||
"label": "کلمات کلیدی"
|
||||
},
|
||||
"level": {
|
||||
"label": "سطح"
|
||||
},
|
||||
"levelNum": {
|
||||
"label": "سطح (عدد)"
|
||||
},
|
||||
"name": {
|
||||
"label": "نام"
|
||||
},
|
||||
"phone": {
|
||||
"label": "شماره تلفن"
|
||||
},
|
||||
"position": {
|
||||
"label": "عنوان شغلی"
|
||||
},
|
||||
"start-date": {
|
||||
"label": "تاریخ شروع"
|
||||
},
|
||||
"subtitle": {
|
||||
"label": "عنوان فرعی"
|
||||
},
|
||||
"summary": {
|
||||
"label": "درباره من"
|
||||
},
|
||||
"title": {
|
||||
"label": "عنوان"
|
||||
},
|
||||
"url": {
|
||||
"label": "وبسایت"
|
||||
}
|
||||
},
|
||||
"glossary": {
|
||||
"page": "صفحه"
|
||||
},
|
||||
"list": {
|
||||
"actions": {
|
||||
"delete": "حذف",
|
||||
"duplicate": "کپی",
|
||||
"edit": "ویرایش"
|
||||
},
|
||||
"empty-text": "این لیست خالی است."
|
||||
},
|
||||
"tooltip": {
|
||||
"delete-item": "آیا از حذف این مورد اطمینان دارید؟ این عمل غیرقابل برگشت است.",
|
||||
"delete-section": "حذف بخش",
|
||||
"rename-section": "تغییر نام بخش",
|
||||
"toggle-visibility": "تغییر وضعیت نمایش"
|
||||
}
|
||||
},
|
||||
"controller": {
|
||||
"tooltip": {
|
||||
"center-artboard": "قرار دادن صفحه در مرکز",
|
||||
"copy-link": "کپی کردن لینک رزومه",
|
||||
"export-pdf": "خروجی PDF",
|
||||
"toggle-orientation": "تغییر وضعیت جهتگیری صفحه",
|
||||
"toggle-page-break-line": "تغییر وضعیت خط شکست صفحه",
|
||||
"toggle-sidebars": "باز/بسته کردن نوار کنار صفحه",
|
||||
"zoom-in": "بزرگنمایی",
|
||||
"zoom-out": "کوچکنمایی"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"menu": {
|
||||
"delete": "حذف",
|
||||
"duplicate": "کپی",
|
||||
"rename": "تغییر نام",
|
||||
"share-link": "اشتراکگذاری لینک",
|
||||
"tooltips": {
|
||||
"delete": "آیا از حذف این رزومه اطمینان دارید؟ این عمل غیرقابل برگشت است.",
|
||||
"share-link": "باید وضعیت نمایش رزومه خود را به عمومی تغییر دهید تا برای دیگران قابل مشاهده باشد."
|
||||
}
|
||||
}
|
||||
},
|
||||
"leftSidebar": {
|
||||
"sections": {
|
||||
"awards": {
|
||||
"form": {
|
||||
"awarder": {
|
||||
"label": "اعطا کننده"
|
||||
}
|
||||
}
|
||||
},
|
||||
"basics": {
|
||||
"actions": {
|
||||
"photo-filters": "فیلترهای تصویر"
|
||||
},
|
||||
"heading": "موارد پایه",
|
||||
"headline": {
|
||||
"label": "سرصفحه"
|
||||
},
|
||||
"name": {
|
||||
"label": "نام کامل"
|
||||
},
|
||||
"birthdate": {
|
||||
"label": "تاریخ تولد"
|
||||
},
|
||||
"photo-filters": {
|
||||
"effects": {
|
||||
"border": {
|
||||
"label": "لبه"
|
||||
},
|
||||
"grayscale": {
|
||||
"label": "سیاه و سفید"
|
||||
},
|
||||
"heading": "افکتها"
|
||||
},
|
||||
"shape": {
|
||||
"heading": "شکل"
|
||||
},
|
||||
"size": {
|
||||
"heading": "اندازه (بر حسب پیکسل)"
|
||||
}
|
||||
},
|
||||
"photo-upload": {
|
||||
"tooltip": {
|
||||
"remove": "حذف تصویر",
|
||||
"upload": "آپلود تصویر"
|
||||
}
|
||||
}
|
||||
},
|
||||
"certifications": {
|
||||
"form": {
|
||||
"issuer": {
|
||||
"label": "صادرکننده"
|
||||
}
|
||||
}
|
||||
},
|
||||
"education": {
|
||||
"form": {
|
||||
"area-study": {
|
||||
"label": "رشته تحصیلی"
|
||||
},
|
||||
"courses": {
|
||||
"label": "دورهها"
|
||||
},
|
||||
"degree": {
|
||||
"label": "مدرک تحصیلی"
|
||||
},
|
||||
"grade": {
|
||||
"label": "نمره"
|
||||
},
|
||||
"institution": {
|
||||
"label": "مؤسسه"
|
||||
}
|
||||
}
|
||||
},
|
||||
"location": {
|
||||
"address": {
|
||||
"label": "نشانی"
|
||||
},
|
||||
"city": {
|
||||
"label": "شهر"
|
||||
},
|
||||
"country": {
|
||||
"label": "كشور"
|
||||
},
|
||||
"heading": "موقعیت مکانی",
|
||||
"postal-code": {
|
||||
"label": "کد پستی"
|
||||
},
|
||||
"region": {
|
||||
"label": "منطقه"
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"form": {
|
||||
"network": {
|
||||
"label": "شبکه اجتماعی"
|
||||
},
|
||||
"username": {
|
||||
"label": "نام کاربری"
|
||||
}
|
||||
},
|
||||
"heading": "پروفایلها",
|
||||
"heading_one": "پروفایل"
|
||||
},
|
||||
"publications": {
|
||||
"form": {
|
||||
"publisher": {
|
||||
"label": "ناشر"
|
||||
}
|
||||
}
|
||||
},
|
||||
"references": {
|
||||
"form": {
|
||||
"relationship": {
|
||||
"label": "نسبت"
|
||||
}
|
||||
}
|
||||
},
|
||||
"section": {
|
||||
"heading": "بخش"
|
||||
},
|
||||
"volunteer": {
|
||||
"form": {
|
||||
"organization": {
|
||||
"label": "سازمان"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"rightSidebar": {
|
||||
"sections": {
|
||||
"css": {
|
||||
"heading": "CSS سفارشی"
|
||||
},
|
||||
"export": {
|
||||
"heading": "خروجی",
|
||||
"json": {
|
||||
"primary": "JSON",
|
||||
"secondary": "یک نسخه JSON از رزومه خود را دانلود کنید که میتواند دوباره در Reactive Resume بارگذاری شود."
|
||||
},
|
||||
"pdf": {
|
||||
"loading": {
|
||||
"primary": "در حال تولید PDF",
|
||||
"secondary": "لطفاً منتظر بمانید تا PDF شما تولید شود، ممکن است تا ۱۵ ثانیه طول بکشد."
|
||||
},
|
||||
"normal": {
|
||||
"primary": "PDF",
|
||||
"secondary": "یک PDF از رزومه خود را دانلود کنید که میتوانید آن را چاپ کرده و به شغل رویایی خود ارسال کنید. این فایل را نمیتوان برای ویرایش بیشتر بارگذاری کرد."
|
||||
}
|
||||
}
|
||||
},
|
||||
"layout": {
|
||||
"heading": "چیدمان",
|
||||
"tooltip": {
|
||||
"reset-layout": "بازنشانی چیدمان"
|
||||
}
|
||||
},
|
||||
"links": {
|
||||
"bugs-features": {
|
||||
"body": "چیزی شما را از ایجاد رزومه باز میدارد؟ یا ایده جذابی برای اضافه کردن دارید؟ برای شروع یک issue در GitHub مطرح کنید.",
|
||||
"button": "GitHub Issues",
|
||||
"heading": "باگها؟ درخواست ویژگی جدید؟"
|
||||
},
|
||||
"donate": {
|
||||
"body": "اگر استفاده از Reactive Resume را دوست داشتید، لطفاً تا جایی که می توانید کمک مالی کنید تا برنامه را بدون تبلیغات و برای همیشه رایگان نگه دارید.",
|
||||
"button": "برای من یک قهوه بخر",
|
||||
"heading": "کمک مالی به Reactive Resume"
|
||||
},
|
||||
"github": "کد منبع",
|
||||
"heading": "لینکها"
|
||||
},
|
||||
"settings": {
|
||||
"global": {
|
||||
"date": {
|
||||
"primary": "تاریخ",
|
||||
"secondary": "فرمت تاریخ برای استفاده در سراسر برنامه"
|
||||
},
|
||||
"heading": "سراسری",
|
||||
"language": {
|
||||
"primary": "زبان",
|
||||
"secondary": "زبان مورد نمایش برای استفاده از برنامه"
|
||||
},
|
||||
"theme": {
|
||||
"primary": "پوسته"
|
||||
}
|
||||
},
|
||||
"heading": "تنظیمات",
|
||||
"page": {
|
||||
"break-line": {
|
||||
"primary": "خط شکست",
|
||||
"secondary": "برای مشخص کردن ارتفاع صفحه A4 یک خط در همه صفحات نشان داده شود"
|
||||
},
|
||||
"heading": "صفحه",
|
||||
"orientation": {
|
||||
"disabled": "زمانی که تنها یک صفحه وجود دارد، تاثیری ندارد",
|
||||
"primary": "جهتگیری",
|
||||
"secondary": "اینکه صفحات به صورت عمودی یا افقی نمایش داده شوند"
|
||||
}
|
||||
},
|
||||
"resume": {
|
||||
"heading": "رزومه",
|
||||
"reset": {
|
||||
"primary": "بازنشانی همه چیز",
|
||||
"secondary": "اشتباهات زیادی انجام دادید؟ اینجا کلیک کنید تا همه تغییرات بازنشانی شوند و از ابتدا شروع کنید. مراقب باشید، این عمل غیرقابل برگشت است."
|
||||
},
|
||||
"sample": {
|
||||
"primary": "بارگیری دادههای نمونه",
|
||||
"secondary": "نمیدانید از کجا شروع کنید؟برای اینکه تعدادی داده نمونه بارگیری شوند تا ببینید یک رزومه کامل به چه شکل است، اینجا کلیک کنید."
|
||||
}
|
||||
}
|
||||
},
|
||||
"sharing": {
|
||||
"heading": "اشتراکگذاری",
|
||||
"short-url": {
|
||||
"label": "انتخاب URL کوتاه"
|
||||
},
|
||||
"visibility": {
|
||||
"subtitle": "هرکسی با این لینک بتواند رزومه شما را ببیند",
|
||||
"title": "عمومی"
|
||||
}
|
||||
},
|
||||
"templates": {
|
||||
"heading": "قالبها"
|
||||
},
|
||||
"theme": {
|
||||
"form": {
|
||||
"background": {
|
||||
"label": "پسزمینه"
|
||||
},
|
||||
"primary": {
|
||||
"label": "اصلی"
|
||||
},
|
||||
"text": {
|
||||
"label": "متن"
|
||||
}
|
||||
},
|
||||
"heading": "پوسته"
|
||||
},
|
||||
"typography": {
|
||||
"form": {
|
||||
"font-family": {
|
||||
"label": "نوع فونت"
|
||||
},
|
||||
"font-size": {
|
||||
"label": "اندازه فونت"
|
||||
}
|
||||
},
|
||||
"heading": "تایپوگرافی",
|
||||
"widgets": {
|
||||
"body": {
|
||||
"label": "بدنه"
|
||||
},
|
||||
"headings": {
|
||||
"label": "سرصفحهها"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
29
client/public/locales/fa/common.json
Normal file
29
client/public/locales/fa/common.json
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
"avatar": {
|
||||
"menu": {
|
||||
"greeting": "سلام",
|
||||
"logout": "خروج"
|
||||
}
|
||||
},
|
||||
"footer": {
|
||||
"credit": "پروژهای پرشور توسط <1>Amruth Pillai</1>",
|
||||
"license": "ساختهشده توسط جامعه، برای جامعه."
|
||||
},
|
||||
"markdown": {
|
||||
"help-text": "این بخش از <1>markdown</1> پشتیبانی میکند."
|
||||
},
|
||||
"date": {
|
||||
"present": "امروز"
|
||||
},
|
||||
"subtitle": "یک رزومهساز رایگان و متنباز.",
|
||||
"title": "Reactive Resume",
|
||||
"toast": {
|
||||
"error": {
|
||||
"upload-file-size": "لطفا تنها فایلهایی با حجم کمتر از ۲ مگابایت آپلود کنید.",
|
||||
"upload-photo-size": "لطفا تنها عکس هایی با حجم کمتر از 2 مگابایت و ترجیحا مربع آپلود کنید."
|
||||
},
|
||||
"success": {
|
||||
"resume-link-copied": "لینک رزومه شما در کلیپبورد کپی شد."
|
||||
}
|
||||
}
|
||||
}
|
||||
25
client/public/locales/fa/dashboard.json
Normal file
25
client/public/locales/fa/dashboard.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"create-resume": {
|
||||
"subtitle": "از ابتدا شروع کنید",
|
||||
"title": "ساخت رزومه جدید"
|
||||
},
|
||||
"import-external": {
|
||||
"subtitle": "LinkedIn، JSON Resume، Reactive Resume",
|
||||
"title": "وارد کردن از منابع خارجی"
|
||||
},
|
||||
"resume": {
|
||||
"menu": {
|
||||
"delete": "حذف",
|
||||
"duplicate": "کپی",
|
||||
"open": "باز کردن",
|
||||
"rename": "تغییر نام",
|
||||
"share-link": "اشتراکگذاری لینک",
|
||||
"tooltips": {
|
||||
"delete": "آیا از حذف این رزومه اطمینان دارید؟ این عمل غیرقابل برگشت است.",
|
||||
"share-link": "باید وضعیت نمایش رزومه خود را به عمومی تغییر دهید تا برای دیگران قابل مشاهده باشد."
|
||||
}
|
||||
},
|
||||
"timestamp": "آخرین بهروزرسانی {{timestamp}} قبل"
|
||||
},
|
||||
"title": "داشبورد"
|
||||
}
|
||||
41
client/public/locales/fa/landing.json
Normal file
41
client/public/locales/fa/landing.json
Normal file
@ -0,0 +1,41 @@
|
||||
{
|
||||
"actions": {
|
||||
"app": "رفتن به برنامه",
|
||||
"login": "ورود",
|
||||
"logout": "خروج",
|
||||
"register": "ثبت نام"
|
||||
},
|
||||
"features": {
|
||||
"heading": "ویژگیها",
|
||||
"list": {
|
||||
"ads": "بدون تبلیغات",
|
||||
"export": "گرفتن خروجی از رزومه خود به فرمت JSON یا PDF",
|
||||
"free": "رایگان، برای همیشه",
|
||||
"import": "وارد کردن داده از LinkedIn، JSON Resume",
|
||||
"languages": "قابل دسترسی به چندین زبان",
|
||||
"more": "و تعداد زیادی ویژگی هیجان انگیز دیگر، <1>همهچیز را درباره آنها اینجا بخوانید</1>",
|
||||
"tracking": "بدون ردیابی کاربر"
|
||||
}
|
||||
},
|
||||
"links": {
|
||||
"heading": "لینکها",
|
||||
"links": {
|
||||
"donate": "حمایت مالی",
|
||||
"github": "کد منبع",
|
||||
"privacy": "حریم خصوصی",
|
||||
"service": "شرایط سرویسدهی"
|
||||
}
|
||||
},
|
||||
"screenshots": {
|
||||
"heading": "اسکرینشاتها"
|
||||
},
|
||||
"testimonials": {
|
||||
"heading": "نظرات کاربران",
|
||||
"body": "خوب یا بد، من دوست دارم نظر شما را در مورد Reactive Resume و اینکه تجربه کار با آن برای شما چگونه بوده است را بدانم.<br/>تعدادی از پیام های ارسال شده توسط کاربران در سراسر جهان را اینجا میبینید.",
|
||||
"contact": "میتوانید از طریق <1>ایمیل من</1> یا فرم تماس در <3>وبسایت من</3> با من در ارتباط باشید."
|
||||
},
|
||||
"summary": {
|
||||
"body": "Reactive Resume یک رزومه ساز رایگان و متنباز است که برای ایجاد، به روز رسانی و به اشتراک گذاری رزومه شما به آسانی شمردن ۱، ۲، ۳ ساخته شده است. با این برنامه، می توانید چندین رزومه ایجاد کنید و آنها را با کارفرماها یا دوستان از طریق یک لینک منحصر به فرد و چاپ آن به صورت PDF، همه به صورت رایگان، بدون تبلیغات، بدون ردیابی، بدون از دست دادن امنیت و حریم خصوصی داده های شما، به اشتراک بگذارید.",
|
||||
"heading": "درباره من"
|
||||
}
|
||||
}
|
||||
136
client/public/locales/fa/modals.json
Normal file
136
client/public/locales/fa/modals.json
Normal file
@ -0,0 +1,136 @@
|
||||
{
|
||||
"auth": {
|
||||
"forgot-password": {
|
||||
"actions": {
|
||||
"send-email": "ارسال ایمیل بازنشانی رمز عبور"
|
||||
},
|
||||
"body": "آدرس ایمیل حسابی را که می خواهید بازیابی کنید، وارد کنید.",
|
||||
"form": {
|
||||
"email": {
|
||||
"label": "آدرس ایمیل"
|
||||
}
|
||||
},
|
||||
"heading": "رمز عبور خود را فراموش کردهاید؟",
|
||||
"help-text": "اگر حساب مورد نظر موجود باشد، یک ایمیل با لینک بازنشانی رمز عبور خود دریافت میکنید."
|
||||
},
|
||||
"login": {
|
||||
"actions": {
|
||||
"login": "ورود",
|
||||
"google": "ورود با گوگل"
|
||||
},
|
||||
"body": "لطفا نام کاربری و رمز عبور مرتبط با حساب کاربری خود را وارد کنید تا وارد شوید و به رزومه خود دسترسی پیدا کنید، آن را مدیریت کنید و به اشتراک بگذارید.",
|
||||
"form": {
|
||||
"password": {
|
||||
"label": "رمز عبور"
|
||||
},
|
||||
"username": {
|
||||
"help-text": "همچنین می توانید آدرس ایمیل خود را وارد کنید",
|
||||
"label": "نام کاربری"
|
||||
}
|
||||
},
|
||||
"heading": "ورود به حساب کابری",
|
||||
"recover-text": "در صورتی که رمز عبور خود را فراموش کردهاید، می توانید از اینجا <1>حساب خود را بازیابی کنید</1>.",
|
||||
"register-text": "اگر حسابی ندارید، میتوانید از اینجا <1>یک حساب ایجاد کنید</1>."
|
||||
},
|
||||
"register": {
|
||||
"actions": {
|
||||
"register": "ثبت نام",
|
||||
"google": "ثبت نام با گوگل"
|
||||
},
|
||||
"body": "لطفا برای ایجاد حساب کاربری، اطلاعات شخصی خود را وارد کنید.",
|
||||
"form": {
|
||||
"confirm-password": {
|
||||
"label": "تکرار رمز عبور"
|
||||
},
|
||||
"email": {
|
||||
"label": "آدرس ایمیل"
|
||||
},
|
||||
"name": {
|
||||
"label": "نام کامل"
|
||||
},
|
||||
"password": {
|
||||
"label": "رمز عبور"
|
||||
},
|
||||
"username": {
|
||||
"label": "نام کاربری"
|
||||
}
|
||||
},
|
||||
"heading": "ایجاد حساب کاربری",
|
||||
"loginText": "اکر حساب کاربری دارید، میتوانید از <1>اینجا</1> وارد شوید."
|
||||
},
|
||||
"reset-password": {
|
||||
"actions": {
|
||||
"set-password": "تعیین رمز عبور جدید"
|
||||
},
|
||||
"body": "یک رمز عبور جدید برای حساب خود وارد کنید.",
|
||||
"form": {
|
||||
"confirm-password": {
|
||||
"label": "تکرار رمز عبور"
|
||||
},
|
||||
"password": {
|
||||
"label": "رمز عبور"
|
||||
}
|
||||
},
|
||||
"heading": "بازنشانی رمز عبور"
|
||||
}
|
||||
},
|
||||
"dashboard": {
|
||||
"create-resume": {
|
||||
"actions": {
|
||||
"create-resume": "ایجاد رزومه"
|
||||
},
|
||||
"body": "ساخت رزومه خود را با نامگذاری آن شروع کنید. این نام میتواند به سمتی که برای آن درخواست میکنید مرتبط باشد، یا میانوعده مورد علاقه شما باشد.",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "نام"
|
||||
},
|
||||
"public": {
|
||||
"label": "آیا به صورت عمومی قابل دسترسی است؟"
|
||||
},
|
||||
"slug": {
|
||||
"label": "نام یکتا"
|
||||
}
|
||||
},
|
||||
"heading": "ایجاد یک رزومه جدید"
|
||||
},
|
||||
"import-external": {
|
||||
"heading": "وارد کردن از منابع خارجی",
|
||||
"json-resume": {
|
||||
"actions": {
|
||||
"upload-json": "آپلود JSON"
|
||||
},
|
||||
"body": "اگر یک <1>JSON Resume معتبر</1> که آماده کار است، می توانید از آن برای پیگیری سریع توسعه خود در Reactive Resume استفاده کنید. روی دکمه زیر کلیک کنید و برای شروع یک فایل JSON معتبر آپلود کنید.",
|
||||
"heading": "بارگذاری از JSON Resume"
|
||||
},
|
||||
"linkedin": {
|
||||
"actions": {
|
||||
"upload-archive": "آپلود آرشیو ZIP"
|
||||
},
|
||||
"body": "میتوانید با خروجی گرفتن از دادههای خود در LinkedIn و استفاده از آن برای پر کردن خودکار فیلدهای Reactive Resume در زمانصرفهجویی کنید. به بخش <1>Data Privacy</1> در LinkedIn بروید و یک آرشیو از دادههای خود را درخواست کنید. پس از در دسترس قرار گرفتن، فایل ZIP را در زیر آپلود کنید.",
|
||||
"heading": "بارگذاری از LinkedIn"
|
||||
},
|
||||
"reactive-resume": {
|
||||
"actions": {
|
||||
"upload-json": "آپلود JSON",
|
||||
"upload-json-v2": "آپلود JSON از ورژن ۲"
|
||||
},
|
||||
"body": "اگر یک فایل JSON دارید که با نسخه فعلی Reactive Resume خروجی گرفتهشده است، میتوانید آن را اینجا بارگذاری کنید تا دوباره نسخه قابل ویرایش دریافت کنید.",
|
||||
"heading": "بارگذاری از Reactive Resume"
|
||||
}
|
||||
},
|
||||
"rename-resume": {
|
||||
"actions": {
|
||||
"rename-resume": "تغییر نام رزومه"
|
||||
},
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "نام"
|
||||
},
|
||||
"slug": {
|
||||
"label": "نام یکتا"
|
||||
}
|
||||
},
|
||||
"heading": "نام رزومه خود را تغییر دهید"
|
||||
}
|
||||
}
|
||||
}
|
||||
29
client/public/locales/he/common.json
Normal file
29
client/public/locales/he/common.json
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
"avatar": {
|
||||
"menu": {
|
||||
"greeting": "שלום",
|
||||
"logout": "התנתק/י"
|
||||
}
|
||||
},
|
||||
"footer": {
|
||||
"credit": "פרויקט תשוקה מאת <1>אמרות פילאי</1>",
|
||||
"license": "על ידי הקהילה, עבור הקהילה."
|
||||
},
|
||||
"markdown": {
|
||||
"help-text": "סעיף זה תומך ב-<1>markdown</1> עיצוב."
|
||||
},
|
||||
"date": {
|
||||
"present": "הווה"
|
||||
},
|
||||
"subtitle": "בונה קורות חיים חינמי ובקוד פתוח.",
|
||||
"title": "קורות חיים תגובתיים",
|
||||
"toast": {
|
||||
"error": {
|
||||
"upload-file-size": "נא להעלות רק קבצים מתחת ל-2 מגה בייט.",
|
||||
"upload-photo-size": "נא להעלות רק תמונות מתחת ל-2 מגה בייט, רצוי מרובע."
|
||||
},
|
||||
"success": {
|
||||
"resume-link-copied": "קישור לקורות החיים שלך הועתק ללוח."
|
||||
}
|
||||
}
|
||||
}
|
||||
361
client/public/locales/id/builder.json
Normal file
361
client/public/locales/id/builder.json
Normal file
@ -0,0 +1,361 @@
|
||||
{
|
||||
"common": {
|
||||
"actions": {
|
||||
"add": "Tambah Baru {{token}}",
|
||||
"delete": "Hapus {{token}}",
|
||||
"edit": "Ubah {{token}}"
|
||||
},
|
||||
"columns": {
|
||||
"heading": "Kolom",
|
||||
"tooltip": "Ubah nomor kolom"
|
||||
},
|
||||
"form": {
|
||||
"date": {
|
||||
"label": "Tanggal"
|
||||
},
|
||||
"description": {
|
||||
"label": "Keterangan"
|
||||
},
|
||||
"email": {
|
||||
"label": "Alamat Email"
|
||||
},
|
||||
"end-date": {
|
||||
"help-text": "Biarkan kosong, Jika masih terbaru",
|
||||
"label": "Tanggal Akhir"
|
||||
},
|
||||
"keywords": {
|
||||
"label": "Kata Kunci"
|
||||
},
|
||||
"level": {
|
||||
"label": "Tingkat"
|
||||
},
|
||||
"levelNum": {
|
||||
"label": "Tingkat (Angka)"
|
||||
},
|
||||
"name": {
|
||||
"label": "Nama"
|
||||
},
|
||||
"phone": {
|
||||
"label": "Nomor Telepon"
|
||||
},
|
||||
"position": {
|
||||
"label": "Jabatan"
|
||||
},
|
||||
"start-date": {
|
||||
"label": "Tanggal Mulai"
|
||||
},
|
||||
"subtitle": {
|
||||
"label": "Sub Judul"
|
||||
},
|
||||
"summary": {
|
||||
"label": "Ringkasan"
|
||||
},
|
||||
"title": {
|
||||
"label": "Judul"
|
||||
},
|
||||
"url": {
|
||||
"label": "Situs web"
|
||||
}
|
||||
},
|
||||
"glossary": {
|
||||
"page": "Halaman"
|
||||
},
|
||||
"list": {
|
||||
"actions": {
|
||||
"delete": "Hapus",
|
||||
"duplicate": "Duplikat",
|
||||
"edit": "Ubah"
|
||||
},
|
||||
"empty-text": "Daftar ini kosong."
|
||||
},
|
||||
"tooltip": {
|
||||
"delete-item": "Anda yakin ingin menghapus item ini? Tindakan ini tidak dapat dibatalkan.",
|
||||
"delete-section": "Hapus Bagian",
|
||||
"rename-section": "Ganti Nama Bagian",
|
||||
"toggle-visibility": "Beralih Visibilitas"
|
||||
}
|
||||
},
|
||||
"controller": {
|
||||
"tooltip": {
|
||||
"center-artboard": "Tengahkan Artboard",
|
||||
"copy-link": "Salin Tautan ke Resume",
|
||||
"export-pdf": "Ekspor PDF",
|
||||
"toggle-orientation": "Beralih Orientasi Halaman",
|
||||
"toggle-page-break-line": "Beralih Garis Pemisah Halaman",
|
||||
"toggle-sidebars": "Beralih Sidebar",
|
||||
"zoom-in": "Perbesar",
|
||||
"zoom-out": "Perkecil"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"menu": {
|
||||
"delete": "Hapus",
|
||||
"duplicate": "Duplikat",
|
||||
"rename": "Ganti nama",
|
||||
"share-link": "Bagikan tautan",
|
||||
"tooltips": {
|
||||
"delete": "Anda yakin ingin menghapus Resume ini? Tindakan ini tidak dapat dibatalkan.",
|
||||
"share-link": "Anda perlu mengubah visibilitas resume Anda ke publik agar terlihat oleh orang lain."
|
||||
}
|
||||
}
|
||||
},
|
||||
"leftSidebar": {
|
||||
"sections": {
|
||||
"awards": {
|
||||
"form": {
|
||||
"awarder": {
|
||||
"label": "Penghargaan"
|
||||
}
|
||||
}
|
||||
},
|
||||
"basics": {
|
||||
"actions": {
|
||||
"photo-filters": "Filter Foto"
|
||||
},
|
||||
"heading": "Dasar",
|
||||
"headline": {
|
||||
"label": "Judul"
|
||||
},
|
||||
"name": {
|
||||
"label": "Nama Lengkap"
|
||||
},
|
||||
"birthdate": {
|
||||
"label": "Tanggal Lahir"
|
||||
},
|
||||
"photo-filters": {
|
||||
"effects": {
|
||||
"border": {
|
||||
"label": "Batas"
|
||||
},
|
||||
"grayscale": {
|
||||
"label": "Grayscale"
|
||||
},
|
||||
"heading": "Efek"
|
||||
},
|
||||
"shape": {
|
||||
"heading": "Bentuk"
|
||||
},
|
||||
"size": {
|
||||
"heading": "Besar (dalam px)"
|
||||
}
|
||||
},
|
||||
"photo-upload": {
|
||||
"tooltip": {
|
||||
"remove": "Hapus Foto",
|
||||
"upload": "Unggah Foto"
|
||||
}
|
||||
}
|
||||
},
|
||||
"certifications": {
|
||||
"form": {
|
||||
"issuer": {
|
||||
"label": "Penerbit"
|
||||
}
|
||||
}
|
||||
},
|
||||
"education": {
|
||||
"form": {
|
||||
"area-study": {
|
||||
"label": "Area belajar"
|
||||
},
|
||||
"courses": {
|
||||
"label": "Kursus"
|
||||
},
|
||||
"degree": {
|
||||
"label": "Gelar"
|
||||
},
|
||||
"grade": {
|
||||
"label": "Tingkatan"
|
||||
},
|
||||
"institution": {
|
||||
"label": "Lembaga"
|
||||
}
|
||||
}
|
||||
},
|
||||
"location": {
|
||||
"address": {
|
||||
"label": "Alamat"
|
||||
},
|
||||
"city": {
|
||||
"label": "Kota"
|
||||
},
|
||||
"country": {
|
||||
"label": "Negara"
|
||||
},
|
||||
"heading": "Lokasi",
|
||||
"postal-code": {
|
||||
"label": "Kode Pos"
|
||||
},
|
||||
"region": {
|
||||
"label": "Wilayah"
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"form": {
|
||||
"network": {
|
||||
"label": "Social Media"
|
||||
},
|
||||
"username": {
|
||||
"label": "Nama Panggilan"
|
||||
}
|
||||
},
|
||||
"heading": "Profil",
|
||||
"heading_one": "Profil"
|
||||
},
|
||||
"publications": {
|
||||
"form": {
|
||||
"publisher": {
|
||||
"label": "Penerbit"
|
||||
}
|
||||
}
|
||||
},
|
||||
"references": {
|
||||
"form": {
|
||||
"relationship": {
|
||||
"label": "Hubungan"
|
||||
}
|
||||
}
|
||||
},
|
||||
"section": {
|
||||
"heading": "Bagian"
|
||||
},
|
||||
"volunteer": {
|
||||
"form": {
|
||||
"organization": {
|
||||
"label": "Organisasi"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"rightSidebar": {
|
||||
"sections": {
|
||||
"css": {
|
||||
"heading": "Kostumisasi CSS"
|
||||
},
|
||||
"export": {
|
||||
"heading": "Ekspor",
|
||||
"json": {
|
||||
"primary": "JSON",
|
||||
"secondary": "Unduh versi JSON dari resume Anda yang dapat diimpor kembali ke Reactive Resume."
|
||||
},
|
||||
"pdf": {
|
||||
"loading": {
|
||||
"primary": "Membuat PDF",
|
||||
"secondary": "Harap tunggu saat ini PDF Anda sedang dibuat, mungkin memerlukan waktu hingga 15 detik."
|
||||
},
|
||||
"normal": {
|
||||
"primary": "PDF",
|
||||
"secondary": "Unduh PDF dari resume Anda yang dapat Anda cetak dan kirimkan ke pekerjaan impian Anda. File ini tidak dapat diimpor kembali untuk pengeditan lanjutan."
|
||||
}
|
||||
}
|
||||
},
|
||||
"layout": {
|
||||
"heading": "Tata Letak",
|
||||
"tooltip": {
|
||||
"reset-layout": "Atur ulang Layout"
|
||||
}
|
||||
},
|
||||
"links": {
|
||||
"bugs-features": {
|
||||
"body": "Sesuatu menghentikan Anda dari membuat resume? Atau apakah Anda memiliki ide luar biasa untuk ditambahkan? Buat Issues di GitHub untuk memulai.",
|
||||
"button": "Masalah GitHub",
|
||||
"heading": "Bugs? Request Fitur?"
|
||||
},
|
||||
"donate": {
|
||||
"body": "Jika Anda suka menggunakan Reactive Resume, harap pertimbangkan untuk donasi sebanyak mungkin untuk menjaga aplikasi tetap berjalan, tanpa iklan dan gratis selamanya.",
|
||||
"button": "Belikan Saya Kopi",
|
||||
"heading": "Donasi ke Reactive Resume"
|
||||
},
|
||||
"github": "Kode sumber",
|
||||
"heading": "Link"
|
||||
},
|
||||
"settings": {
|
||||
"global": {
|
||||
"date": {
|
||||
"primary": "Tanggal",
|
||||
"secondary": "Format tanggal untuk digunakan di seluruh aplikasi"
|
||||
},
|
||||
"heading": "Global",
|
||||
"language": {
|
||||
"primary": "Bahasa",
|
||||
"secondary": "Tampilkan bahasa untuk digunakan di seluruh aplikasi"
|
||||
},
|
||||
"theme": {
|
||||
"primary": "Tema"
|
||||
}
|
||||
},
|
||||
"heading": "Pengaturan",
|
||||
"page": {
|
||||
"break-line": {
|
||||
"primary": "Break Line",
|
||||
"secondary": "Tampilkan garis di semua halaman untuk menandai ketinggian halaman A4"
|
||||
},
|
||||
"heading": "Halaman",
|
||||
"orientation": {
|
||||
"disabled": "Tidak berpengaruh ketika hanya ada satu halaman",
|
||||
"primary": "Orientasi",
|
||||
"secondary": "Menampilkan halaman secara horizontal atau vertikal"
|
||||
}
|
||||
},
|
||||
"resume": {
|
||||
"heading": "Resume",
|
||||
"reset": {
|
||||
"primary": "Atur ulang Semuanya",
|
||||
"secondary": "Membuat terlalu banyak kesalahan? Klik di sini untuk mengatur ulang semua perubahan dan memulai dari awal. Hati-hati, tindakan ini tidak dapat dibatalkan."
|
||||
},
|
||||
"sample": {
|
||||
"primary": "Muat Data Sampel",
|
||||
"secondary": "Tidak yakin harus mulai dari mana? Klik di sini untuk memuat beberapa contoh data untuk melihat bagaimana resume lengkap terlihat."
|
||||
}
|
||||
}
|
||||
},
|
||||
"sharing": {
|
||||
"heading": "Bagikan",
|
||||
"short-url": {
|
||||
"label": "Gunakan URL pendek"
|
||||
},
|
||||
"visibility": {
|
||||
"subtitle": "Izinkan siapa pun yang memiliki tautan untuk melihat resume Anda",
|
||||
"title": "Publik"
|
||||
}
|
||||
},
|
||||
"templates": {
|
||||
"heading": "Template"
|
||||
},
|
||||
"theme": {
|
||||
"form": {
|
||||
"background": {
|
||||
"label": "Latar Belakang"
|
||||
},
|
||||
"primary": {
|
||||
"label": "Utama"
|
||||
},
|
||||
"text": {
|
||||
"label": "Teks"
|
||||
}
|
||||
},
|
||||
"heading": "Tema"
|
||||
},
|
||||
"typography": {
|
||||
"form": {
|
||||
"font-family": {
|
||||
"label": "Font Family"
|
||||
},
|
||||
"font-size": {
|
||||
"label": "Besar Font"
|
||||
}
|
||||
},
|
||||
"heading": "Tipografi",
|
||||
"widgets": {
|
||||
"body": {
|
||||
"label": "Tubuh"
|
||||
},
|
||||
"headings": {
|
||||
"label": "Judul"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
29
client/public/locales/id/common.json
Normal file
29
client/public/locales/id/common.json
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
"avatar": {
|
||||
"menu": {
|
||||
"greeting": "Halo",
|
||||
"logout": "Keluar"
|
||||
}
|
||||
},
|
||||
"footer": {
|
||||
"credit": "Sebuah passion project dari <1>Amruth Pillai</1>",
|
||||
"license": "Dari komunitas, untuk komunitas."
|
||||
},
|
||||
"markdown": {
|
||||
"help-text": "Bagian ini mendukung format <1>markdown</1>."
|
||||
},
|
||||
"date": {
|
||||
"present": "Sekarang"
|
||||
},
|
||||
"subtitle": "Pembuat resume open source dan gratis.",
|
||||
"title": "Reactive Resume",
|
||||
"toast": {
|
||||
"error": {
|
||||
"upload-file-size": "Harap unggah hanya file di bawah 2 megabytes.",
|
||||
"upload-photo-size": "Harap unggah hanya foto di bawah 2 megabytes, lebih baik jika persegi."
|
||||
},
|
||||
"success": {
|
||||
"resume-link-copied": "Tautan ke resume Anda telah disalin ke papan klip Anda."
|
||||
}
|
||||
}
|
||||
}
|
||||
25
client/public/locales/id/dashboard.json
Normal file
25
client/public/locales/id/dashboard.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"create-resume": {
|
||||
"subtitle": "Mulai dari Awal",
|
||||
"title": "Buat Resume Baru"
|
||||
},
|
||||
"import-external": {
|
||||
"subtitle": "LinkedIn, JSON Resume, Reactive Resume",
|
||||
"title": "Impor dari sumber luar"
|
||||
},
|
||||
"resume": {
|
||||
"menu": {
|
||||
"delete": "Hapus",
|
||||
"duplicate": "Duplikasi",
|
||||
"open": "Buka",
|
||||
"rename": "Ganti Nama",
|
||||
"share-link": "Bagikan link",
|
||||
"tooltips": {
|
||||
"delete": "Anda yakin ingin menghapus resume ini? Ini adalah tindakan yang tidak dapat dibatalkan.",
|
||||
"share-link": "Anda perlu mengubah visibilitas resume Anda ke publik agar terlihat oleh orang lain."
|
||||
}
|
||||
},
|
||||
"timestamp": "Terakhir diubah {{timestamp}} lalu"
|
||||
},
|
||||
"title": "Dasbor"
|
||||
}
|
||||
41
client/public/locales/id/landing.json
Normal file
41
client/public/locales/id/landing.json
Normal file
@ -0,0 +1,41 @@
|
||||
{
|
||||
"actions": {
|
||||
"app": "Buka Aplikasi",
|
||||
"login": "Masuk",
|
||||
"logout": "Keluar",
|
||||
"register": "Registrasi"
|
||||
},
|
||||
"features": {
|
||||
"heading": "Fitur",
|
||||
"list": {
|
||||
"ads": "Tanpa Iklan",
|
||||
"export": "Ekspor resume Anda ke JSON atau format PDF",
|
||||
"free": "Gratis, selamanya",
|
||||
"import": "Impor data dari LinkedIn, JSON Resume",
|
||||
"languages": "Dapat diakses dari berbagai bahasa",
|
||||
"more": "Dan masih banyak lagi fitur menarik lainnya, <1>baca semuanya disini</1>",
|
||||
"tracking": "Tanpa Pelacakan Pengguna"
|
||||
}
|
||||
},
|
||||
"links": {
|
||||
"heading": "Link",
|
||||
"links": {
|
||||
"donate": "Donasi",
|
||||
"github": "Kode Sumber",
|
||||
"privacy": "Kebijakan Pribadi",
|
||||
"service": "Persyaratan Layanan"
|
||||
}
|
||||
},
|
||||
"screenshots": {
|
||||
"heading": "Screenshot"
|
||||
},
|
||||
"testimonials": {
|
||||
"heading": "Testimoni",
|
||||
"body": "Baik atau buruk, saya akan senang mendengar pendapat Anda tentang Reactive Resume dan bagaimana pengalamannya bagi Anda.<br/>Berikut adalah beberapa pesan yang dikirim oleh pengguna di seluruh dunia.",
|
||||
"contact": "Anda dapat menghubungi saya melalui <1>email saya</1> atau melalui formulir kontak di <3>situs web saya</3>."
|
||||
},
|
||||
"summary": {
|
||||
"body": "Reactive Resume adalah pembuat resume gratis dan open source yang dibuat untuk membuat tugas-tugas lebih mudah seperti membuat, memperbarui, dan membagikan resume Anda semudah 1, 2, 3. Dengan aplikasi ini, Anda dapat membuat beberapa resume, membaginya dengan perekrut atau teman melalui tautan unik dan cetak sebagai PDF, semuanya gratis, tanpa iklan, tanpa pelacakan, tanpa kehilangan integritas dan privasi data Anda.",
|
||||
"heading": "Ringkasan"
|
||||
}
|
||||
}
|
||||
136
client/public/locales/id/modals.json
Normal file
136
client/public/locales/id/modals.json
Normal file
@ -0,0 +1,136 @@
|
||||
{
|
||||
"auth": {
|
||||
"forgot-password": {
|
||||
"actions": {
|
||||
"send-email": "Kirim Reset Kata Sandi Email"
|
||||
},
|
||||
"body": "Cukup masukkan alamat email yang terkait dengan akun yang ingin Anda pulihkan.",
|
||||
"form": {
|
||||
"email": {
|
||||
"label": "Alamat Email"
|
||||
}
|
||||
},
|
||||
"heading": "Lupa Kata Sandi?",
|
||||
"help-text": "Jika akun ada, Anda akan menerima email dengan tautan untuk mengatur ulang kata sandi Anda."
|
||||
},
|
||||
"login": {
|
||||
"actions": {
|
||||
"login": "Masuk",
|
||||
"google": "Masuk dengan Google"
|
||||
},
|
||||
"body": "Silakan masukkan nama pengguna dan kata sandi Anda yang terkait dengan akun Anda untuk masuk dan mengakses, mengelola, dan membagikan resume Anda.",
|
||||
"form": {
|
||||
"password": {
|
||||
"label": "kata Sandi"
|
||||
},
|
||||
"username": {
|
||||
"help-text": "Anda juga dapat memasukkan alamat email Anda",
|
||||
"label": "Nama Pengguna"
|
||||
}
|
||||
},
|
||||
"heading": "Masuk ke akun Anda",
|
||||
"recover-text": "Jika Anda lupa sandi, Anda dapat <1>memulihkan akun</1> di sini.",
|
||||
"register-text": "Jika Anda tidak memilikinya, Anda dapat <1>membuat akun</1> di sini."
|
||||
},
|
||||
"register": {
|
||||
"actions": {
|
||||
"register": "Daftar",
|
||||
"google": "Daftar dengan Google"
|
||||
},
|
||||
"body": "Silakan masukkan informasi pribadi Anda untuk membuat akun.",
|
||||
"form": {
|
||||
"confirm-password": {
|
||||
"label": "Konfirmasi Sandi"
|
||||
},
|
||||
"email": {
|
||||
"label": "Alamat Email"
|
||||
},
|
||||
"name": {
|
||||
"label": "Nama Lengkap"
|
||||
},
|
||||
"password": {
|
||||
"label": "Kata Sandi"
|
||||
},
|
||||
"username": {
|
||||
"label": "Nama Panggilan"
|
||||
}
|
||||
},
|
||||
"heading": "Buat akun",
|
||||
"loginText": "Jika Anda sudah memiliki akun, Anda dapat <1>masuk di sini</1>."
|
||||
},
|
||||
"reset-password": {
|
||||
"actions": {
|
||||
"set-password": "Ubah Kata Sandi Baru"
|
||||
},
|
||||
"body": "Masukkan kata sandi baru untuk akun Anda.",
|
||||
"form": {
|
||||
"confirm-password": {
|
||||
"label": "Konfirmasi Sandi"
|
||||
},
|
||||
"password": {
|
||||
"label": "Kata Sandi"
|
||||
}
|
||||
},
|
||||
"heading": "Atur ulang kata sandi"
|
||||
}
|
||||
},
|
||||
"dashboard": {
|
||||
"create-resume": {
|
||||
"actions": {
|
||||
"create-resume": "Buat Resume"
|
||||
},
|
||||
"body": "Mulailah membangun resume Anda dengan memberinya nama. Bisa jadi mengacu pada peran yang Anda lamar, atau hanya cemilan favorit Anda.",
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "Nama"
|
||||
},
|
||||
"public": {
|
||||
"label": "Apakah Dapat Diakses Publik?"
|
||||
},
|
||||
"slug": {
|
||||
"label": "Slug"
|
||||
}
|
||||
},
|
||||
"heading": "Buat resume baru"
|
||||
},
|
||||
"import-external": {
|
||||
"heading": "Impor dari Sumber luar",
|
||||
"json-resume": {
|
||||
"actions": {
|
||||
"upload-json": "Unggah JSON"
|
||||
},
|
||||
"body": "Jika Anda memiliki <1>JSON Resume yang divalidasi</1> yang siap digunakan, Anda dapat menggunakannya untuk mempercepat pengembangan Anda di Reactive Resume. Klik tombol di bawah dan unggah file JSON yang valid untuk memulai.",
|
||||
"heading": "Impor dari JSON Resume"
|
||||
},
|
||||
"linkedin": {
|
||||
"actions": {
|
||||
"upload-archive": "Unggah berkas ZIP"
|
||||
},
|
||||
"body": "Anda dapat menghemat waktu dengan mengekspor data Anda dari LinkedIn dan menggunakannya untuk mengisi kolom secara otomatis di Reactive Resume. Buka bagian <1>Privasi Data</1> di LinkedIn dan minta arsip data Anda. Setelah tersedia, unggah file ZIP di bawah ini.",
|
||||
"heading": "Impor dari LinkedIn"
|
||||
},
|
||||
"reactive-resume": {
|
||||
"actions": {
|
||||
"upload-json": "Unggah JSON",
|
||||
"upload-json-v2": "Unggah JSON dari v2"
|
||||
},
|
||||
"body": "Jika Anda memiliki JSON yang diekspor dengan versi Reactive Resume saat ini, Anda dapat mengimpornya kembali ke sini untuk mendapatkan versi yang dapat diedit lagi.",
|
||||
"heading": "Impor dari Reactive Resume"
|
||||
}
|
||||
},
|
||||
"rename-resume": {
|
||||
"actions": {
|
||||
"rename-resume": "Ubah nama Resume"
|
||||
},
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "Nama"
|
||||
},
|
||||
"slug": {
|
||||
"label": "Slug"
|
||||
}
|
||||
},
|
||||
"heading": "Ubah nama resume Anda"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -9,6 +9,7 @@ import {
|
||||
FaHackerrank,
|
||||
FaInstagram,
|
||||
FaLinkedinIn,
|
||||
FaMedium,
|
||||
FaSkype,
|
||||
FaSoundcloud,
|
||||
FaStackOverflow,
|
||||
@ -30,6 +31,7 @@ const profileIconMap: Record<string, JSX.Element> = {
|
||||
hackerrank: <FaHackerrank />,
|
||||
instagram: <FaInstagram />,
|
||||
linkedin: <FaLinkedinIn />,
|
||||
medium: <FaMedium />,
|
||||
skype: <FaSkype />,
|
||||
soundcloud: <FaSoundcloud />,
|
||||
stackoverflow: <FaStackOverflow />,
|
||||
|
||||
@ -18,9 +18,12 @@ const DateWrapper: React.FC<React.PropsWithChildren<unknown>> = ({ children }) =
|
||||
require('dayjs/locale/el');
|
||||
require('dayjs/locale/en');
|
||||
require('dayjs/locale/es');
|
||||
require('dayjs/locale/fa');
|
||||
require('dayjs/locale/fr');
|
||||
require('dayjs/locale/he');
|
||||
require('dayjs/locale/hi');
|
||||
require('dayjs/locale/hu');
|
||||
require('dayjs/locale/id');
|
||||
require('dayjs/locale/it');
|
||||
require('dayjs/locale/kn');
|
||||
require('dayjs/locale/ml');
|
||||
|
||||
@ -55,6 +55,7 @@ You have complete control over what goes into your resume, how it looks, what co
|
||||
- German (Deutsch)
|
||||
- Greek (Ελληνικά)
|
||||
- Hindi (हिन्दी)
|
||||
- Hungarian (Magyar)
|
||||
- Italian (Italiano)
|
||||
- Kannada (ಕನ್ನಡ)
|
||||
- Malayalam (മലയാളം)
|
||||
|
||||
@ -14,14 +14,14 @@
|
||||
"write-heading-ids": "docusaurus write-heading-ids"
|
||||
},
|
||||
"dependencies": {
|
||||
"@algolia/client-search": "^4.13.0",
|
||||
"@docusaurus/core": "2.0.0-beta.18",
|
||||
"@docusaurus/preset-classic": "2.0.0-beta.18",
|
||||
"@mdx-js/react": "1.6.22",
|
||||
"@algolia/client-search": "^4.13.1",
|
||||
"@docusaurus/core": "2.0.0-beta.21",
|
||||
"@docusaurus/preset-classic": "2.0.0-beta.21",
|
||||
"@mdx-js/react": "2.1.2",
|
||||
"clsx": "^1.1.1",
|
||||
"prism-react-renderer": "^1.3.1",
|
||||
"react": "17.0.2",
|
||||
"react-dom": "17.0.2"
|
||||
"prism-react-renderer": "^1.3.3",
|
||||
"react": ">=16.13.1 <17.0.0 || >=17.0.0 <18.0.0",
|
||||
"react-dom": ">=16.8.4 <17.0.0 || >=17.0.0 <18.0.0"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
@ -36,7 +36,7 @@
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "17.0.2",
|
||||
"typescript": "^4.6.4"
|
||||
"@types/react": ">=16.8.0 <19.0.0",
|
||||
"typescript": "^4.7.4"
|
||||
}
|
||||
}
|
||||
|
||||
49813
package-lock.json
generated
Normal file
49813
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
21
package.json
21
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "reactive-resume",
|
||||
"version": "3.4.4",
|
||||
"version": "3.4.6",
|
||||
"private": true,
|
||||
"workspaces": [
|
||||
"schema",
|
||||
@ -34,22 +34,25 @@
|
||||
"start": "env-cmd --silent concurrently --kill-others \"pnpm run start:*\""
|
||||
},
|
||||
"dependencies": {
|
||||
"concurrently": "^7.1.0",
|
||||
"@aws-sdk/client-s3": "^3.113.0",
|
||||
"@docusaurus/core": "^2.0.0-beta.21",
|
||||
"@docusaurus/preset-classic": "^2.0.0-beta.21",
|
||||
"concurrently": "^7.2.2",
|
||||
"env-cmd": "^10.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@typescript-eslint/eslint-plugin": "^5.21.0",
|
||||
"@typescript-eslint/parser": "^5.21.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.28.0",
|
||||
"@typescript-eslint/parser": "^5.28.0",
|
||||
"cz-conventional-changelog": "^3.3.0",
|
||||
"eslint": "^8.14.0",
|
||||
"eslint": "^8.18.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-simple-import-sort": "^7.0.0",
|
||||
"eslint-plugin-unused-imports": "^2.0.0",
|
||||
"husky": "^7.0.4",
|
||||
"prettier": "^2.6.2",
|
||||
"standard-version": "^9.3.2",
|
||||
"typescript": "^4.6.4"
|
||||
"husky": "^8.0.1",
|
||||
"prettier": "^2.7.1",
|
||||
"standard-version": "^9.5.0",
|
||||
"typescript": "^4.7.4"
|
||||
}
|
||||
}
|
||||
|
||||
6917
pnpm-lock.yaml
generated
6917
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -9,7 +9,7 @@
|
||||
"lint": "eslint --fix --ext .ts ./src"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^8.14.0",
|
||||
"typescript": "^4.6.4"
|
||||
"eslint": "^8.18.0",
|
||||
"typescript": "^4.7.4"
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,6 +43,8 @@ RUN pnpm install -F server --frozen-lockfile --prod
|
||||
|
||||
COPY --from=builder /app/server/dist ./server/dist
|
||||
|
||||
VOLUME /app/server/dist/assets/uploads
|
||||
|
||||
EXPOSE 3100
|
||||
|
||||
ENV PORT 3100
|
||||
|
||||
@ -10,62 +10,63 @@
|
||||
"lint": "eslint --fix --ext .ts ./src"
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.81.0",
|
||||
"@nestjs/axios": "^0.0.7",
|
||||
"@nestjs/common": "^8.4.4",
|
||||
"@nestjs/config": "^2.0.0",
|
||||
"@nestjs/core": "^8.4.4",
|
||||
"@nestjs/jwt": "^8.0.0",
|
||||
"@aws-sdk/client-s3": "^3.113.0",
|
||||
"@nestjs/axios": "^0.0.8",
|
||||
"@nestjs/common": "^8.4.7",
|
||||
"@nestjs/config": "^2.1.0",
|
||||
"@nestjs/core": "^8.4.7",
|
||||
"@nestjs/jwt": "^8.0.1",
|
||||
"@nestjs/mapped-types": "^1.0.1",
|
||||
"@nestjs/passport": "^8.2.1",
|
||||
"@nestjs/platform-express": "^8.4.4",
|
||||
"@nestjs/schedule": "^1.1.0",
|
||||
"@nestjs/passport": "^8.2.2",
|
||||
"@nestjs/platform-express": "^8.4.7",
|
||||
"@nestjs/schedule": "^2.0.1",
|
||||
"@nestjs/serve-static": "^2.2.2",
|
||||
"@nestjs/terminus": "^8.0.6",
|
||||
"@nestjs/typeorm": "^8.0.3",
|
||||
"@sendgrid/mail": "^7.6.2",
|
||||
"@types/passport": "^1.0.7",
|
||||
"@nestjs/terminus": "^8.0.8",
|
||||
"@nestjs/typeorm": "^8.1.4",
|
||||
"@sendgrid/mail": "^7.7.0",
|
||||
"@types/passport": "^1.0.9",
|
||||
"bcrypt": "^5.0.1",
|
||||
"cache-manager": "^3.6.1",
|
||||
"cache-manager": "^4.0.1",
|
||||
"class-transformer": "^0.5.1",
|
||||
"class-validator": "^0.13.2",
|
||||
"cookie-parser": "^1.4.6",
|
||||
"csvtojson": "^2.0.10",
|
||||
"dayjs": "^1.11.1",
|
||||
"dayjs": "^1.11.3",
|
||||
"google-auth-library": "^8.0.2",
|
||||
"joi": "^17.6.0",
|
||||
"lodash": "^4.17.21",
|
||||
"multer": "^1.4.4",
|
||||
"nanoid": "^3.3.3",
|
||||
"nanoid": "^3.3.4",
|
||||
"node-stream-zip": "^1.15.0",
|
||||
"passport": "^0.5.2",
|
||||
"passport": "^0.6.0",
|
||||
"passport-jwt": "^4.0.0",
|
||||
"passport-local": "^1.0.0",
|
||||
"pdf-lib": "^1.17.1",
|
||||
"pg": "^8.7.3",
|
||||
"playwright-chromium": "^1.21.1",
|
||||
"playwright-chromium": "^1.22.2",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"rimraf": "^3.0.2",
|
||||
"rxjs": "^7.5.5",
|
||||
"typeorm": "0.2.45",
|
||||
"typeorm": "0.3.6",
|
||||
"uuid": "^8.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nestjs/cli": "^8.2.5",
|
||||
"@nestjs/schematics": "^8.0.10",
|
||||
"@nestjs/cli": "^8.2.6",
|
||||
"@nestjs/schematics": "^8.0.11",
|
||||
"@reactive-resume/schema": "workspace:*",
|
||||
"@types/bcrypt": "^5.0.0",
|
||||
"@types/cookie-parser": "^1.4.3",
|
||||
"@types/express": "^4.17.13",
|
||||
"@types/lodash": "^4.14.182",
|
||||
"@types/multer": "^1.4.7",
|
||||
"@types/node": "^17.0.31",
|
||||
"eslint": "^8.14.0",
|
||||
"prettier": "^2.6.2",
|
||||
"@types/node": "^18.0.0",
|
||||
"eslint": "^8.18.0",
|
||||
"prettier": "^2.7.1",
|
||||
"source-map-support": "^0.5.21",
|
||||
"ts-loader": "^9.3.0",
|
||||
"ts-node": "^10.7.0",
|
||||
"tsconfig-paths": "^3.14.1",
|
||||
"typescript": "^4.6.4",
|
||||
"webpack": "^5.72.0"
|
||||
"ts-node": "^10.8.1",
|
||||
"tsconfig-paths": "^4.0.0",
|
||||
"typescript": "^4.7.4",
|
||||
"webpack": "^5.73.0"
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,4 +7,5 @@ export default registerAs('storage', () => ({
|
||||
urlPrefix: process.env.STORAGE_URL_PREFIX,
|
||||
accessKey: process.env.STORAGE_ACCESS_KEY,
|
||||
secretKey: process.env.STORAGE_SECRET_KEY,
|
||||
s3Enabled: process.env.STORAGE_S3_ENABLED,
|
||||
}));
|
||||
|
||||
@ -35,8 +35,6 @@ export class ResumeController {
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Get()
|
||||
async findAllByUser(@User('id') userId: number) {
|
||||
console.log('findAllByUser', userId);
|
||||
|
||||
return this.resumeService.findAllByUser(userId);
|
||||
}
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Resume as ResumeSchema } from '@reactive-resume/schema';
|
||||
import fs from 'fs';
|
||||
import { pick, sample, set } from 'lodash';
|
||||
import { nanoid } from 'nanoid';
|
||||
import { extname } from 'path';
|
||||
@ -23,20 +24,24 @@ export const SHORT_ID_LENGTH = 8;
|
||||
@Injectable()
|
||||
export class ResumeService {
|
||||
private s3Client: S3Client;
|
||||
private s3Enabled: boolean;
|
||||
|
||||
constructor(
|
||||
@InjectRepository(Resume) private resumeRepository: Repository<Resume>,
|
||||
private configService: ConfigService,
|
||||
private usersService: UsersService
|
||||
) {
|
||||
this.s3Client = new S3({
|
||||
endpoint: configService.get<string>('storage.endpoint'),
|
||||
region: configService.get<string>('storage.region'),
|
||||
credentials: {
|
||||
accessKeyId: configService.get<string>('storage.accessKey'),
|
||||
secretAccessKey: configService.get<string>('storage.secretKey'),
|
||||
},
|
||||
});
|
||||
this.s3Enabled = configService.get<string>('storage.s3Enabled') !== 'false';
|
||||
if (this.s3Enabled) {
|
||||
this.s3Client = new S3({
|
||||
endpoint: configService.get<string>('storage.endpoint'),
|
||||
region: configService.get<string>('storage.region'),
|
||||
credentials: {
|
||||
accessKeyId: configService.get<string>('storage.accessKey'),
|
||||
secretAccessKey: configService.get<string>('storage.secretKey'),
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async create(createResumeDto: CreateResumeDto, userId: number) {
|
||||
@ -103,11 +108,11 @@ export class ResumeService {
|
||||
}
|
||||
|
||||
findAllByUser(userId: number) {
|
||||
return this.resumeRepository.find({ user: { id: userId } });
|
||||
return this.resumeRepository.find({ where: { user: { id: userId } } });
|
||||
}
|
||||
|
||||
async findOne(id: number, userId?: number) {
|
||||
const resume = await this.resumeRepository.findOne(id);
|
||||
const resume = await this.resumeRepository.findOne({ where: { id } });
|
||||
|
||||
if (!resume) {
|
||||
throw new HttpException('The resume you are looking does not exist, or maybe never did?', HttpStatus.NOT_FOUND);
|
||||
@ -124,7 +129,7 @@ export class ResumeService {
|
||||
}
|
||||
|
||||
async findOneByShortId(shortId: string, userId?: number, secretKey?: string) {
|
||||
const resume = await this.resumeRepository.findOne({ shortId });
|
||||
const resume = await this.resumeRepository.findOne({ where: { shortId } });
|
||||
|
||||
if (!resume) {
|
||||
throw new HttpException('The resume you are looking does not exist, or maybe never did?', HttpStatus.NOT_FOUND);
|
||||
@ -142,7 +147,7 @@ export class ResumeService {
|
||||
}
|
||||
|
||||
async findOneByIdentifier(username: string, slug: string, userId?: number, secretKey?: string) {
|
||||
const resume = await this.resumeRepository.findOne({ user: { username }, slug });
|
||||
const resume = await this.resumeRepository.findOne({ where: { user: { username }, slug } });
|
||||
|
||||
if (!resume) {
|
||||
throw new HttpException('The resume you are looking does not exist, or maybe never did?', HttpStatus.NOT_FOUND);
|
||||
@ -230,40 +235,62 @@ export class ResumeService {
|
||||
async uploadPhoto(id: number, userId: number, file: Express.Multer.File) {
|
||||
const resume = await this.findOne(id, userId);
|
||||
|
||||
const urlPrefix = this.configService.get<string>('storage.urlPrefix');
|
||||
const filename = new Date().getTime() + extname(file.originalname);
|
||||
const key = `uploads/${userId}/${id}/${filename}`;
|
||||
|
||||
await this.s3Client.send(
|
||||
new PutObjectCommand({
|
||||
Bucket: this.configService.get<string>('storage.bucket'),
|
||||
Key: key,
|
||||
Body: file.buffer,
|
||||
ACL: 'public-read',
|
||||
})
|
||||
);
|
||||
|
||||
const publicUrl = urlPrefix + key;
|
||||
|
||||
const updatedResume = set(resume, 'basics.photo.url', publicUrl);
|
||||
let updatedResume = null;
|
||||
if (this.s3Enabled) {
|
||||
const urlPrefix = this.configService.get<string>('storage.urlPrefix');
|
||||
const key = `uploads/${userId}/${id}/${filename}`;
|
||||
const publicUrl = urlPrefix + key;
|
||||
await this.s3Client.send(
|
||||
new PutObjectCommand({
|
||||
Bucket: this.configService.get<string>('storage.bucket'),
|
||||
Key: key,
|
||||
Body: file.buffer,
|
||||
ACL: 'public-read',
|
||||
})
|
||||
);
|
||||
updatedResume = set(resume, 'basics.photo.url', publicUrl);
|
||||
} else {
|
||||
const path = `${__dirname}/../assets/uploads/${userId}/${id}/`;
|
||||
fs.mkdir(path, { recursive: true }, (err) => {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
}
|
||||
fs.writeFile(path + filename, file.buffer, (err) => {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
updatedResume = set(resume, 'basics.photo.url', `/api/assets/uploads/${userId}/${id}/` + filename);
|
||||
}
|
||||
|
||||
return this.resumeRepository.save<Resume>(updatedResume);
|
||||
}
|
||||
|
||||
async deletePhoto(id: number, userId: number) {
|
||||
const resume = await this.findOne(id, userId);
|
||||
|
||||
const urlPrefix = this.configService.get<string>('storage.urlPrefix');
|
||||
const publicUrl = resume.basics.photo.url;
|
||||
const key = publicUrl.replace(urlPrefix, '');
|
||||
|
||||
await this.s3Client.send(
|
||||
new DeleteObjectCommand({
|
||||
Bucket: this.configService.get<string>('storage.bucket'),
|
||||
Key: key,
|
||||
})
|
||||
);
|
||||
if (this.s3Enabled) {
|
||||
const urlPrefix = this.configService.get<string>('storage.urlPrefix');
|
||||
const key = publicUrl.replace(urlPrefix, '');
|
||||
|
||||
await this.s3Client.send(
|
||||
new DeleteObjectCommand({
|
||||
Bucket: this.configService.get<string>('storage.bucket'),
|
||||
Key: key,
|
||||
})
|
||||
);
|
||||
} else {
|
||||
const filePath = __dirname + '/../' + resume.basics.photo.url.replace('/api/', '');
|
||||
if (fs.existsSync(filePath)) {
|
||||
fs.unlink(filePath, (err) => {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
const updatedResume = set(resume, 'basics.photo.url', '');
|
||||
|
||||
return this.resumeRepository.save<Resume>(updatedResume);
|
||||
|
||||
@ -23,7 +23,7 @@ export class UsersService {
|
||||
) {}
|
||||
|
||||
async findById(id: number): Promise<User> {
|
||||
const user = await this.userRepository.findOne({ id });
|
||||
const user = await this.userRepository.findOne({ where: { id } });
|
||||
|
||||
if (user) {
|
||||
return user;
|
||||
@ -33,7 +33,7 @@ export class UsersService {
|
||||
}
|
||||
|
||||
async findByEmail(email: string): Promise<User> {
|
||||
const user = await this.userRepository.findOne({ email });
|
||||
const user = await this.userRepository.findOne({ where: { email } });
|
||||
|
||||
if (user) {
|
||||
return user;
|
||||
@ -55,7 +55,7 @@ export class UsersService {
|
||||
}
|
||||
|
||||
async findByResetToken(resetToken: string): Promise<User> {
|
||||
const user = await this.userRepository.findOne({ resetToken });
|
||||
const user = await this.userRepository.findOne({ where: { resetToken } });
|
||||
|
||||
if (user) {
|
||||
return user;
|
||||
|
||||
Reference in New Issue
Block a user