mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2025-11-10 04:22:27 +10:00
Compare commits
209 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f9ef4d0a64 | |||
| c4b4e6013f | |||
| 24bbc46c32 | |||
| 85bc9ef124 | |||
| 33755a8573 | |||
| ab45321889 | |||
| 940b310f64 | |||
| 8026241b6c | |||
| 89b35392bd | |||
| 62eb239ec4 | |||
| 7fdf8c1f0c | |||
| 538697238a | |||
| 7bc4a998fe | |||
| e33df485ab | |||
| 36ae54fe17 | |||
| 50958fd6df | |||
| e9e595f0d0 | |||
| 43ddfba777 | |||
| 78a32961d7 | |||
| 9b1f3eda05 | |||
| 1154621e5c | |||
| e7aeee77a7 | |||
| fab3988a36 | |||
| 354cad88d3 | |||
| 876f930f30 | |||
| 5b3ea46f0f | |||
| 37a2563c11 | |||
| cb977a146b | |||
| 72b2551b6d | |||
| c94633e616 | |||
| 7fee2d670f | |||
| 837b06eb38 | |||
| 2b8860b21c | |||
| 3a7b98d30e | |||
| 284a39aa77 | |||
| c14c9955dd | |||
| 4de787157a | |||
| 6bc6425a01 | |||
| 6051305908 | |||
| 5e13253454 | |||
| c1fd2b40e3 | |||
| fccf7a7b56 | |||
| 5098b094db | |||
| 7c1eb74aca | |||
| 7f9ede8ff0 | |||
| 172b23e429 | |||
| f287ca6183 | |||
| 7548e36aaf | |||
| 2f754616b4 | |||
| dc51f6f9b2 | |||
| 0cdac1d657 | |||
| c3cfe8ae7b | |||
| 08435c173b | |||
| 62cc2d6eac | |||
| 5a6f6e2b6c | |||
| 2dfa8c04a1 | |||
| 63e3f94d2d | |||
| 7f45a8cb7f | |||
| 4377ebb811 | |||
| ed3af6975b | |||
| 7904905a8b | |||
| bd2e6d2bf2 | |||
| ae4e9e688e | |||
| 78c45b7019 | |||
| 9a2fbbec4e | |||
| 93d751d9be | |||
| 9926ed2262 | |||
| 62220d20e7 | |||
| 2f6108cd29 | |||
| 7aeed37869 | |||
| ed99659b7b | |||
| 5e33d00910 | |||
| c00d0341e6 | |||
| 511ae036c2 | |||
| 1642ec9ba2 | |||
| 1115bc2b69 | |||
| 27e5c7811c | |||
| 3b739f0bb7 | |||
| d937ba2056 | |||
| de110d7de1 | |||
| b03229b5e0 | |||
| 280fc73c7b | |||
| 677ad2a115 | |||
| f394b26d18 | |||
| aab4e2e941 | |||
| f0f552a635 | |||
| 136e143e12 | |||
| 857e4b8670 | |||
| ff03d41d97 | |||
| 2bad37aaf3 | |||
| 3a40fbf78b | |||
| 49c638fb18 | |||
| 50e8d60773 | |||
| bf157a8d1a | |||
| c4f5955fcd | |||
| 86d33b0f21 | |||
| 56bca30639 | |||
| eed3b76959 | |||
| 615eb3ad5d | |||
| b505199319 | |||
| 91e55e642c | |||
| f549d8749a | |||
| f31123659e | |||
| 93633c9415 | |||
| 19b9fa4857 | |||
| a5c84214f9 | |||
| 65bb8b5ceb | |||
| 06a11a1f2a | |||
| 53eedc8500 | |||
| 4b2d9d7026 | |||
| 045145ed67 | |||
| ec27e5e6ab | |||
| 2faa15db5a | |||
| 2c2893d5fc | |||
| 19c7ebe8a4 | |||
| c24847ac0b | |||
| 7137694832 | |||
| 049de38da2 | |||
| 17019e446b | |||
| d73ee7b7f8 | |||
| 2c95dc2ac8 | |||
| e148dd3e82 | |||
| 0aa2d61c55 | |||
| 0b2c1ffd26 | |||
| a531e8cd89 | |||
| 152e386141 | |||
| 87189cd045 | |||
| 114b04a740 | |||
| 383cde53df | |||
| 9bf98d3c49 | |||
| e62f0a3f5e | |||
| 10fb7b143a | |||
| 67ba58e798 | |||
| 179cf99f83 | |||
| 81a51d487b | |||
| b41b50565a | |||
| 8cd073eb62 | |||
| f4f8502703 | |||
| 0d079d7b24 | |||
| 167f7c902f | |||
| 7c630df927 | |||
| b391c561e5 | |||
| 4dbe015fbf | |||
| bae35b2614 | |||
| 8b7719a198 | |||
| 39cf238de3 | |||
| 98855ae230 | |||
| ab92cbf21e | |||
| 388ab4e29a | |||
| bb18c59018 | |||
| 217ab6ab93 | |||
| 12690b33d7 | |||
| bff5173701 | |||
| 821813d90d | |||
| b1d3c4da5b | |||
| 39f962b440 | |||
| b1cfd4b7c8 | |||
| c98d4a6004 | |||
| a5ec1f8609 | |||
| b2c897660d | |||
| c1a7fe7354 | |||
| b628c4a21b | |||
| 5fb4935146 | |||
| ae5280435d | |||
| 6451609d8f | |||
| edfe79f580 | |||
| 5d7318d46d | |||
| 77428c1661 | |||
| a2e075df39 | |||
| 63af1d2b69 | |||
| 99c5016762 | |||
| 44ff6caf27 | |||
| 7d2981f7ce | |||
| fcc5dd4bad | |||
| a9fb995d39 | |||
| 31a85bfaa6 | |||
| 51151a601e | |||
| 9931b22313 | |||
| fdf6b76c21 | |||
| b4696301ed | |||
| 294d7b5dab | |||
| 0430920f56 | |||
| 5444b4f5ab | |||
| d649b7fc08 | |||
| 20b39c0b35 | |||
| 8b87b054ee | |||
| 5eb68e9e21 | |||
| ec2606d625 | |||
| 9055010f61 | |||
| 9763b5c270 | |||
| 75c3bfe9e5 | |||
| 7f39247655 | |||
| d6f11e7807 | |||
| 361a1e65d0 | |||
| 6fddbe0c59 | |||
| 3412711f27 | |||
| a4bfc17431 | |||
| 7c698ef9d2 | |||
| e929faf9b0 | |||
| e3ff18b6dd | |||
| 2734493ca4 | |||
| f0015143c6 | |||
| 8d97b195a0 | |||
| f30692196a | |||
| 242278edd1 | |||
| 162759c716 | |||
| f0c6bd16f5 | |||
| fac8a9d4ff | |||
| fc0b69796f |
@ -1,3 +1,6 @@
|
||||
# Android App
|
||||
/app
|
||||
|
||||
# Build Artifacts
|
||||
dist
|
||||
.next
|
||||
@ -22,6 +25,3 @@ node_modules
|
||||
Dockerfile
|
||||
.dockerignore
|
||||
docker-compose.yml
|
||||
|
||||
# Android App
|
||||
/app
|
||||
|
||||
@ -4,8 +4,8 @@ TURBO_TOKEN=
|
||||
|
||||
# Server + Client
|
||||
TZ=UTC
|
||||
PUBLIC_URL=http://client:3000
|
||||
PUBLIC_SERVER_URL=http://server:3100
|
||||
PUBLIC_URL=http://localhost:3000
|
||||
PUBLIC_SERVER_URL=http://localhost:3100
|
||||
PUBLIC_GOOGLE_CLIENT_ID=
|
||||
|
||||
# Server + Database
|
||||
@ -34,6 +34,7 @@ STORAGE_ENDPOINT=
|
||||
STORAGE_URL_PREFIX=
|
||||
STORAGE_ACCESS_KEY=
|
||||
STORAGE_SECRET_KEY=
|
||||
PDF_DELETION_TIME=
|
||||
|
||||
# Flags (Client)
|
||||
PUBLIC_FLAG_DISABLE_SIGNUPS=false
|
||||
@ -2,23 +2,11 @@
|
||||
"ignorePatterns": ["/app"],
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"extends": ["plugin:@typescript-eslint/recommended"],
|
||||
"plugins": ["@typescript-eslint/eslint-plugin", "simple-import-sort", "unused-imports"],
|
||||
"plugins": ["@typescript-eslint/eslint-plugin", "simple-import-sort"],
|
||||
"rules": {
|
||||
// ESLint
|
||||
"no-unused-vars": "off",
|
||||
|
||||
// Unused Imports
|
||||
"unused-imports/no-unused-imports": "error",
|
||||
"unused-imports/no-unused-vars": [
|
||||
"warn",
|
||||
{
|
||||
"vars": "all",
|
||||
"args": "none",
|
||||
"varsIgnorePattern": "^_",
|
||||
"argsIgnorePattern": "^_"
|
||||
}
|
||||
],
|
||||
|
||||
// Simple Import Sort
|
||||
"simple-import-sort/imports": "error",
|
||||
"simple-import-sort/exports": "error",
|
||||
|
||||
1
.github/FUNDING.yml
vendored
1
.github/FUNDING.yml
vendored
@ -1 +1,2 @@
|
||||
github: AmruthPillai
|
||||
custom: https://paypal.me/RajaRajanA
|
||||
|
||||
2
.github/workflows/digitalocean-deploy.yml
vendored
2
.github/workflows/digitalocean-deploy.yml
vendored
@ -13,7 +13,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Install DigitalOcean CLI
|
||||
uses: digitalocean/action-doctl@v2.1.1
|
||||
uses: digitalocean/action-doctl@v2.2.0
|
||||
with:
|
||||
token: ${{ secrets.DIGITALOCEAN_TOKEN }}
|
||||
|
||||
|
||||
36
.github/workflows/docker-build-push.yml
vendored
36
.github/workflows/docker-build-push.yml
vendored
@ -15,38 +15,38 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@v3.0.2
|
||||
uses: actions/checkout@v3.1.0
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- id: version
|
||||
name: Get Version
|
||||
run: echo ::set-output name=tag::${GITHUB_REF#refs/*/}
|
||||
run: echo "version=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2.0.0
|
||||
uses: docker/setup-qemu-action@v2.1.0
|
||||
|
||||
- id: buildx
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2.0.0
|
||||
uses: docker/setup-buildx-action@v2.2.1
|
||||
with:
|
||||
install: true
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2.0.0
|
||||
uses: docker/login-action@v2.1.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v2.0.0
|
||||
uses: docker/login-action@v2.1.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: $GITHUB_REPOSITORY_OWNER
|
||||
password: ${{ secrets.GH_TOKEN }}
|
||||
|
||||
- name: Build and Push Client Image
|
||||
uses: docker/build-push-action@v3.1.1
|
||||
uses: docker/build-push-action@v3.2.0
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
@ -54,9 +54,9 @@ jobs:
|
||||
platforms: linux/amd64,linux/arm64
|
||||
tags: |
|
||||
amruthpillai/reactive-resume:client-latest
|
||||
amruthpillai/reactive-resume:client-${{ steps.version.outputs.tag }}
|
||||
amruthpillai/reactive-resume:client-${{ env.version }}
|
||||
ghcr.io/amruthpillai/reactive-resume:client-latest
|
||||
ghcr.io/amruthpillai/reactive-resume:client-${{ steps.version.outputs.tag }}
|
||||
ghcr.io/amruthpillai/reactive-resume:client-${{ env.version }}
|
||||
|
||||
server:
|
||||
name: Server
|
||||
@ -68,38 +68,38 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@v3.0.2
|
||||
uses: actions/checkout@v3.1.0
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- id: version
|
||||
name: Get Version
|
||||
run: echo ::set-output name=tag::${GITHUB_REF#refs/*/}
|
||||
run: echo "version=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2.0.0
|
||||
uses: docker/setup-qemu-action@v2.1.0
|
||||
|
||||
- id: buildx
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2.0.0
|
||||
uses: docker/setup-buildx-action@v2.2.1
|
||||
with:
|
||||
install: true
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2.0.0
|
||||
uses: docker/login-action@v2.1.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v2.0.0
|
||||
uses: docker/login-action@v2.1.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: $GITHUB_REPOSITORY_OWNER
|
||||
password: ${{ secrets.GH_TOKEN }}
|
||||
|
||||
- name: Build and Push Server Image
|
||||
uses: docker/build-push-action@v3.1.1
|
||||
uses: docker/build-push-action@v3.2.0
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
@ -107,6 +107,6 @@ jobs:
|
||||
platforms: linux/amd64,linux/arm64
|
||||
tags: |
|
||||
amruthpillai/reactive-resume:server-latest
|
||||
amruthpillai/reactive-resume:server-${{ steps.version.outputs.tag }}
|
||||
amruthpillai/reactive-resume:server-${{ env.version }}
|
||||
ghcr.io/amruthpillai/reactive-resume:server-latest
|
||||
ghcr.io/amruthpillai/reactive-resume:server-${{ steps.version.outputs.tag }}
|
||||
ghcr.io/amruthpillai/reactive-resume:server-${{ env.version }}
|
||||
|
||||
84
.github/workflows/docker-build.yml
vendored
84
.github/workflows/docker-build.yml
vendored
@ -1,84 +0,0 @@
|
||||
name: Build Docker Image
|
||||
|
||||
on: pull_request
|
||||
|
||||
jobs:
|
||||
client:
|
||||
name: Client
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
env:
|
||||
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@v3.0.2
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2.0.0
|
||||
|
||||
- id: buildx
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2.0.0
|
||||
with:
|
||||
install: true
|
||||
|
||||
- id: variables
|
||||
name: Get Short SHA
|
||||
run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
|
||||
|
||||
- name: Build Client Image
|
||||
uses: docker/build-push-action@v3.1.1
|
||||
with:
|
||||
context: .
|
||||
push: false
|
||||
file: client/Dockerfile
|
||||
platforms: linux/amd64,linux/arm64
|
||||
tags: |
|
||||
amruthpillai/reactive-resume:client-latest
|
||||
amruthpillai/reactive-resume:client-${{ steps.variables.outputs.sha_short }}
|
||||
ghcr.io/amruthpillai/reactive-resume:client-latest
|
||||
ghcr.io/amruthpillai/reactive-resume:client-${{ steps.variables.outputs.sha_short }}
|
||||
|
||||
server:
|
||||
name: Server
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
env:
|
||||
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@v3.0.2
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2.0.0
|
||||
|
||||
- id: buildx
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2.0.0
|
||||
with:
|
||||
install: true
|
||||
|
||||
- id: variables
|
||||
name: Get Short SHA
|
||||
run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
|
||||
|
||||
- name: Build Server Image
|
||||
uses: docker/build-push-action@v3.1.1
|
||||
with:
|
||||
context: .
|
||||
push: false
|
||||
file: server/Dockerfile
|
||||
platforms: linux/amd64,linux/arm64
|
||||
tags: |
|
||||
amruthpillai/reactive-resume:server-latest
|
||||
amruthpillai/reactive-resume:server-${{ steps.variables.outputs.sha_short }}
|
||||
ghcr.io/amruthpillai/reactive-resume:server-latest
|
||||
ghcr.io/amruthpillai/reactive-resume:server-${{ steps.variables.outputs.sha_short }}
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@ -10,4 +10,7 @@ node_modules
|
||||
.DS_Store
|
||||
|
||||
# Turbo
|
||||
.turbo
|
||||
.turbo
|
||||
|
||||
# Intellij
|
||||
.idea
|
||||
|
||||
21
README.md
21
README.md
@ -1,4 +1,4 @@
|
||||
<img src="https://github.com/AmruthPillai/Reactive-Resume/blob/main/docs/static/logo.svg" alt="Reactive Resume" width="256px" height="256px" />
|
||||
<img src="https://rxresu.me/images/logos/logo.png" alt="Reactive Resume" width="256px" height="256px" />
|
||||
|
||||
# Reactive Resume
|
||||
|
||||
@ -27,7 +27,8 @@ You have complete control over what goes into your resume, how it looks, what co
|
||||
- [Contributing](#contributing)
|
||||
- [Report Bugs and Feature Requests](#report-bugs-and-feature-requests)
|
||||
- [Donations](#donations)
|
||||
- [💸 PayPal](#-paypal)
|
||||
- [GitHub Sponsor](#github-sponsor)
|
||||
- [PayPal](#paypal)
|
||||
- [Infrastructure](#infrastructure)
|
||||
- [Contributors Wall](#contributors-wall)
|
||||
- [License](#license)
|
||||
@ -54,9 +55,11 @@ You have complete control over what goes into your resume, how it looks, what co
|
||||
|
||||
## Languages
|
||||
|
||||
- Amharic (አማርኛ)
|
||||
- Arabic (اَلْعَرَبِيَّةُ)
|
||||
- Bengali (বাংলা)
|
||||
- Bulgarian (български)
|
||||
- Catalan (Valencian)
|
||||
- Chinese (中文)
|
||||
- Czech (čeština)
|
||||
- Danish (Dansk)
|
||||
@ -71,17 +74,26 @@ You have complete control over what goes into your resume, how it looks, what co
|
||||
- Hungarian (Magyar)
|
||||
- Indonesian (Bahasa Indonesia)
|
||||
- Italian (Italiano)
|
||||
- Japanese (日本語)
|
||||
- Kannada (ಕನ್ನಡ)
|
||||
- Khmer (ភាសាខ្មែរ)
|
||||
- Korean (한국어)
|
||||
- Malayalam (മലയാളം)
|
||||
- Marathi (मराठी)
|
||||
- Nepali (नेपाली)
|
||||
- Norwegian (Norsk)
|
||||
- Odia (ଓଡ଼ିଆ)
|
||||
- Persian (Farsi)
|
||||
- Persian (فارسی)
|
||||
- Polish (Polski)
|
||||
- Portuguese (Português)
|
||||
- Romanian (limba română)
|
||||
- Russian (русский)
|
||||
- Serbian (српски језик)
|
||||
- Spanish (Español)
|
||||
- Swedish (Svenska)
|
||||
- Tamil (தமிழ்)
|
||||
- Turkish (Türkçe)
|
||||
- Ukranian (Українська мова)
|
||||
- Vietnamese (Tiếng Việt)
|
||||
|
||||
Help by [translating Reactive Resume](https://translate.rxresu.me) to your language!
|
||||
@ -114,7 +126,8 @@ Use the [GitHub Issues](https://github.com/AmruthPillai/Reactive-Resume/issues/n
|
||||
|
||||
Reactive Resume would be nothing without the folks who supported me and kept the project alive in the beginning, and your continued support is what keeps me going. If you found Reactive Resume to be useful, helpful or just insightful and appreciate the effort I took to make the project, please consider donating as little or as much as you can.
|
||||
|
||||
### [💸 PayPal](https://paypal.me/RajaRajanA)
|
||||
### [GitHub Sponsor](https://github.com/sponsors/AmruthPillai)
|
||||
### [PayPal](https://paypal.me/RajaRajanA)
|
||||
|
||||
## Infrastructure
|
||||
|
||||
|
||||
@ -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.7.10' apply false
|
||||
id 'org.jetbrains.kotlin.android' version '1.7.21' apply false
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
{
|
||||
"extends": ["../.eslintrc.json", "next/core-web-vitals", "plugin:tailwindcss/recommended"],
|
||||
"plugins": ["unused-imports"],
|
||||
"ignorePatterns": [".next", "__ENV.js"],
|
||||
"settings": {
|
||||
"next": {
|
||||
@ -14,6 +15,18 @@
|
||||
// React Hooks
|
||||
"react-hooks/exhaustive-deps": "off",
|
||||
|
||||
// Unused Imports
|
||||
"unused-imports/no-unused-imports": "error",
|
||||
"unused-imports/no-unused-vars": [
|
||||
"warn",
|
||||
{
|
||||
"vars": "all",
|
||||
"args": "none",
|
||||
"varsIgnorePattern": "^_",
|
||||
"argsIgnorePattern": "^_"
|
||||
}
|
||||
],
|
||||
|
||||
// Tailwind CSS
|
||||
"tailwindcss/no-custom-classname": ["warn", { "whitelist": ["preview-mode", "printer-mode", "markdown"] }]
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ FROM node:lts-alpine AS base
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN apk add --no-cache g++ git curl make python3 \
|
||||
RUN apk add --no-cache g++ git curl make python3 libc6-compat \
|
||||
&& curl -f https://get.pnpm.io/v6.16.js | node - add --global pnpm
|
||||
|
||||
FROM base as dependencies
|
||||
@ -46,6 +46,6 @@ EXPOSE 3000
|
||||
ENV PORT 3000
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=20s --retries=3 --start-period=15s \
|
||||
CMD curl -fSs 127.0.0.1:3000 || exit 1
|
||||
CMD curl -fSs localhost:3000 || exit 1
|
||||
|
||||
CMD [ "pnpm", "run", "start", "--filter", "client" ]
|
||||
@ -13,6 +13,7 @@ import {
|
||||
} from '@mui/icons-material';
|
||||
import { ButtonBase, Divider, Tooltip, useMediaQuery, useTheme } from '@mui/material';
|
||||
import clsx from 'clsx';
|
||||
import dayjs from 'dayjs';
|
||||
import { get } from 'lodash';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import toast from 'react-hot-toast';
|
||||
@ -67,10 +68,11 @@ const ArtboardController: React.FC<ReactZoomPanPinchRef> = ({ zoomIn, zoomOut, c
|
||||
|
||||
const slug = get(resume, 'slug');
|
||||
const username = get(resume, 'user.username');
|
||||
const updatedAt = get(resume, 'updatedAt');
|
||||
|
||||
const url = await mutateAsync({ username, slug });
|
||||
const url = await mutateAsync({ username, slug, lastUpdated: dayjs(updatedAt).unix().toString() });
|
||||
|
||||
download(`/api${url}`);
|
||||
download(url);
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
@apply h-full w-full #{!important};
|
||||
@apply h-full w-full overflow-visible #{!important};
|
||||
}
|
||||
|
||||
.artboard {
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
}
|
||||
|
||||
&.break::after {
|
||||
content: 'A4 Page Break';
|
||||
content: 'Page Break';
|
||||
top: calc(297mm - 19px);
|
||||
|
||||
@apply absolute w-full border-b border-dashed border-neutral-800/75;
|
||||
@ -28,9 +28,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
padding-left: 1.5em;
|
||||
text-indent: -1.5em;
|
||||
&.format-letter {
|
||||
width: 216mm;
|
||||
min-height: 279mm;
|
||||
|
||||
&.break::after {
|
||||
top: calc(279mm - 19px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { css } from '@emotion/css';
|
||||
import { CustomCSS, Theme, Typography } from '@reactive-resume/schema';
|
||||
import { CustomCSS, PageConfig, ThemeConfig, Typography } from '@reactive-resume/schema';
|
||||
import clsx from 'clsx';
|
||||
import get from 'lodash/get';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
@ -23,22 +23,24 @@ const Page: React.FC<Props> = ({ page, showPageNumbers = false }) => {
|
||||
const resume = useAppSelector((state) => state.resume.present);
|
||||
const breakLine: boolean = useAppSelector((state) => state.build.page.breakLine);
|
||||
|
||||
const theme: Theme = get(resume, 'metadata.theme');
|
||||
const theme: ThemeConfig = get(resume, 'metadata.theme');
|
||||
const customCSS: CustomCSS = get(resume, 'metadata.css');
|
||||
const template: string = get(resume, 'metadata.template');
|
||||
const typography: Typography = get(resume, 'metadata.typography');
|
||||
const pageConfig: PageConfig = get(resume, 'metadata.page', {} as PageConfig);
|
||||
|
||||
const themeCSS = useMemo(() => !isEmpty(theme) && generateThemeStyles(theme), [theme]);
|
||||
const typographyCSS = useMemo(() => !isEmpty(typography) && generateTypographyStyles(typography), [typography]);
|
||||
const TemplatePage: React.FC<PageProps> | null = useMemo(() => templateMap[template].component, [template]);
|
||||
|
||||
return (
|
||||
<div data-page={page + 1} className={styles.container}>
|
||||
<div className={styles.container} data-page={page + 1} data-format={pageConfig?.format || 'A4'}>
|
||||
<div
|
||||
className={clsx({
|
||||
reset: true,
|
||||
[styles.page]: true,
|
||||
[styles.break]: breakLine,
|
||||
[styles['format-letter']]: pageConfig?.format === 'Letter',
|
||||
[css(themeCSS)]: true,
|
||||
[css(typographyCSS)]: true,
|
||||
[css(customCSS.value)]: customCSS.visible,
|
||||
|
||||
@ -1,14 +1,15 @@
|
||||
import { Add, Star } from '@mui/icons-material';
|
||||
import { Button, Divider, IconButton, SwipeableDrawer, Tooltip, useMediaQuery, useTheme } from '@mui/material';
|
||||
import { Section as SectionRecord } from '@reactive-resume/schema';
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
import get from 'lodash/get';
|
||||
import Link from 'next/link';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useMemo } from 'react';
|
||||
import React, { ReactComponentElement, useMemo } from 'react';
|
||||
import { validate } from 'uuid';
|
||||
|
||||
import Logo from '@/components/shared/Logo';
|
||||
import { getCustomSections, left } from '@/config/sections';
|
||||
import { getCustomSections, getSectionsByType, left } from '@/config/sections';
|
||||
import { setSidebarState } from '@/store/build/buildSlice';
|
||||
import { useAppDispatch, useAppSelector } from '@/store/hooks';
|
||||
import { addSection } from '@/store/resume/resumeSlice';
|
||||
@ -52,7 +53,49 @@ const LeftSidebar = () => {
|
||||
items: [],
|
||||
};
|
||||
|
||||
dispatch(addSection({ value: newSection }));
|
||||
dispatch(addSection({ value: newSection, type: 'custom' }));
|
||||
};
|
||||
|
||||
const sectionsList = () => {
|
||||
const sectionsComponents: Array<ReactComponentElement<any>> = [];
|
||||
|
||||
for (const item of left) {
|
||||
const id = (item as any).id;
|
||||
const component = (item as any).component;
|
||||
const type = component.props.type || 'basic';
|
||||
const addMore = !!component.props.addMore;
|
||||
|
||||
sectionsComponents.push(
|
||||
<section key={id} id={id}>
|
||||
{component}
|
||||
</section>
|
||||
);
|
||||
|
||||
if (addMore) {
|
||||
const additionalSections = getSectionsByType(sections, type);
|
||||
const elements = [];
|
||||
for (const element of additionalSections) {
|
||||
const newId = element.id;
|
||||
|
||||
const props = cloneDeep(component.props);
|
||||
props.path = 'sections.' + newId;
|
||||
props.name = element.name;
|
||||
props.isDeletable = true;
|
||||
props.addMore = false;
|
||||
props.isDuplicated = true;
|
||||
const newComponent = React.cloneElement(component, props);
|
||||
|
||||
elements.push(
|
||||
<section key={newId} id={`section-${newId}`}>
|
||||
{newComponent}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
sectionsComponents.push(...elements);
|
||||
}
|
||||
}
|
||||
|
||||
return sectionsComponents;
|
||||
};
|
||||
|
||||
return (
|
||||
@ -68,9 +111,7 @@ const LeftSidebar = () => {
|
||||
<nav className="overflow-y-scroll">
|
||||
<div>
|
||||
<Link href="/dashboard">
|
||||
<a className="inline-flex">
|
||||
<Logo size={40} />
|
||||
</a>
|
||||
<Logo size={40} />
|
||||
</Link>
|
||||
<Divider />
|
||||
</div>
|
||||
@ -89,7 +130,7 @@ const LeftSidebar = () => {
|
||||
|
||||
{customSections.map(({ id }) => (
|
||||
<Tooltip key={id} title={get(sections, `${id}.name`, '') as string} placement="right" arrow>
|
||||
<IconButton onClick={() => handleClick(id)}>
|
||||
<IconButton onClick={() => id && handleClick(id)}>
|
||||
<Star />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
@ -100,12 +141,7 @@ const LeftSidebar = () => {
|
||||
</nav>
|
||||
|
||||
<main>
|
||||
{left.map(({ id, component }) => (
|
||||
<section key={id} id={id}>
|
||||
{component}
|
||||
</section>
|
||||
))}
|
||||
|
||||
{sectionsList()}
|
||||
{customSections.map(({ id }) => (
|
||||
<section key={id} id={`section-${id}`}>
|
||||
<Section path={`sections.${id}`} isEditable isHideable isDeletable />
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { Add } from '@mui/icons-material';
|
||||
import { Button } from '@mui/material';
|
||||
import { ListItem } from '@reactive-resume/schema';
|
||||
import { ListItem, Section as SectionRecord, SectionType } from '@reactive-resume/schema';
|
||||
import clsx from 'clsx';
|
||||
import get from 'lodash/get';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
@ -10,28 +10,34 @@ import Heading from '@/components/shared/Heading';
|
||||
import List from '@/components/shared/List';
|
||||
import { useAppDispatch, useAppSelector } from '@/store/hooks';
|
||||
import { ModalName, setModalState } from '@/store/modal/modalSlice';
|
||||
import { duplicateItem } from '@/store/resume/resumeSlice';
|
||||
import { duplicateItem, duplicateSection } from '@/store/resume/resumeSlice';
|
||||
|
||||
import SectionSettings from './SectionSettings';
|
||||
|
||||
type Props = {
|
||||
path: `sections.${string}`;
|
||||
type?: SectionType;
|
||||
name?: string;
|
||||
titleKey?: string;
|
||||
subtitleKey?: string;
|
||||
isEditable?: boolean;
|
||||
isHideable?: boolean;
|
||||
isDeletable?: boolean;
|
||||
addMore?: boolean;
|
||||
isDuplicated?: boolean;
|
||||
};
|
||||
|
||||
const Section: React.FC<Props> = ({
|
||||
path,
|
||||
name = 'Section Name',
|
||||
type = 'basic',
|
||||
titleKey = 'title',
|
||||
subtitleKey = 'subtitle',
|
||||
isEditable = false,
|
||||
isHideable = false,
|
||||
isDeletable = false,
|
||||
addMore = false,
|
||||
isDuplicated = false,
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
@ -42,21 +48,43 @@ const Section: React.FC<Props> = ({
|
||||
|
||||
const handleAdd = () => {
|
||||
const id = path.split('.')[1];
|
||||
const modal: ModalName = validate(id) ? 'builder.sections.custom' : `builder.${path}`;
|
||||
let modal: ModalName = validate(id) ? 'builder.sections.custom' : `builder.${path}`;
|
||||
|
||||
if (type) {
|
||||
modal = `builder.sections.${type}`;
|
||||
}
|
||||
dispatch(setModalState({ modal, state: { open: true, payload: { path } } }));
|
||||
};
|
||||
|
||||
const handleEdit = (item: ListItem) => {
|
||||
const id = path.split('.')[1];
|
||||
const modal: ModalName = validate(id) ? 'builder.sections.custom' : `builder.${path}`;
|
||||
let modal: ModalName = validate(id) ? 'builder.sections.custom' : `builder.${path}`;
|
||||
|
||||
const payload = validate(id) ? { path, item } : { item };
|
||||
|
||||
if (isDuplicated) {
|
||||
modal = `builder.sections.${type}`;
|
||||
payload.path = path;
|
||||
}
|
||||
|
||||
dispatch(setModalState({ modal, state: { open: true, payload } }));
|
||||
};
|
||||
|
||||
const handleDuplicate = (item: ListItem) => dispatch(duplicateItem({ path: `${path}.items`, value: item }));
|
||||
|
||||
const handleDuplicateSection = () => {
|
||||
const newSection: SectionRecord = {
|
||||
name: `${heading}`,
|
||||
type: type,
|
||||
visible: true,
|
||||
columns: 2,
|
||||
items: [],
|
||||
isDuplicated: true,
|
||||
};
|
||||
|
||||
dispatch(duplicateSection({ value: newSection, type }));
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Heading path={path} name={name} isEditable={isEditable} isHideable={isHideable} isDeletable={isDeletable} />
|
||||
@ -77,6 +105,16 @@ const Section: React.FC<Props> = ({
|
||||
{t<string>('builder.common.actions.add', { token: heading })}
|
||||
</Button>
|
||||
</footer>
|
||||
|
||||
{addMore ? (
|
||||
<div className="py-6 text-right">
|
||||
<Button fullWidth variant="outlined" startIcon={<Add />} onClick={handleDuplicateSection}>
|
||||
{t<string>('builder.common.actions.duplicate')}
|
||||
</Button>
|
||||
</div>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@ -17,7 +17,9 @@ const CustomCSS = () => {
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const customCSS: CustomCSSType = useAppSelector((state) => get(state.resume.present, 'metadata.css', {}));
|
||||
const customCSS: CustomCSSType = useAppSelector((state) =>
|
||||
get(state.resume.present, 'metadata.css', {} as CustomCSSType)
|
||||
);
|
||||
|
||||
const handleChange = (value: string | undefined) => {
|
||||
dispatch(setResumeState({ path: 'metadata.css.value', value }));
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { PictureAsPdf, Schema } from '@mui/icons-material';
|
||||
import { List, ListItem, ListItemButton, ListItemText } from '@mui/material';
|
||||
import dayjs from 'dayjs';
|
||||
import get from 'lodash/get';
|
||||
import pick from 'lodash/pick';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
@ -45,10 +46,11 @@ const Export = () => {
|
||||
|
||||
const slug = get(resume, 'slug');
|
||||
const username = get(resume, 'user.username');
|
||||
const updatedAt = get(resume, 'updatedAt');
|
||||
|
||||
const url = await mutateAsync({ username, slug });
|
||||
const url = await mutateAsync({ username, slug, lastUpdated: dayjs(updatedAt).unix().toString() });
|
||||
|
||||
download(`/api${url}`);
|
||||
download(url);
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@ -3,7 +3,7 @@ import { Button } from '@mui/material';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
|
||||
import Heading from '@/components/shared/Heading';
|
||||
import { DONATION_URL, GITHUB_ISSUES_URL, GITHUB_URL } from '@/constants/index';
|
||||
import { DOCS_URL, DONATION_URL, GITHUB_ISSUES_URL, GITHUB_URL } from '@/constants/index';
|
||||
|
||||
import styles from './Links.module.scss';
|
||||
|
||||
@ -49,6 +49,12 @@ const Links = () => {
|
||||
{t<string>('builder.rightSidebar.sections.links.github')}
|
||||
</Button>
|
||||
</a>
|
||||
|
||||
<a href={DOCS_URL} target="_blank" rel="noreferrer">
|
||||
<Button variant="text" startIcon={<Link />}>
|
||||
{t<string>('builder.rightSidebar.sections.links.docs')}
|
||||
</Button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
||||
@ -10,7 +10,7 @@ import {
|
||||
Switch,
|
||||
TextField,
|
||||
} from '@mui/material';
|
||||
import { DateConfig, Resume } from '@reactive-resume/schema';
|
||||
import { DateConfig, PageConfig, Resume } from '@reactive-resume/schema';
|
||||
import dayjs from 'dayjs';
|
||||
import get from 'lodash/get';
|
||||
import { useRouter } from 'next/router';
|
||||
@ -48,9 +48,10 @@ const Settings = () => {
|
||||
const slug: string = useMemo(() => get(resume, 'slug'), [resume]);
|
||||
const username: string = useMemo(() => get(resume, 'user.username'), [resume]);
|
||||
const dateConfig: DateConfig = useMemo(() => get(resume, 'metadata.date'), [resume]);
|
||||
const pageConfig: PageConfig | undefined = useMemo(() => get(resume, 'metadata.page'), [resume]);
|
||||
|
||||
const isDarkMode = useMemo(() => theme === 'dark', [theme]);
|
||||
const exampleString = useMemo(() => `Eg. ${dayjs().utc().format(dateConfig.format)}`, [dateConfig.format]);
|
||||
const exampleDateString = useMemo(() => `Eg. ${dayjs().utc().format(dateConfig.format)}`, [dateConfig.format]);
|
||||
const themeString = useMemo(() => (isDarkMode ? 'Matte Black Everything' : 'As bright as your future'), [isDarkMode]);
|
||||
|
||||
const { mutateAsync: loadSampleDataMutation } = useMutation<Resume, ServerError, LoadSampleDataParams>(
|
||||
@ -60,6 +61,9 @@ const Settings = () => {
|
||||
|
||||
const handleSetTheme = (value: boolean) => dispatch(setTheme({ theme: value ? 'dark' : 'light' }));
|
||||
|
||||
const handleChangePageFormat = (value: PageConfig['format'] | null) =>
|
||||
dispatch(setResumeState({ path: 'metadata.page.format', value }));
|
||||
|
||||
const handleChangeDateFormat = (value: string | null) =>
|
||||
dispatch(setResumeState({ path: 'metadata.date.format', value }));
|
||||
|
||||
@ -94,7 +98,7 @@ const Settings = () => {
|
||||
<>
|
||||
<Heading path="metadata.settings" name={t<string>('builder.rightSidebar.sections.settings.heading')} />
|
||||
|
||||
<List sx={{ padding: 0 }}>
|
||||
<List disablePadding>
|
||||
{/* Global Settings */}
|
||||
<>
|
||||
<ListSubheader disableSticky className="rounded">
|
||||
@ -118,13 +122,13 @@ const Settings = () => {
|
||||
primary={t<string>('builder.rightSidebar.sections.settings.global.date.primary')}
|
||||
secondary={t<string>('builder.rightSidebar.sections.settings.global.date.secondary')}
|
||||
/>
|
||||
<Autocomplete<string, false, boolean, false>
|
||||
<Autocomplete<string, false, true, false>
|
||||
disableClearable
|
||||
className="my-2 w-full"
|
||||
options={dateFormatOptions}
|
||||
value={dateConfig.format}
|
||||
onChange={(_, value) => handleChangeDateFormat(value)}
|
||||
renderInput={(params) => <TextField {...params} helperText={exampleString} />}
|
||||
renderInput={(params) => <TextField {...params} helperText={exampleDateString} />}
|
||||
/>
|
||||
</ListItem>
|
||||
|
||||
@ -134,7 +138,7 @@ const Settings = () => {
|
||||
primary={t<string>('builder.rightSidebar.sections.settings.global.language.primary')}
|
||||
secondary={t<string>('builder.rightSidebar.sections.settings.global.language.secondary')}
|
||||
/>
|
||||
<Autocomplete<Language, false, boolean, false>
|
||||
<Autocomplete<Language, false, true, false>
|
||||
disableClearable
|
||||
className="my-2 w-full"
|
||||
options={languages}
|
||||
@ -159,6 +163,23 @@ const Settings = () => {
|
||||
{t<string>('builder.rightSidebar.sections.settings.page.heading')}
|
||||
</ListSubheader>
|
||||
|
||||
<ListItem className="flex-col">
|
||||
<ListItemText
|
||||
className="w-full"
|
||||
primary={t<string>('builder.rightSidebar.sections.settings.page.format.primary')}
|
||||
secondary={t<string>('builder.rightSidebar.sections.settings.page.format.secondary')}
|
||||
/>
|
||||
<Autocomplete<PageConfig['format'], false, true, false>
|
||||
disableClearable
|
||||
defaultValue="A4"
|
||||
className="my-2 w-full"
|
||||
options={['A4', 'Letter']}
|
||||
value={pageConfig?.format || 'A4'}
|
||||
renderInput={(params) => <TextField {...params} />}
|
||||
onChange={(_, value) => handleChangePageFormat(value)}
|
||||
/>
|
||||
</ListItem>
|
||||
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
primary={t<string>('builder.rightSidebar.sections.settings.page.orientation.primary')}
|
||||
@ -191,7 +212,7 @@ const Settings = () => {
|
||||
{t<string>('builder.rightSidebar.sections.settings.resume.heading')}
|
||||
</ListSubheader>
|
||||
|
||||
<ListItem>
|
||||
<ListItem disableGutters>
|
||||
<ListItemButton onClick={handleLoadSampleData}>
|
||||
<ListItemIcon>
|
||||
<Anchor />
|
||||
@ -203,7 +224,7 @@ const Settings = () => {
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
|
||||
<ListItem>
|
||||
<ListItem disableGutters>
|
||||
<ListItemButton onClick={handleResetResume}>
|
||||
<ListItemIcon>
|
||||
<DeleteForever />
|
||||
|
||||
@ -31,7 +31,14 @@ const Templates = () => {
|
||||
<div key={template.id} className={styles.template}>
|
||||
<div className={clsx(styles.preview, { [styles.selected]: template.id === currentTemplate })}>
|
||||
<ButtonBase onClick={() => handleChange(template)}>
|
||||
<Image src={template.preview} alt={template.name} className="rounded-sm" layout="fill" priority />
|
||||
<Image
|
||||
fill
|
||||
priority
|
||||
alt={template.name}
|
||||
src={template.preview}
|
||||
className="rounded-sm"
|
||||
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
|
||||
/>
|
||||
</ButtonBase>
|
||||
</div>
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Theme as ThemeType } from '@reactive-resume/schema';
|
||||
import { ThemeConfig } from '@reactive-resume/schema';
|
||||
import get from 'lodash/get';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
|
||||
@ -16,7 +16,7 @@ const Theme = () => {
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const { background, text, primary } = useAppSelector<ThemeType>((state) =>
|
||||
const { background, text, primary } = useAppSelector<ThemeConfig>((state) =>
|
||||
get(state.resume.present, 'metadata.theme')
|
||||
);
|
||||
|
||||
|
||||
@ -16,9 +16,7 @@ type Props = {
|
||||
const ResumeCard: React.FC<Props> = ({ modal, icon: Icon, title, subtitle }) => {
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const handleClick = () => {
|
||||
dispatch(setModalState({ modal, state: { open: true } }));
|
||||
};
|
||||
const handleClick = () => dispatch(setModalState({ modal, state: { open: true } }));
|
||||
|
||||
return (
|
||||
<section className={styles.resume}>
|
||||
|
||||
@ -115,9 +115,7 @@ const ResumePreview: React.FC<Props> = ({ resume }) => {
|
||||
}}
|
||||
>
|
||||
<ButtonBase className={styles.preview}>
|
||||
{resume.image ? (
|
||||
<Image src={resume.image} alt={resume.name} objectFit="cover" layout="fill" priority />
|
||||
) : null}
|
||||
{resume.image ? <Image src={resume.image} alt={resume.name} priority width={400} height={0} /> : null}
|
||||
</ButtonBase>
|
||||
</Link>
|
||||
|
||||
|
||||
@ -47,9 +47,9 @@ const Avatar: React.FC<Props> = ({ size = 64 }) => {
|
||||
<Image
|
||||
width={size}
|
||||
height={size}
|
||||
alt={user?.name}
|
||||
className={styles.avatar}
|
||||
src={getGravatarUrl(email, size)}
|
||||
alt={user?.name ?? 'User Avatar'}
|
||||
/>
|
||||
</IconButton>
|
||||
|
||||
|
||||
@ -4,8 +4,8 @@ type Props = {
|
||||
size?: 256 | 64 | 48 | 40 | 32;
|
||||
};
|
||||
|
||||
const Logo: React.FC<Props> = ({ size = 64 }) => {
|
||||
return <Image alt="Reactive Resume" src="/images/logos/logo.svg" className="rounded" width={size} height={size} />;
|
||||
};
|
||||
const Logo: React.FC<Props> = ({ size = 64 }) => (
|
||||
<Image alt="Reactive Resume" src="/images/logos/logo.svg" className="rounded" width={size} height={size} priority />
|
||||
);
|
||||
|
||||
export default Logo;
|
||||
|
||||
@ -2,10 +2,12 @@ export type Language = {
|
||||
code: string;
|
||||
name: string;
|
||||
localName?: string;
|
||||
isRTL?: boolean;
|
||||
};
|
||||
|
||||
export const languages: Language[] = [
|
||||
{ code: 'ar', name: 'Arabic', localName: 'اَلْعَرَبِيَّةُ' },
|
||||
{ code: 'am', name: 'Amharic', localName: 'አማርኛ' },
|
||||
{ code: 'ar', name: 'Arabic', localName: 'اَلْعَرَبِيَّةُ', isRTL: true },
|
||||
{ code: 'bg', name: 'Bulgarian', localName: 'български' },
|
||||
{ code: 'bn', name: 'Bengali', localName: 'বাংলা' },
|
||||
{ code: 'ca', name: 'Catalan', localName: 'Valencian' },
|
||||
@ -15,10 +17,10 @@ export const languages: Language[] = [
|
||||
{ code: 'el', name: 'Greek', localName: 'Ελληνικά' },
|
||||
{ code: 'en', name: 'English' },
|
||||
{ code: 'es', name: 'Spanish', localName: 'Español' },
|
||||
{ code: 'fa', name: 'Persian', localName: 'فارسی' },
|
||||
{ code: 'fa', name: 'Persian', localName: 'فارسی', isRTL: true },
|
||||
{ code: 'fi', name: 'Finnish', localName: 'Suomi' },
|
||||
{ code: 'fr', name: 'French', localName: 'Français' },
|
||||
{ code: 'he', name: 'Hebrew', localName: 'Ivrit' },
|
||||
{ code: 'he', name: 'Hebrew', localName: 'Ivrit', isRTL: true },
|
||||
{ code: 'hi', name: 'Hindi', localName: 'हिन्दी' },
|
||||
{ code: 'hu', name: 'Hungarian', localName: 'Magyar' },
|
||||
{ code: 'id', name: 'Indonesian', localName: 'Bahasa Indonesia' },
|
||||
@ -26,7 +28,9 @@ export const languages: Language[] = [
|
||||
{ code: 'ja', name: 'Japanese', localName: '日本語' },
|
||||
{ code: 'km', name: 'Khmer', localName: 'ភាសាខ្មែរ' },
|
||||
{ code: 'kn', name: 'Kannada', localName: 'ಕನ್ನಡ' },
|
||||
{ code: 'ko', name: 'Korean', localName: '한국어' },
|
||||
{ code: 'ml', name: 'Malayalam', localName: 'മലയാളം' },
|
||||
{ code: 'mr', name: 'Marathi', localName: 'मराठी' },
|
||||
{ code: 'ne', name: 'Nepali', localName: 'नेपाली' },
|
||||
{ code: 'nl', name: 'Dutch', localName: 'Nederlands' },
|
||||
{ code: 'no', name: 'Norwegian', localName: 'Norsk' },
|
||||
|
||||
@ -23,7 +23,7 @@ import {
|
||||
VolunteerActivism,
|
||||
Work,
|
||||
} from '@mui/icons-material';
|
||||
import { Section as SectionRecord } from '@reactive-resume/schema';
|
||||
import { Section as SectionRecord, SectionType } from '@reactive-resume/schema';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
|
||||
import Basics from '@/components/build/LeftSidebar/sections/Basics';
|
||||
@ -60,59 +60,136 @@ export const left: SidebarSection[] = [
|
||||
{
|
||||
id: 'work',
|
||||
icon: <Work />,
|
||||
component: <Section path="sections.work" titleKey="name" subtitleKey="position" isEditable isHideable />,
|
||||
component: (
|
||||
<Section
|
||||
type={'work'}
|
||||
addMore={true}
|
||||
path="sections.work"
|
||||
titleKey="name"
|
||||
subtitleKey="position"
|
||||
isEditable
|
||||
isHideable
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'education',
|
||||
icon: <School />,
|
||||
component: <Section path="sections.education" titleKey="institution" subtitleKey="area" isEditable isHideable />,
|
||||
component: (
|
||||
<Section
|
||||
type={'education'}
|
||||
path="sections.education"
|
||||
titleKey="institution"
|
||||
subtitleKey="area"
|
||||
isEditable
|
||||
isHideable
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'awards',
|
||||
icon: <EmojiEvents />,
|
||||
component: <Section path="sections.awards" titleKey="title" subtitleKey="awarder" isEditable isHideable />,
|
||||
component: (
|
||||
<Section type={'awards'} path="sections.awards" titleKey="title" subtitleKey="awarder" isEditable isHideable />
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'certifications',
|
||||
icon: <CardGiftcard />,
|
||||
component: <Section path="sections.certifications" titleKey="name" subtitleKey="issuer" isEditable isHideable />,
|
||||
component: (
|
||||
<Section
|
||||
type={'certifications'}
|
||||
path="sections.certifications"
|
||||
titleKey="name"
|
||||
subtitleKey="issuer"
|
||||
isEditable
|
||||
isHideable
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'publications',
|
||||
icon: <MenuBook />,
|
||||
component: <Section path="sections.publications" titleKey="name" subtitleKey="publisher" isEditable isHideable />,
|
||||
component: (
|
||||
<Section
|
||||
type={'publications'}
|
||||
path="sections.publications"
|
||||
titleKey="name"
|
||||
subtitleKey="publisher"
|
||||
isEditable
|
||||
isHideable
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'skills',
|
||||
icon: <Architecture />,
|
||||
component: <Section path="sections.skills" titleKey="name" subtitleKey="level" isEditable isHideable />,
|
||||
component: (
|
||||
<Section type={'skills'} path="sections.skills" titleKey="name" subtitleKey="level" isEditable isHideable />
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'languages',
|
||||
icon: <Language />,
|
||||
component: <Section path="sections.languages" titleKey="name" subtitleKey="level" isEditable isHideable />,
|
||||
component: (
|
||||
<Section type={'languages'} path="sections.languages" titleKey="name" subtitleKey="level" isEditable isHideable />
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'interests',
|
||||
icon: <Sailing />,
|
||||
component: <Section path="sections.interests" titleKey="name" subtitleKey="keywords" isEditable isHideable />,
|
||||
component: (
|
||||
<Section
|
||||
type={'interests'}
|
||||
path="sections.interests"
|
||||
titleKey="name"
|
||||
subtitleKey="keywords"
|
||||
isEditable
|
||||
isHideable
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'volunteer',
|
||||
icon: <VolunteerActivism />,
|
||||
component: (
|
||||
<Section path="sections.volunteer" titleKey="organization" subtitleKey="position" isEditable isHideable />
|
||||
<Section
|
||||
type={'volunteer'}
|
||||
path="sections.volunteer"
|
||||
titleKey="organization"
|
||||
subtitleKey="position"
|
||||
isEditable
|
||||
isHideable
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'projects',
|
||||
icon: <Coffee />,
|
||||
component: <Section path="sections.projects" titleKey="name" subtitleKey="description" isEditable isHideable />,
|
||||
component: (
|
||||
<Section
|
||||
type={'projects'}
|
||||
path="sections.projects"
|
||||
titleKey="name"
|
||||
subtitleKey="description"
|
||||
isEditable
|
||||
isHideable
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'references',
|
||||
icon: <Groups />,
|
||||
component: <Section path="sections.references" titleKey="name" subtitleKey="relationship" isEditable isHideable />,
|
||||
component: (
|
||||
<Section
|
||||
type={'references'}
|
||||
path="sections.references"
|
||||
titleKey="name"
|
||||
subtitleKey="relationship"
|
||||
isEditable
|
||||
isHideable
|
||||
/>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
@ -164,7 +241,19 @@ export const right: SidebarSection[] = [
|
||||
},
|
||||
];
|
||||
|
||||
export const getCustomSections = (sections: Record<string, SectionRecord>): Array<Required<SectionRecord>> => {
|
||||
export const getSectionsByType = (sections: Record<string, SectionRecord>, type: SectionType): SectionRecord[] => {
|
||||
if (isEmpty(sections)) return [];
|
||||
|
||||
return Object.entries(sections).reduce((acc, [id, section]) => {
|
||||
if (section.type.startsWith(type) && section.isDuplicated) {
|
||||
return [...acc, { ...section, id }];
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, [] as SectionRecord[]);
|
||||
};
|
||||
|
||||
export const getCustomSections = (sections: Record<string, SectionRecord>): SectionRecord[] => {
|
||||
if (isEmpty(sections)) return [];
|
||||
|
||||
return Object.entries(sections).reduce((acc, [id, section]) => {
|
||||
@ -173,7 +262,7 @@ export const getCustomSections = (sections: Record<string, SectionRecord>): Arra
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, [] as Array<Required<SectionRecord>>);
|
||||
}, [] as SectionRecord[]);
|
||||
};
|
||||
|
||||
const sections = [...left, ...right];
|
||||
|
||||
@ -9,6 +9,7 @@ export const VALID_URL_REGEX = /[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}
|
||||
export const FILENAME_TIMESTAMP = 'DDMMYYYYHHmmss';
|
||||
|
||||
// Links
|
||||
export const DOCS_URL = 'https://docs.rxresu.me';
|
||||
export const DONATION_URL = 'https://paypal.me/RajaRajanA';
|
||||
export const TRANSLATE_URL = 'https://translate.rxresu.me/';
|
||||
export const DIGITALOCEAN_URL = 'https://pillai.xyz/digitalocean';
|
||||
|
||||
@ -162,15 +162,15 @@ const LoginModal: React.FC = () => {
|
||||
{!FLAG_DISABLE_SIGNUPS && (
|
||||
<p className="text-xs">
|
||||
<Trans t={t} i18nKey="modals.auth.login.register-text">
|
||||
If you don't have one, you can <a onClick={handleCreateAccount}>create an account</a> here.
|
||||
If you don't have one, you can <a onClick={handleCreateAccount}>create an account here.</a>
|
||||
</Trans>
|
||||
</p>
|
||||
)}
|
||||
|
||||
<p className="text-xs">
|
||||
<Trans t={t} i18nKey="modals.auth.login.recover-text">
|
||||
In case you have forgotten your password, you can <a onClick={handleRecoverAccount}>recover your account</a>
|
||||
here.
|
||||
In case you have forgotten your password, you can{' '}
|
||||
<a onClick={handleRecoverAccount}>recover your account here.</a>
|
||||
</Trans>
|
||||
</p>
|
||||
</BaseModal>
|
||||
|
||||
@ -93,7 +93,7 @@ const AwardModal: React.FC = () => {
|
||||
heading={isEditMode ? editText : addText}
|
||||
footerChildren={<Button onClick={handleSubmit(onSubmit)}>{isEditMode ? editText : addText}</Button>}
|
||||
>
|
||||
<form className="my-2 grid grid-cols-2 gap-4">
|
||||
<form className="my-2 grid grid-cols-2 gap-4" onSubmit={handleSubmit(onSubmit)}>
|
||||
<Controller
|
||||
name="title"
|
||||
control={control}
|
||||
@ -177,6 +177,7 @@ const AwardModal: React.FC = () => {
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<input type="submit" style={{ display: 'none' }} />
|
||||
</form>
|
||||
</BaseModal>
|
||||
);
|
||||
|
||||
@ -93,7 +93,7 @@ const CertificateModal: React.FC = () => {
|
||||
heading={isEditMode ? editText : addText}
|
||||
footerChildren={<Button onClick={handleSubmit(onSubmit)}>{isEditMode ? editText : addText}</Button>}
|
||||
>
|
||||
<form className="my-2 grid grid-cols-2 gap-4">
|
||||
<form className="my-2 grid grid-cols-2 gap-4" onSubmit={handleSubmit(onSubmit)}>
|
||||
<Controller
|
||||
name="name"
|
||||
control={control}
|
||||
@ -177,6 +177,7 @@ const CertificateModal: React.FC = () => {
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<input type="submit" style={{ display: 'none' }} />
|
||||
</form>
|
||||
</BaseModal>
|
||||
);
|
||||
|
||||
@ -60,13 +60,14 @@ const CustomModal: React.FC = () => {
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const heading = useAppSelector((state) => get(state.resume.present, `${path}.name`));
|
||||
const { open: isOpen, payload } = useAppSelector((state) => state.modal['builder.sections.custom']);
|
||||
|
||||
const path: string = get(payload, 'path', '');
|
||||
const path: string = get(payload, 'path', 'sections.custom');
|
||||
const item: FormData = get(payload, 'item', null);
|
||||
const isEditMode = useMemo(() => !!item, [item]);
|
||||
|
||||
const heading = useAppSelector((state) => get(state.resume.present, `${path}.name`));
|
||||
|
||||
const addText = useMemo(() => t<string>('builder.common.actions.add', { token: heading }), [t, heading]);
|
||||
const editText = useMemo(() => t<string>('builder.common.actions.edit', { token: heading }), [t, heading]);
|
||||
|
||||
@ -110,7 +111,7 @@ const CustomModal: React.FC = () => {
|
||||
heading={isEditMode ? editText : addText}
|
||||
footerChildren={<Button onClick={handleSubmit(onSubmit)}>{isEditMode ? editText : addText}</Button>}
|
||||
>
|
||||
<form className="my-2 grid grid-cols-2 gap-4">
|
||||
<form className="my-2 grid grid-cols-2 gap-4" onSubmit={handleSubmit(onSubmit)}>
|
||||
<Controller
|
||||
name="title"
|
||||
control={control}
|
||||
@ -260,9 +261,9 @@ const CustomModal: React.FC = () => {
|
||||
multiline
|
||||
minRows={3}
|
||||
maxRows={6}
|
||||
label={t<string>('builder.common.form.summary.label')}
|
||||
className="col-span-2"
|
||||
error={!!fieldState.error}
|
||||
label={t<string>('builder.common.form.summary.label')}
|
||||
helperText={fieldState.error?.message || <MarkdownSupported />}
|
||||
{...field}
|
||||
/>
|
||||
@ -282,6 +283,7 @@ const CustomModal: React.FC = () => {
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<input type="submit" style={{ display: 'none' }} />
|
||||
</form>
|
||||
</BaseModal>
|
||||
);
|
||||
|
||||
@ -106,7 +106,7 @@ const EducationModal: React.FC = () => {
|
||||
heading={isEditMode ? editText : addText}
|
||||
footerChildren={<Button onClick={handleSubmit(onSubmit)}>{isEditMode ? editText : addText}</Button>}
|
||||
>
|
||||
<form className="my-2 grid grid-cols-2 gap-4">
|
||||
<form className="my-2 grid grid-cols-2 gap-4" onSubmit={handleSubmit(onSubmit)}>
|
||||
<Controller
|
||||
name="institution"
|
||||
control={control}
|
||||
@ -255,6 +255,7 @@ const EducationModal: React.FC = () => {
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<input type="submit" style={{ display: 'none' }} />
|
||||
</form>
|
||||
</BaseModal>
|
||||
);
|
||||
|
||||
@ -84,7 +84,7 @@ const InterestModal: React.FC = () => {
|
||||
heading={isEditMode ? editText : addText}
|
||||
footerChildren={<Button onClick={handleSubmit(onSubmit)}>{isEditMode ? editText : addText}</Button>}
|
||||
>
|
||||
<form className="my-2 grid grid-cols-2 gap-4">
|
||||
<form className="my-2 grid grid-cols-2 gap-4" onSubmit={handleSubmit(onSubmit)}>
|
||||
<Controller
|
||||
name="name"
|
||||
control={control}
|
||||
@ -114,6 +114,7 @@ const InterestModal: React.FC = () => {
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<input type="submit" style={{ display: 'none' }} />
|
||||
</form>
|
||||
</BaseModal>
|
||||
);
|
||||
|
||||
@ -85,7 +85,7 @@ const LanguageModal: React.FC = () => {
|
||||
heading={isEditMode ? editText : addText}
|
||||
footerChildren={<Button onClick={handleSubmit(onSubmit)}>{isEditMode ? editText : addText}</Button>}
|
||||
>
|
||||
<form className="my-2 grid grid-cols-2 gap-4">
|
||||
<form className="my-2 grid grid-cols-2 gap-4" onSubmit={handleSubmit(onSubmit)}>
|
||||
<Controller
|
||||
name="name"
|
||||
control={control}
|
||||
@ -150,6 +150,7 @@ const LanguageModal: React.FC = () => {
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
<input type="submit" style={{ display: 'none' }} />
|
||||
</form>
|
||||
</BaseModal>
|
||||
);
|
||||
|
||||
@ -89,7 +89,7 @@ const ProfileModal: React.FC = () => {
|
||||
handleClose={handleClose}
|
||||
footerChildren={<Button onClick={handleSubmit(onSubmit)}>{isEditMode ? editText : addText}</Button>}
|
||||
>
|
||||
<form className="my-2 grid grid-cols-2 gap-4">
|
||||
<form className="my-2 grid grid-cols-2 gap-4" onSubmit={handleSubmit(onSubmit)}>
|
||||
<Controller
|
||||
name="network"
|
||||
control={control}
|
||||
@ -136,6 +136,7 @@ const ProfileModal: React.FC = () => {
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<input type="submit" style={{ display: 'none' }} />
|
||||
</form>
|
||||
</BaseModal>
|
||||
);
|
||||
|
||||
@ -102,7 +102,7 @@ const ProjectModal: React.FC = () => {
|
||||
heading={isEditMode ? editText : addText}
|
||||
footerChildren={<Button onClick={handleSubmit(onSubmit)}>{isEditMode ? editText : addText}</Button>}
|
||||
>
|
||||
<form className="my-2 grid grid-cols-2 gap-4">
|
||||
<form className="my-2 grid grid-cols-2 gap-4" onSubmit={handleSubmit(onSubmit)}>
|
||||
<Controller
|
||||
name="name"
|
||||
control={control}
|
||||
@ -225,6 +225,7 @@ const ProjectModal: React.FC = () => {
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<input type="submit" style={{ display: 'none' }} />
|
||||
</form>
|
||||
</BaseModal>
|
||||
);
|
||||
|
||||
@ -93,7 +93,7 @@ const PublicationModal: React.FC = () => {
|
||||
heading={isEditMode ? editText : addText}
|
||||
footerChildren={<Button onClick={handleSubmit(onSubmit)}>{isEditMode ? editText : addText}</Button>}
|
||||
>
|
||||
<form className="my-2 grid grid-cols-2 gap-4">
|
||||
<form className="my-2 grid grid-cols-2 gap-4" onSubmit={handleSubmit(onSubmit)}>
|
||||
<Controller
|
||||
name="name"
|
||||
control={control}
|
||||
@ -177,6 +177,7 @@ const PublicationModal: React.FC = () => {
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<input type="submit" style={{ display: 'none' }} />
|
||||
</form>
|
||||
</BaseModal>
|
||||
);
|
||||
|
||||
@ -90,7 +90,7 @@ const ReferenceModal: React.FC = () => {
|
||||
heading={isEditMode ? editText : addText}
|
||||
footerChildren={<Button onClick={handleSubmit(onSubmit)}>{isEditMode ? editText : addText}</Button>}
|
||||
>
|
||||
<form className="my-2 grid grid-cols-2 gap-4">
|
||||
<form className="my-2 grid grid-cols-2 gap-4" onSubmit={handleSubmit(onSubmit)}>
|
||||
<Controller
|
||||
name="name"
|
||||
control={control}
|
||||
@ -162,6 +162,7 @@ const ReferenceModal: React.FC = () => {
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<input type="submit" style={{ display: 'none' }} />
|
||||
</form>
|
||||
</BaseModal>
|
||||
);
|
||||
|
||||
@ -88,7 +88,7 @@ const SkillModal: React.FC = () => {
|
||||
heading={isEditMode ? editText : addText}
|
||||
footerChildren={<Button onClick={handleSubmit(onSubmit)}>{isEditMode ? editText : addText}</Button>}
|
||||
>
|
||||
<form className="my-2 grid grid-cols-2 gap-4">
|
||||
<form className="my-2 grid grid-cols-2 gap-4" onSubmit={handleSubmit(onSubmit)}>
|
||||
<Controller
|
||||
name="name"
|
||||
control={control}
|
||||
@ -166,6 +166,8 @@ const SkillModal: React.FC = () => {
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
<input type="submit" style={{ display: 'none' }} />
|
||||
</form>
|
||||
</BaseModal>
|
||||
);
|
||||
|
||||
@ -99,7 +99,7 @@ const VolunteerModal: React.FC = () => {
|
||||
heading={isEditMode ? editText : addText}
|
||||
footerChildren={<Button onClick={handleSubmit(onSubmit)}>{isEditMode ? editText : addText}</Button>}
|
||||
>
|
||||
<form className="my-2 grid grid-cols-2 gap-4">
|
||||
<form className="my-2 grid grid-cols-2 gap-4" onSubmit={handleSubmit(onSubmit)}>
|
||||
<Controller
|
||||
name="organization"
|
||||
control={control}
|
||||
@ -208,6 +208,7 @@ const VolunteerModal: React.FC = () => {
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<input type="submit" style={{ display: 'none' }} />
|
||||
</form>
|
||||
</BaseModal>
|
||||
);
|
||||
|
||||
@ -2,7 +2,7 @@ import { joiResolver } from '@hookform/resolvers/joi';
|
||||
import { Add, DriveFileRenameOutline } from '@mui/icons-material';
|
||||
import { Button, TextField } from '@mui/material';
|
||||
import { DatePicker } from '@mui/x-date-pickers';
|
||||
import { SectionPath, WorkExperience } from '@reactive-resume/schema';
|
||||
import { WorkExperience } from '@reactive-resume/schema';
|
||||
import dayjs from 'dayjs';
|
||||
import Joi from 'joi';
|
||||
import get from 'lodash/get';
|
||||
@ -20,8 +20,6 @@ import { addItem, editItem } from '@/store/resume/resumeSlice';
|
||||
|
||||
type FormData = WorkExperience;
|
||||
|
||||
const path: SectionPath = 'sections.work';
|
||||
|
||||
const defaultState: FormData = {
|
||||
name: '',
|
||||
position: '',
|
||||
@ -50,10 +48,12 @@ const WorkModal: React.FC = () => {
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const heading = useAppSelector((state) => get(state.resume.present, `${path}.name`));
|
||||
const { open: isOpen, payload } = useAppSelector((state) => state.modal[`builder.${path}`]);
|
||||
|
||||
const { open: isOpen, payload } = useAppSelector((state) => state.modal['builder.sections.work']);
|
||||
const path: string = get(payload, 'path', 'sections.work');
|
||||
const item: FormData = get(payload, 'item', null);
|
||||
|
||||
const heading = useAppSelector((state) => get(state.resume.present, `${path}.name`));
|
||||
|
||||
const isEditMode = useMemo(() => !!item, [item]);
|
||||
|
||||
const addText = useMemo(() => t<string>('builder.common.actions.add', { token: heading }), [t, heading]);
|
||||
@ -77,7 +77,7 @@ const WorkModal: React.FC = () => {
|
||||
const handleClose = () => {
|
||||
dispatch(
|
||||
setModalState({
|
||||
modal: `builder.${path}`,
|
||||
modal: 'builder.sections.work',
|
||||
state: { open: false },
|
||||
})
|
||||
);
|
||||
@ -99,7 +99,7 @@ const WorkModal: React.FC = () => {
|
||||
heading={isEditMode ? editText : addText}
|
||||
footerChildren={<Button onClick={handleSubmit(onSubmit)}>{isEditMode ? editText : addText}</Button>}
|
||||
>
|
||||
<form className="my-2 grid grid-cols-2 gap-4">
|
||||
<form className="my-2 grid grid-cols-2 gap-4" onSubmit={handleSubmit(onSubmit)}>
|
||||
<Controller
|
||||
name="name"
|
||||
control={control}
|
||||
@ -208,6 +208,7 @@ const WorkModal: React.FC = () => {
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<input type="submit" style={{ display: 'none' }} />
|
||||
</form>
|
||||
</BaseModal>
|
||||
);
|
||||
|
||||
@ -4,6 +4,7 @@ const i18nConfig = {
|
||||
i18n: {
|
||||
defaultLocale: 'en',
|
||||
locales: [
|
||||
'am',
|
||||
'ar',
|
||||
'bg',
|
||||
'bn',
|
||||
@ -25,7 +26,9 @@ const i18nConfig = {
|
||||
'ja',
|
||||
'km',
|
||||
'kn',
|
||||
'ko',
|
||||
'ml',
|
||||
'mr',
|
||||
'ne',
|
||||
'nl',
|
||||
'no',
|
||||
|
||||
@ -15,19 +15,6 @@ const nextConfig = {
|
||||
domains: ['cdn.rxresu.me', 'www.gravatar.com'],
|
||||
},
|
||||
|
||||
async rewrites() {
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
return [
|
||||
{
|
||||
source: '/api/:path*',
|
||||
destination: 'http://localhost:3100/:path*',
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
return [];
|
||||
},
|
||||
|
||||
// Hack to make Tailwind darkMode 'class' strategy with CSS Modules
|
||||
// Ref: https://github.com/tailwindlabs/tailwindcss/issues/3258#issuecomment-968368156
|
||||
webpack: (config) => {
|
||||
|
||||
@ -9,75 +9,75 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@beam-australia/react-env": "^3.1.1",
|
||||
"@date-io/dayjs": "^2.15.0",
|
||||
"@emotion/css": "^11.10.0",
|
||||
"@emotion/react": "^11.10.0",
|
||||
"@emotion/styled": "^11.10.0",
|
||||
"@hello-pangea/dnd": "^16.0.0",
|
||||
"@hookform/resolvers": "2.9.7",
|
||||
"@monaco-editor/react": "^4.4.5",
|
||||
"@mui/icons-material": "^5.10.2",
|
||||
"@mui/lab": "^5.0.0-alpha.96",
|
||||
"@mui/material": "^5.10.2",
|
||||
"@mui/system": "^5.10.2",
|
||||
"@mui/x-date-pickers": "5.0.0-beta.7",
|
||||
"@next/env": "^12.2.5",
|
||||
"@react-oauth/google": "^0.2.6",
|
||||
"@reduxjs/toolkit": "^1.8.5",
|
||||
"axios": "^0.27.2",
|
||||
"@date-io/dayjs": "^2.16.0",
|
||||
"@emotion/css": "^11.10.5",
|
||||
"@emotion/react": "^11.10.5",
|
||||
"@emotion/styled": "^11.10.5",
|
||||
"@hello-pangea/dnd": "^16.0.1",
|
||||
"@hookform/resolvers": "2.9.10",
|
||||
"@monaco-editor/react": "^4.4.6",
|
||||
"@mui/icons-material": "^5.10.9",
|
||||
"@mui/lab": "^5.0.0-alpha.107",
|
||||
"@mui/material": "^5.10.13",
|
||||
"@mui/system": "^5.10.13",
|
||||
"@mui/x-date-pickers": "5.0.8",
|
||||
"@next/env": "^13.0.3",
|
||||
"@react-oauth/google": "^0.4.0",
|
||||
"@reduxjs/toolkit": "^1.9.0",
|
||||
"axios": "^1.1.3",
|
||||
"clsx": "^1.2.1",
|
||||
"dayjs": "^1.11.5",
|
||||
"dayjs": "^1.11.6",
|
||||
"downloadjs": "^1.4.7",
|
||||
"joi": "^17.6.0",
|
||||
"joi": "^17.7.0",
|
||||
"lodash": "^4.17.21",
|
||||
"md5-hex": "^4.0.0",
|
||||
"monaco-editor": "^0.34.0",
|
||||
"monaco-editor": "^0.34.1",
|
||||
"nanoid": "^3.3.4",
|
||||
"next": "12.2.5",
|
||||
"next-i18next": "^12.0.0",
|
||||
"next": "13.0.3",
|
||||
"next-i18next": "^12.1.0",
|
||||
"react": "^18.2.0",
|
||||
"react-colorful": "^5.6.1",
|
||||
"react-dnd": "16.0.1",
|
||||
"react-dnd-html5-backend": "16.0.1",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-hook-form": "^7.34.2",
|
||||
"react-hot-toast": "2.3.0",
|
||||
"react-hotkeys-hook": "^3.4.7",
|
||||
"react-icons": "^4.4.0",
|
||||
"react-hook-form": "^7.39.3",
|
||||
"react-hot-toast": "2.4.0",
|
||||
"react-icons": "^4.6.0",
|
||||
"react-markdown": "^8.0.3",
|
||||
"react-query": "^3.39.2",
|
||||
"react-redux": "^8.0.2",
|
||||
"react-redux": "^8.0.5",
|
||||
"react-zoom-pan-pinch": "^2.1.3",
|
||||
"redux": "^4.2.0",
|
||||
"redux-persist": "^6.0.0",
|
||||
"redux-saga": "^1.2.1",
|
||||
"redux-undo": "^1.0.1",
|
||||
"remark-gfm": "^3.0.1",
|
||||
"sharp": "^0.30.7",
|
||||
"uuid": "^8.3.2",
|
||||
"sharp": "^0.31.2",
|
||||
"uuid": "^9.0.0",
|
||||
"webfontloader": "^1.6.28"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.18.13",
|
||||
"@babel/core": "^7.20.2",
|
||||
"@reactive-resume/schema": "workspace:*",
|
||||
"@tailwindcss/typography": "^0.5.4",
|
||||
"eslint-plugin-unused-imports": "^2.0.0",
|
||||
"@tailwindcss/typography": "^0.5.8",
|
||||
"@types/downloadjs": "^1.4.3",
|
||||
"@types/lodash": "^4.14.184",
|
||||
"@types/node": "^18.7.13",
|
||||
"@types/react": "^18.0.17",
|
||||
"@types/react-dom": "^18.0.6",
|
||||
"@types/lodash": "^4.14.188",
|
||||
"@types/node": "^18.11.9",
|
||||
"@types/react": "^18.0.25",
|
||||
"@types/react-dom": "^18.0.8",
|
||||
"@types/react-redux": "^7.1.24",
|
||||
"@types/tailwindcss": "^3.0.11",
|
||||
"@types/uuid": "^8.3.4",
|
||||
"@types/webfontloader": "^1.6.34",
|
||||
"autoprefixer": "^10.4.8",
|
||||
"csstype": "^3.1.0",
|
||||
"eslint-config-next": "^12.2.5",
|
||||
"eslint-plugin-tailwindcss": "^3.6.0",
|
||||
"next-sitemap": "^3.1.21",
|
||||
"postcss": "^8.4.16",
|
||||
"sass": "^1.54.5",
|
||||
"tailwindcss": "^3.1.8",
|
||||
"typescript": "^4.8.2"
|
||||
"@types/webfontloader": "^1.6.35",
|
||||
"autoprefixer": "^10.4.13",
|
||||
"csstype": "^3.1.1",
|
||||
"eslint-config-next": "^13.0.3",
|
||||
"eslint-plugin-tailwindcss": "^3.6.2",
|
||||
"next-sitemap": "^3.1.31",
|
||||
"postcss": "^8.4.19",
|
||||
"sass": "^1.56.1",
|
||||
"tailwindcss": "^3.2.4",
|
||||
"typescript": "^4.8.4"
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ import { Download, Downloading } from '@mui/icons-material';
|
||||
import { ButtonBase } from '@mui/material';
|
||||
import { Resume } from '@reactive-resume/schema';
|
||||
import clsx from 'clsx';
|
||||
import dayjs from 'dayjs';
|
||||
import download from 'downloadjs';
|
||||
import get from 'lodash/get';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
@ -96,9 +97,11 @@ const Preview: NextPage<Props> = ({ username, slug, resume: initialData }) => {
|
||||
|
||||
const handleDownload = async () => {
|
||||
try {
|
||||
const url = await mutateAsync({ username, slug });
|
||||
const updatedAt = get(resume, 'updatedAt');
|
||||
|
||||
download(`/api${url}`);
|
||||
const url = await mutateAsync({ username, slug, lastUpdated: dayjs(updatedAt).unix().toString() });
|
||||
|
||||
download(url);
|
||||
} catch {
|
||||
toast.error('Something went wrong, please try again later.');
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ import clsx from 'clsx';
|
||||
import get from 'lodash/get';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
import { GetServerSideProps, NextPage } from 'next';
|
||||
import { useRouter } from 'next/router';
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
@ -54,10 +55,20 @@ export const getServerSideProps: GetServerSideProps<Props | Promise<Props>, Quer
|
||||
};
|
||||
|
||||
const Printer: NextPage<Props> = ({ resume: initialData, locale }) => {
|
||||
const router = useRouter();
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const resume = useAppSelector((state) => state.resume.present);
|
||||
|
||||
useEffect(() => {
|
||||
if (router.locale !== locale) {
|
||||
const { pathname, asPath, query } = router;
|
||||
|
||||
router.push({ pathname, query }, asPath, { locale });
|
||||
}
|
||||
}, [router, locale]);
|
||||
|
||||
useEffect(() => {
|
||||
if (initialData) dispatch(setResume(initialData));
|
||||
}, [dispatch, initialData]);
|
||||
|
||||
@ -18,46 +18,44 @@ import queryClient from '@/services/react-query';
|
||||
import store, { persistor } from '@/store/index';
|
||||
import WrapperRegistry from '@/wrappers/index';
|
||||
|
||||
const App: React.FC<AppProps> = ({ Component, pageProps }) => {
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Reactive Resume</title>
|
||||
const App = ({ Component, pageProps }: AppProps): JSX.Element => (
|
||||
<>
|
||||
<Head>
|
||||
<title>Reactive Resume</title>
|
||||
|
||||
<meta
|
||||
name="description"
|
||||
content="Reactive Resume is a free and open source resume builder that's built to make the mundane tasks of creating, updating and sharing your resume as easy as 1, 2, 3."
|
||||
/>
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="initial-scale=1, width=device-width" />
|
||||
</Head>
|
||||
<meta
|
||||
name="description"
|
||||
content="Reactive Resume is a free and open source resume builder that's built to make the mundane tasks of creating, updating and sharing your resume as easy as 1, 2, 3."
|
||||
/>
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="initial-scale=1, width=device-width" />
|
||||
</Head>
|
||||
|
||||
<ReduxProvider store={store}>
|
||||
<LocalizationProvider dateAdapter={DayjsAdapter}>
|
||||
<PersistGate loading={null} persistor={persistor}>
|
||||
<GoogleOAuthProvider clientId={env('GOOGLE_CLIENT_ID')}>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<WrapperRegistry>
|
||||
<Loading />
|
||||
<ReduxProvider store={store}>
|
||||
<LocalizationProvider dateAdapter={DayjsAdapter}>
|
||||
<PersistGate loading={null} persistor={persistor}>
|
||||
<GoogleOAuthProvider clientId={env('GOOGLE_CLIENT_ID')}>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<WrapperRegistry>
|
||||
<Loading />
|
||||
|
||||
<Component {...pageProps} />
|
||||
<Component {...pageProps} />
|
||||
|
||||
<ModalWrapper />
|
||||
<Toaster
|
||||
position="bottom-right"
|
||||
toastOptions={{
|
||||
duration: 4000,
|
||||
className: 'toast',
|
||||
}}
|
||||
/>
|
||||
</WrapperRegistry>
|
||||
</QueryClientProvider>
|
||||
</GoogleOAuthProvider>
|
||||
</PersistGate>
|
||||
</LocalizationProvider>
|
||||
</ReduxProvider>
|
||||
</>
|
||||
);
|
||||
};
|
||||
<ModalWrapper />
|
||||
<Toaster
|
||||
position="bottom-right"
|
||||
toastOptions={{
|
||||
duration: 4000,
|
||||
className: 'toast',
|
||||
}}
|
||||
/>
|
||||
</WrapperRegistry>
|
||||
</QueryClientProvider>
|
||||
</GoogleOAuthProvider>
|
||||
</PersistGate>
|
||||
</LocalizationProvider>
|
||||
</ReduxProvider>
|
||||
</>
|
||||
);
|
||||
|
||||
export default appWithTranslation(App);
|
||||
|
||||
@ -17,13 +17,11 @@ import { fetchResumes } from '@/services/resume';
|
||||
import { useAppDispatch } from '@/store/hooks';
|
||||
import styles from '@/styles/pages/Dashboard.module.scss';
|
||||
|
||||
export const getStaticProps: GetStaticProps = async ({ locale = 'en' }) => {
|
||||
return {
|
||||
props: {
|
||||
...(await serverSideTranslations(locale, ['common', 'modals', 'dashboard'])),
|
||||
},
|
||||
};
|
||||
};
|
||||
export const getStaticProps: GetStaticProps = async ({ locale = 'en' }) => ({
|
||||
props: {
|
||||
...(await serverSideTranslations(locale, ['common', 'modals', 'dashboard'])),
|
||||
},
|
||||
});
|
||||
|
||||
const Dashboard: NextPage = () => {
|
||||
const { t } = useTranslation();
|
||||
@ -48,9 +46,7 @@ const Dashboard: NextPage = () => {
|
||||
|
||||
<header>
|
||||
<Link href="/">
|
||||
<a>
|
||||
<Logo size={40} />
|
||||
</a>
|
||||
<Logo size={40} />
|
||||
</Link>
|
||||
|
||||
<Avatar size={40} />
|
||||
@ -58,15 +54,15 @@ const Dashboard: NextPage = () => {
|
||||
|
||||
<main className={styles.resumes}>
|
||||
<ResumeCard
|
||||
modal="dashboard.create-resume"
|
||||
icon={Add}
|
||||
modal="dashboard.create-resume"
|
||||
title={t<string>('dashboard.create-resume.title')}
|
||||
subtitle={t<string>('dashboard.create-resume.subtitle')}
|
||||
/>
|
||||
|
||||
<ResumeCard
|
||||
modal="dashboard.import-external"
|
||||
icon={ImportExport}
|
||||
modal="dashboard.import-external"
|
||||
title={t<string>('dashboard.import-external.title')}
|
||||
subtitle={t<string>('dashboard.import-external.subtitle')}
|
||||
/>
|
||||
|
||||
@ -20,15 +20,13 @@ import { useAppDispatch, useAppSelector } from '@/store/hooks';
|
||||
import { setModalState } from '@/store/modal/modalSlice';
|
||||
import styles from '@/styles/pages/Home.module.scss';
|
||||
|
||||
import { DIGITALOCEAN_URL, DONATION_URL, GITHUB_URL } from '../constants';
|
||||
import { DIGITALOCEAN_URL, DOCS_URL, DONATION_URL, GITHUB_URL } from '../constants';
|
||||
|
||||
export const getStaticProps: GetStaticProps = async ({ locale = 'en' }) => {
|
||||
return {
|
||||
props: {
|
||||
...(await serverSideTranslations(locale, ['common', 'modals', 'landing'])),
|
||||
},
|
||||
};
|
||||
};
|
||||
export const getStaticProps: GetStaticProps = async ({ locale = 'en' }) => ({
|
||||
props: {
|
||||
...(await serverSideTranslations(locale, ['common', 'modals', 'landing'])),
|
||||
},
|
||||
});
|
||||
|
||||
const Home: NextPage = () => {
|
||||
const { t } = useTranslation();
|
||||
@ -39,11 +37,8 @@ const Home: NextPage = () => {
|
||||
const isLoggedIn = useAppSelector((state) => state.auth.isLoggedIn);
|
||||
|
||||
const handleLogin = () => dispatch(setModalState({ modal: 'auth.login', state: { open: true } }));
|
||||
|
||||
const handleRegister = () => dispatch(setModalState({ modal: 'auth.register', state: { open: true } }));
|
||||
|
||||
const handleToggle = () => dispatch(setTheme({ theme: theme === 'light' ? 'dark' : 'light' }));
|
||||
|
||||
const handleLogout = () => dispatch(logout());
|
||||
|
||||
return (
|
||||
@ -117,7 +112,13 @@ const Home: NextPage = () => {
|
||||
<div className={styles.screenshots}>
|
||||
{screenshots.map(({ src, alt }) => (
|
||||
<a key={src} href={src} className={styles.image} target="_blank" rel="noreferrer">
|
||||
<Image src={src} alt={alt} layout="fill" objectFit="cover" />
|
||||
<Image
|
||||
fill
|
||||
src={src}
|
||||
alt={alt}
|
||||
className="object-cover"
|
||||
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
|
||||
/>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
@ -170,6 +171,12 @@ const Home: NextPage = () => {
|
||||
</Button>
|
||||
</a>
|
||||
|
||||
<a href={DOCS_URL} target="_blank" rel="noreferrer">
|
||||
<Button variant="text" startIcon={<LinkIcon />}>
|
||||
{t<string>('landing.links.links.docs')}
|
||||
</Button>
|
||||
</a>
|
||||
|
||||
<a href={DONATION_URL} target="_blank" rel="noreferrer">
|
||||
<Button variant="text" startIcon={<LinkIcon />}>
|
||||
{t<string>('landing.links.links.donate')}
|
||||
@ -180,7 +187,13 @@ const Home: NextPage = () => {
|
||||
|
||||
<section className={styles.section}>
|
||||
<a href={DIGITALOCEAN_URL} target="_blank" rel="noreferrer">
|
||||
<Image src="/images/sponsors/digitalocean.svg" alt="Powered By DigitalOcean" width={200} height={40} />
|
||||
<Image
|
||||
src={`/images/sponsors/${theme == 'dark' ? 'digitalocean' : 'digitaloceanLight'}.svg`}
|
||||
style={{ width: 200, height: 40, objectFit: 'contain' }}
|
||||
alt="Powered By DigitalOcean"
|
||||
width={200}
|
||||
height={40}
|
||||
/>
|
||||
</a>
|
||||
</section>
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@ import { Download, Downloading } from '@mui/icons-material';
|
||||
import { ButtonBase } from '@mui/material';
|
||||
import { Resume } from '@reactive-resume/schema';
|
||||
import clsx from 'clsx';
|
||||
import dayjs from 'dayjs';
|
||||
import download from 'downloadjs';
|
||||
import get from 'lodash/get';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
@ -69,9 +70,13 @@ const Preview: NextPage<Props> = ({ shortId }) => {
|
||||
|
||||
const handleDownload = async () => {
|
||||
try {
|
||||
const url = await mutateAsync({ username: resume.user.username, slug: resume.slug });
|
||||
const url = await mutateAsync({
|
||||
username: resume.user.username,
|
||||
slug: resume.slug,
|
||||
lastUpdated: dayjs(resume.updatedAt).unix().toString(),
|
||||
});
|
||||
|
||||
download(`/api${url}`);
|
||||
download(url);
|
||||
} catch {
|
||||
toast.error('Something went wrong, please try again later.');
|
||||
}
|
||||
|
||||
101
client/public/images/sponsors/digitaloceanLight.svg
Normal file
101
client/public/images/sponsors/digitaloceanLight.svg
Normal file
@ -0,0 +1,101 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 604 129" style="enable-background:new 0 0 604 129;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#0069ff;}
|
||||
.st1{fill-rule:evenodd;clip-rule:evenodd;fill:#0069ff;}
|
||||
</style>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st0" d="M174.3,3c4.9,0,8.7,2.9,8.7,8.6c0,5.6-3.8,8.5-8.7,8.5h-7.6v11.1h-3.5V3H174.3z M166.7,17.1h7.2
|
||||
c3,0,5.6-1.8,5.6-5.5c0-3.8-2.5-5.5-5.6-5.5h-7.2V17.1z"/>
|
||||
<path class="st0" d="M208.8,21.7c0,6.1-4.3,10-9.9,10c-5.6,0-9.9-3.9-9.9-10c0-6.1,4.3-10,9.9-10
|
||||
C204.5,11.7,208.8,15.6,208.8,21.7z M192.3,21.7c0,4.5,2.9,7.2,6.6,7.2c3.7,0,6.6-2.7,6.6-7.2c0-4.5-2.9-7.1-6.6-7.1
|
||||
C195.2,14.5,192.3,17.2,192.3,21.7z"/>
|
||||
<path class="st0" d="M234.4,31.3l-5.2-13.8L224,31.3h-2.6L214.1,12h3.6l5.2,14l5.2-14h2.3l5.3,14l5.2-14h3.5L237,31.3H234.4z"/>
|
||||
<path class="st0" d="M253,22.9c0.2,3.7,2.6,5.9,6,5.9c2.8,0,4.8-1.3,5.4-3.4l3.2,0.2c-0.8,3.5-4.1,6.1-8.6,6.1
|
||||
c-5.5,0-9.6-3.7-9.6-10c0-6.3,4-10,9.5-10c5.5,0,8.8,3.7,8.8,9.4v1.8H253z M253,20.3h11.6c-0.1-3.4-2-5.7-5.6-5.7
|
||||
C255.6,14.5,253.2,16.5,253,20.3z"/>
|
||||
<path class="st0" d="M285.4,14.9c-3.4,0-5.6,2.3-5.6,5.3v11.1h-3.2V12h3.2v2.9c0.7-1.6,2.5-3.1,5.7-3.1V14.9z"/>
|
||||
<path class="st0" d="M294.7,22.9c0.2,3.7,2.6,5.9,6,5.9c2.8,0,4.8-1.3,5.4-3.4l3.2,0.2c-0.8,3.5-4.1,6.1-8.6,6.1
|
||||
c-5.5,0-9.6-3.7-9.6-10c0-6.3,4-10,9.5-10c5.5,0,8.8,3.7,8.8,9.4v1.8H294.7z M294.7,20.3h11.6c-0.1-3.4-2-5.7-5.6-5.7
|
||||
C297.4,14.5,294.9,16.5,294.7,20.3z"/>
|
||||
<path class="st0" d="M333.1,31.3v-3.1c-1.1,2-3.6,3.5-6.8,3.5c-5.3,0-9.3-3.8-9.3-10c0-6.2,4-10,9.3-10c3.2,0,5.6,1.4,6.6,3.2V2
|
||||
h3.2v29.4H333.1z M320.3,21.7c0,4.6,2.8,7.2,6.5,7.2c3.6,0,6.2-2.2,6.2-6.6v-1.1c0-4.3-2.6-6.6-6.2-6.6
|
||||
C323.1,14.5,320.3,17.1,320.3,21.7z"/>
|
||||
<path class="st0" d="M361.8,14.9c1.1-1.9,3.4-3.2,6.7-3.2c5.3,0,9.3,3.8,9.3,10c0,6.2-4,10-9.3,10c-3.3,0-5.7-1.5-6.8-3.5v3.1
|
||||
h-3.1V2h3.2V14.9z M361.9,21.1v1.1c0,4.4,2.6,6.6,6.2,6.6c3.7,0,6.5-2.5,6.5-7.2c0-4.6-2.8-7.1-6.5-7.1
|
||||
C364.5,14.5,361.9,16.8,361.9,21.1z"/>
|
||||
<path class="st0" d="M386.3,40.9l4.6-10.7L383.2,12h3.6l5.8,14.5l5.8-14.5h3.6l-12.2,28.9H386.3z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="XMLID_2369_">
|
||||
<g>
|
||||
<g id="XMLID_281_">
|
||||
<g id="XMLID_282_">
|
||||
<g>
|
||||
<g id="XMLID_283_">
|
||||
<g id="XMLID_287_">
|
||||
<path id="XMLID_288_" class="st0" d="M64.4,127l0-24.2c25.6,0,45.5-25.4,35.7-52.3c-3.6-10-11.6-17.9-21.6-21.6
|
||||
c-27-9.8-52.3,10-52.3,35.7c0,0,0,0,0,0L2,64.7C2,23.8,41.5-8,84.3,5.4c18.7,5.8,33.6,20.7,39.4,39.4
|
||||
C137,87.6,105.2,127,64.4,127z"/>
|
||||
</g>
|
||||
<polygon id="XMLID_286_" class="st1" points="64.4,102.9 40.4,102.9 40.4,78.9 40.4,78.9 64.4,78.9 64.4,78.9 "/>
|
||||
<polygon id="XMLID_285_" class="st1" points="40.3,121.5 21.8,121.5 21.8,121.5 21.8,102.9 40.4,102.9 40.4,121.5 "/>
|
||||
<path id="XMLID_284_" class="st1" d="M21.9,102.9H6.3c0,0,0,0,0,0V87.4c0,0,0,0,0,0h15.5c0,0,0,0,0,0V102.9z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g id="XMLID_254_">
|
||||
<path id="XMLID_278_" class="st0" d="M200.9,52.4c-5.5-3.8-12.4-5.8-20.5-5.8h-17.5v55.5h17.5c8,0,14.9-2.1,20.5-6.1
|
||||
c3-2.1,5.4-5.1,7.1-8.9c1.7-3.7,2.5-8.2,2.5-13.1c0-4.9-0.8-9.3-2.5-13C206.3,57.4,203.9,54.4,200.9,52.4z M173.1,56h5.5
|
||||
c6.1,0,11.1,1.2,15,3.6c4.2,2.6,6.4,7.4,6.4,14.4c0,7.2-2.2,12.3-6.4,15.1h0c-3.7,2.4-8.7,3.6-14.9,3.6h-5.6V56z"/>
|
||||
<path id="XMLID_277_" class="st0" d="M222.6,45.9c-1.7,0-3.1,0.6-4.3,1.8c-1.2,1.1-1.8,2.6-1.8,4.2c0,1.7,0.6,3.1,1.8,4.3
|
||||
c1.2,1.2,2.6,1.8,4.3,1.8c1.7,0,3.1-0.6,4.3-1.8c1.2-1.2,1.8-2.6,1.8-4.3c0-1.7-0.6-3.1-1.8-4.2
|
||||
C225.7,46.5,224.3,45.9,222.6,45.9z"/>
|
||||
<rect id="XMLID_276_" x="217.6" y="63" class="st0" width="9.8" height="39.1"/>
|
||||
<path id="XMLID_273_" class="st0" d="M263.2,66.3c-3-2.6-6.3-4.2-9.9-4.2c-5.4,0-9.9,1.9-13.4,5.6c-3.5,3.7-5.3,8.4-5.3,14.1
|
||||
c0,5.5,1.8,10.2,5.2,14c3.5,3.7,8,5.5,13.5,5.5c3.8,0,7.1-1.1,9.7-3.1V99c0,3.2-0.9,5.8-2.6,7.5c-1.7,1.7-4.1,2.6-7.1,2.6
|
||||
c-4.5,0-7.4-1.8-10.9-6.5l-6.7,6.4l0.2,0.3c1.4,2,3.7,4,6.6,5.9c2.9,1.9,6.6,2.8,10.9,2.8c5.8,0,10.6-1.8,14.1-5.4
|
||||
c3.5-3.6,5.3-8.4,5.3-14.2V63h-9.7V66.3z M260.6,89.4c-1.7,2-3.9,2.9-6.8,2.9c-2.8,0-5-0.9-6.7-2.9c-1.7-1.9-2.5-4.5-2.5-7.7
|
||||
c0-3.2,0.9-5.8,2.5-7.7c1.7-1.9,3.9-2.9,6.7-2.9c2.8,0,5,1,6.8,2.9c1.7,2,2.6,4.6,2.6,7.7C263.2,84.9,262.3,87.5,260.6,89.4z"/>
|
||||
<rect id="XMLID_272_" x="281.3" y="63" class="st0" width="9.8" height="39.1"/>
|
||||
<path id="XMLID_271_" class="st0" d="M286.3,45.9c-1.7,0-3.1,0.6-4.3,1.8c-1.2,1.1-1.8,2.6-1.8,4.2c0,1.7,0.6,3.1,1.8,4.3
|
||||
c1.2,1.2,2.6,1.8,4.3,1.8c1.7,0,3.1-0.6,4.3-1.8c1.2-1.2,1.8-2.6,1.8-4.3c0-1.7-0.6-3.1-1.8-4.2C289.4,46.5,288,45.9,286.3,45.9
|
||||
z"/>
|
||||
<path id="XMLID_270_" class="st0" d="M312.7,52.5H303V63h-5.6v9h5.6v16.2c0,5.1,1,8.7,3,10.8c2,2.1,5.6,3.2,10.6,3.2
|
||||
c1.6,0,3.2-0.1,4.8-0.2l0.4,0v-9l-3.4,0.2c-2.3,0-3.9-0.4-4.7-1.2c-0.8-0.8-1.1-2.6-1.1-5.2V72h9.2v-9h-9.2V52.5z"/>
|
||||
<rect id="XMLID_269_" x="368" y="46.6" class="st0" width="9.8" height="55.5"/>
|
||||
<path id="XMLID_268_" class="st0" d="M477.3,88.2c-1.8,2-3.6,3.7-4.9,4.6v0c-1.4,0.9-3.1,1.3-5.1,1.3c-2.9,0-5.2-1.1-7.1-3.2
|
||||
c-1.9-2.2-2.8-4.9-2.8-8.3s0.9-6.1,2.8-8.2c1.9-2.2,4.2-3.2,7.1-3.2c3.2,0,6.5,2,9.4,5.4l6.5-6.2l0,0c-4.2-5.5-9.7-8.1-16.1-8.1
|
||||
c-5.4,0-10.1,2-13.9,5.8c-3.8,3.9-5.7,8.8-5.7,14.6s1.9,10.7,5.7,14.6c3.8,3.9,8.5,5.9,13.9,5.9c7.1,0,12.9-3.1,16.8-8.7
|
||||
L477.3,88.2z"/>
|
||||
<path id="XMLID_265_" class="st0" d="M517.7,68.5c-1.4-1.9-3.3-3.5-5.7-4.7c-2.3-1.1-5.1-1.7-8.1-1.7c-5.5,0-10,2-13.4,6
|
||||
c-3.3,4-4.9,8.9-4.9,14.7c0,5.9,1.8,10.8,5.4,14.6c3.6,3.7,8.4,5.6,14.2,5.6c6.6,0,12.1-2.7,16.2-8l0.2-0.3l-6.4-6.2l0,0
|
||||
c-0.6,0.7-1.4,1.5-2.2,2.3c-1,0.9-1.9,1.6-2.9,2.1c-1.5,0.7-3.1,1.1-5,1.1c-2.7,0-5-0.8-6.7-2.4c-1.6-1.5-2.6-3.5-2.8-5.9h26.1
|
||||
l0.1-3.6c0-2.5-0.3-5-1-7.3C520.1,72.6,519.1,70.4,517.7,68.5z M496.2,77.7c0.5-1.9,1.3-3.4,2.6-4.6c1.3-1.3,3.1-2,5.2-2
|
||||
c2.4,0,4.2,0.7,5.5,2c1.2,1.2,1.8,2.8,2,4.6H496.2z"/>
|
||||
<path id="XMLID_262_" class="st0" d="M555.5,66L555.5,66c-3-2.5-7.1-3.8-12.3-3.8c-3.3,0-6.3,0.7-9.1,2.1
|
||||
c-2.6,1.3-5.1,3.5-6.7,6.3l0.1,0.1l6.3,6c2.6-4.1,5.5-5.6,9.3-5.6c2.1,0,3.8,0.6,5.1,1.6c1.3,1.1,1.9,2.5,1.9,4.2v1.9
|
||||
c-2.4-0.7-4.9-1.1-7.2-1.1c-4.9,0-8.9,1.2-11.8,3.4c-3,2.3-4.5,5.6-4.5,9.8c0,3.7,1.3,6.7,3.8,8.9c2.6,2.1,5.8,3.2,9.5,3.2
|
||||
c3.7,0,7.3-1.5,10.4-4.1v3.2h9.7V77C560,72.2,558.5,68.5,555.5,66z M538,87.2c1.1-0.8,2.7-1.2,4.7-1.2c2.4,0,4.9,0.5,7.5,1.4
|
||||
v3.8c-2.1,2-5,3-8.5,3c-1.7,0-3-0.4-3.9-1.1c-0.9-0.7-1.3-1.7-1.3-2.8C536.4,89,536.9,88,538,87.2z"/>
|
||||
<path id="XMLID_261_" class="st0" d="M597.9,66.7c-2.7-3.1-6.6-4.6-11.5-4.6c-3.9,0-7.1,1.1-9.4,3.3V63h-9.7v39.1h9.8V80.6
|
||||
c0-3,0.7-5.3,2.1-7c1.4-1.7,3.3-2.5,5.8-2.5c2.2,0,3.9,0.7,5.2,2.2c1.3,1.5,1.9,3.6,1.9,6.2v22.7h9.8V79.5
|
||||
C602,74.1,600.6,69.8,597.9,66.7z"/>
|
||||
<path id="XMLID_258_" class="st0" d="M355.6,66L355.6,66c-3-2.5-7.1-3.8-12.3-3.8c-3.3,0-6.3,0.7-9.1,2.1
|
||||
c-2.6,1.3-5.1,3.5-6.7,6.3l0.1,0.1l6.3,6c2.6-4.1,5.5-5.6,9.3-5.6c2.1,0,3.8,0.6,5.1,1.6c1.3,1.1,1.9,2.5,1.9,4.2v1.9
|
||||
c-2.4-0.7-4.9-1.1-7.2-1.1c-4.9,0-8.9,1.2-11.8,3.4c-3,2.3-4.5,5.6-4.5,9.8c0,3.7,1.3,6.7,3.8,8.9c2.6,2.1,5.8,3.2,9.5,3.2
|
||||
c3.7,0,7.3-1.5,10.4-4.1v3.2h9.7V77C360.2,72.2,358.7,68.5,355.6,66z M338.2,87.2c1.1-0.8,2.7-1.2,4.7-1.2
|
||||
c2.4,0,4.9,0.5,7.5,1.4v3.8c-2.1,2-5,3-8.5,3c-1.7,0-3-0.4-3.9-1.1c-0.9-0.7-1.3-1.7-1.3-2.8C336.6,89,337.1,88,338.2,87.2z"/>
|
||||
<path id="XMLID_255_" class="st0" d="M413.6,103c-15.8,0-28.6-12.8-28.6-28.6s12.8-28.6,28.6-28.6s28.6,12.8,28.6,28.6
|
||||
S429.4,103,413.6,103z M413.6,55.8c-10.2,0-18.5,8.3-18.5,18.5s8.3,18.5,18.5,18.5s18.5-8.3,18.5-18.5S423.8,55.8,413.6,55.8z"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 7.7 KiB |
368
client/public/locales/am/builder.json
Normal file
368
client/public/locales/am/builder.json
Normal file
@ -0,0 +1,368 @@
|
||||
{
|
||||
"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": "እርግጠኛ ነዎት ይህንn ማጥፋት ይፈልጋሉ? ይህ የማይመለስ ተግባር ነው።",
|
||||
"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": "አሳንስ",
|
||||
"undo": "ቀልብስ",
|
||||
"redo": "ድገም"
|
||||
}
|
||||
},
|
||||
"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": "ወደ Reactive Resume ተመልሶ ሊመጣ የሚችል የስራ ልምድ ሰነድ የJSON ቅጂዎትን ያውርዱ።"
|
||||
},
|
||||
"pdf": {
|
||||
"loading": {
|
||||
"primary": "PDF በመስራት ላይ",
|
||||
"secondary": "እባክዎ PDF እስኪሰራ ይጠብቁ፣ ይህ እስከ 15 ሰከንድ ሊወስድ ይችላል።"
|
||||
},
|
||||
"normal": {
|
||||
"primary": "PDF",
|
||||
"secondary": "ማተም እና መላክ የሚችሉትን የስራ ልምድ ሰነድዎን በPDF ያውርዱ። ይህ ፋይል ለተጨማሪ አርትዖት ተመልሶ ሊመጣ አይችልም።"
|
||||
}
|
||||
}
|
||||
},
|
||||
"layout": {
|
||||
"heading": "አቀማመጥ",
|
||||
"tooltip": {
|
||||
"reset-layout": "አቀማመጡን መልስ"
|
||||
}
|
||||
},
|
||||
"links": {
|
||||
"bugs-features": {
|
||||
"body": "የስራ ልምድ ሰነድዎን ለመስራት የሚከለክሎት ነገር አለ? ወይም የሚጨምሩት አስደናቂ ሀሳብ አለዎት? በ GitHub ላይ ጉዳይዎን ያቅርቡ።",
|
||||
"button": "GitHub ጉዳዮች",
|
||||
"heading": "ችግሮች? የባህሪ ጥያቄዎች?"
|
||||
},
|
||||
"donate": {
|
||||
"body": "Reactive Resumeን መጠቀም ከወደዱ እባክዎን መተግበሪያው እንዲሰራ እና ያለ ማስታወቂያ ሁሌም በነፃ እንዲቀጥል በተቻለዎት መጠን ለመለገስ ያስቡበት።",
|
||||
"button": "ቡና ይጋብዙኝ",
|
||||
"heading": "ለ Reactive Resume ይለግሱ"
|
||||
},
|
||||
"github": "የምንጭ ኮድ",
|
||||
"docs": "ሰነዶች",
|
||||
"heading": "አገናኞች"
|
||||
},
|
||||
"settings": {
|
||||
"global": {
|
||||
"date": {
|
||||
"primary": "ቀን",
|
||||
"secondary": "በመላው መተግበሪያ ላይ የሚጠቀሙበት የቀን አይነት"
|
||||
},
|
||||
"heading": "ዓለም አቀፍ",
|
||||
"language": {
|
||||
"primary": "ቋንቋ",
|
||||
"secondary": "በመላው መተግበሪያ ላይ የሚጠቀሙበት ቋንቋ"
|
||||
},
|
||||
"theme": {
|
||||
"primary": "ገጽታ"
|
||||
}
|
||||
},
|
||||
"heading": "ቅንብሮች",
|
||||
"page": {
|
||||
"format": {
|
||||
"primary": "የወረቀት መጠን",
|
||||
"secondary": "ከቆመበት ቀጥል ገጾችዎ ልኬቶችን ይወስናል"
|
||||
},
|
||||
"break-line": {
|
||||
"primary": "መስመር መቁረጫ",
|
||||
"secondary": "የA4 ገጽ ቁመትን ለመለየት በሁሉም ገጾች ላይ መስመር አሳይ"
|
||||
},
|
||||
"heading": "ገጽ",
|
||||
"orientation": {
|
||||
"disabled": "አንድ ገጽ ብቻ ሲኖር ምንም ተጽእኖ የለውም",
|
||||
"primary": "አቅጣጫ",
|
||||
"secondary": "ገጾችን በአግድም ሆነ በቋሚ ለማሳየት"
|
||||
}
|
||||
},
|
||||
"resume": {
|
||||
"heading": "የስራልምድ ሰነድ",
|
||||
"reset": {
|
||||
"primary": "ሁሉንም ነገር ዳግም አስጀምር",
|
||||
"secondary": "በጣም ብዙ ስህተቶችን ሰርተዋል? ሁሉንም ለውጦች ዳግም ለማስጀመር እና ከባዶ ለመጀመር እዚህ ይንኩ። ይጠንቀቁ፤ ይህ እርምጃ ወደ ኋላ መመለስ አይቻልም።"
|
||||
},
|
||||
"sample": {
|
||||
"primary": "የናሙና መረጃን ጫን",
|
||||
"secondary": "የት መጀመር እንዳለብዎት እርግጠኛ አይደሉም? የተሟላ የስራ ልምድ ሰነድ እንዴት እንደሚመስል ለማየት አንዳንድ ናሙና መረጃ ለመጫን እዚህ ይንኩ።"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sharing": {
|
||||
"heading": "ማጋራት",
|
||||
"short-url": {
|
||||
"label": "አጭር ማስፈንጠሪያ ይመርጣሉ።"
|
||||
},
|
||||
"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/am/common.json
Normal file
29
client/public/locales/am/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": "እባክዎ ከ2 ሜጋባይት በታች የሆኑ ፋይሎችን ብቻ ይስቀሉ።",
|
||||
"upload-photo-size": "እባክዎትን ከ2 ሜጋባይት በታች የሆኑ ፎቶዎችን ብቻ ይስቀሉ፣ ቢቻል ካሬ።"
|
||||
},
|
||||
"success": {
|
||||
"resume-link-copied": "ወደ የስራ ታሪክዎ የሚወስድ አገናኝ በሰሌዳዎ ተይዟል።"
|
||||
}
|
||||
}
|
||||
}
|
||||
25
client/public/locales/am/dashboard.json
Normal file
25
client/public/locales/am/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": "ዳሽቦርድ"
|
||||
}
|
||||
42
client/public/locales/am/landing.json
Normal file
42
client/public/locales/am/landing.json
Normal file
@ -0,0 +1,42 @@
|
||||
{
|
||||
"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": "የምንጭ ኮድ",
|
||||
"docs": "ሰነዶች",
|
||||
"privacy": "የግላዊነት መመሪያ",
|
||||
"service": "የአገልግሎት ውሎች"
|
||||
}
|
||||
},
|
||||
"screenshots": {
|
||||
"heading": "የገጽ እይታዎች"
|
||||
},
|
||||
"testimonials": {
|
||||
"heading": "ምስክሮች",
|
||||
"body": "ጥሩም ይሁን መጥፎ፣ ስለ Reactive Resume እና ለእርስዎ እንዴት እንደነበረ አስተያየትዎን መስማት እፈልጋለሁ።<br/>በአለም ዙሪያ በተጠቃሚዎች የተላኩ አንዳንድ መልዕክቶች እነዚሁና",
|
||||
"contact": "በዚህ በኩል ልታገኙኝ <1>ኢሜል</1> ትችላላችሁ ወይም <3>በድረ-ገጽ</3> ላይ ባለው የእውቂያ ቅጽ ማግኘት ይችላሉ።"
|
||||
},
|
||||
"summary": {
|
||||
"body": "Reactive Resume የእርስዎን የስራ ታሪክ የመፍጠር፣ የማዘመን እና የማጋራት መደበኛ ተግባራትን እንደ 1 2 3 ቀላል ለማድረግ የተሰራ ነፃ እና በነጻ የሚገኝ የስራ ልምድ ሰነድ መገንቢያ ነው። በዚህ መገልገያ የተለያዩ የስራ ልምድ ሰነዶችን በመስራት፣ ከቀጣሪዎች ወይም ከጓደኞች ጋር በማስፈንጠሪያ ማጋራት እና እንደ PDF ማተም ፣ ሁሉንም በነጻ ፣ ምንም ማስታወቂያ ሳይኖር ፣ ምንም ክትትል ሳይደረግ ፣ የመረጃዎን ትክክለኛነት እና ግላዊነት ተጠብቆ ማከናወን ይችላሉ።",
|
||||
"heading": "ማጠቃለያ"
|
||||
}
|
||||
}
|
||||
135
client/public/locales/am/modals.json
Normal file
135
client/public/locales/am/modals.json
Normal file
@ -0,0 +1,135 @@
|
||||
{
|
||||
"auth": {
|
||||
"forgot-password": {
|
||||
"actions": {
|
||||
"send-email": "የይለፍ ቃል ዳግም ማስጀመሪያ ኢሜይል ላክ"
|
||||
},
|
||||
"body": "መልሰው ማግኘት ከሚፈልጉት መለያ ጋር የተያያዘውን የኢሜይል አድራሻ ያስገቡ።",
|
||||
"form": {
|
||||
"email": {
|
||||
"label": "የኢሜል አድራሻ"
|
||||
}
|
||||
},
|
||||
"heading": "የይለፍ ቃልዎን ረሱ?",
|
||||
"help-text": "መለያው ካለ የይለፍ ቃልዎን እንደገና ለማስጀመር የሚያስችል ኢሜል ይደርስዎታል።"
|
||||
},
|
||||
"login": {
|
||||
"actions": {
|
||||
"login": "ግባ"
|
||||
},
|
||||
"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 ሰነድ</1> ካለዎት በReactive Resume ላይ ስራዎን ለማፋጠን ሊጠቀሙበት ይችላሉ። ከታች ያለውን አዝራር በመጫን የሚሰራ JSON ፋይል ይስቀሉ።",
|
||||
"heading": "ከ JSON ሰነድ"
|
||||
},
|
||||
"linkedin": {
|
||||
"actions": {
|
||||
"upload-archive": "የ ZIP ማህደር ስቀል"
|
||||
},
|
||||
"body": "መረጃዎን ከ LinkedIn ወደ በመላክ እና Reactive Resume ላይ በራስ-ሙላ መስኮችን በመጠቀም ጊዜ መቆጠብ ይችላሉ። በ LinkedIn ላይ ወደ <1>የመረጃ ግላዊነት</1> ክፍል ይሂዱ እና የመረጃ ማህደርዎን ይጠይቁ። ከተገኘ በኋላ፣ ከታች በሚገኘው የ ZIP ፋይሉን ይስቀሉ።",
|
||||
"heading": "ከ LinkedIn ስቀል"
|
||||
},
|
||||
"reactive-resume": {
|
||||
"actions": {
|
||||
"upload-json": "JSON ስቀል",
|
||||
"upload-json-v2": "JSON v2 ይስቀሉ።"
|
||||
},
|
||||
"body": "አሁን ካለው Reactive Resume ስሪት ጋር ወደ ውጭ የተላከ JSON ካለዎት፣ እንደገና ሊስተካከል የሚችል ስሪት ለማግኘት ወደዚህ መልሰው ማስገባት ይችላሉ።",
|
||||
"heading": "ከ Reactive Resume ስቀል"
|
||||
}
|
||||
},
|
||||
"rename-resume": {
|
||||
"actions": {
|
||||
"rename-resume": "የስራ ታሪክ ሰነዱን ደግመው ይሰይሙ"
|
||||
},
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "ስም"
|
||||
},
|
||||
"slug": {
|
||||
"label": "ማስፈንጥሪያ"
|
||||
}
|
||||
},
|
||||
"heading": "የስራ ታሪክ ሰነዱን ደግመው ይሰይሙ"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -270,6 +270,7 @@
|
||||
"heading": "تبرع الى Reactive Resume"
|
||||
},
|
||||
"github": "الشفرة المصدرية",
|
||||
"docs": "توثيق",
|
||||
"heading": "الروابط"
|
||||
},
|
||||
"settings": {
|
||||
@ -289,6 +290,10 @@
|
||||
},
|
||||
"heading": "الإعدادات",
|
||||
"page": {
|
||||
"format": {
|
||||
"primary": "حجم الورق",
|
||||
"secondary": "تحدد أبعاد صفحات سيرتك الذاتية"
|
||||
},
|
||||
"break-line": {
|
||||
"primary": "خط فاصل",
|
||||
"secondary": "اعرض خط في كل الصفحات لتحديد ارتفاع صفحة A4"
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
"links": {
|
||||
"donate": "تبرّع",
|
||||
"github": "الشفرة المصدرية",
|
||||
"docs": "توثيق",
|
||||
"privacy": "سياسة الخصوصية",
|
||||
"service": "شروط الإستخدام"
|
||||
}
|
||||
|
||||
@ -270,6 +270,7 @@
|
||||
"heading": "Направи дарение и подкрепи Reactive Resume"
|
||||
},
|
||||
"github": "Програмен код",
|
||||
"docs": "Документация",
|
||||
"heading": "Връзки"
|
||||
},
|
||||
"settings": {
|
||||
@ -289,6 +290,10 @@
|
||||
},
|
||||
"heading": "Настройки",
|
||||
"page": {
|
||||
"format": {
|
||||
"primary": "Размер на хартията",
|
||||
"secondary": "Определя размерите на вашите страници с автобиография"
|
||||
},
|
||||
"break-line": {
|
||||
"primary": "Линия на прекъсване",
|
||||
"secondary": "Показване на линия на всички страници за обозначаване на височината на страница A4"
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
"links": {
|
||||
"donate": "Дарение",
|
||||
"github": "Програмен код",
|
||||
"docs": "Документация",
|
||||
"privacy": "Политика за поверителност",
|
||||
"service": "Условия на ползване"
|
||||
}
|
||||
|
||||
@ -270,6 +270,7 @@
|
||||
"heading": "Reactive Resume -তে দান করুন"
|
||||
},
|
||||
"github": "সোর্স কোড",
|
||||
"docs": "ডকুমেন্টেশন",
|
||||
"heading": "লিঙ্ক"
|
||||
},
|
||||
"settings": {
|
||||
@ -289,6 +290,10 @@
|
||||
},
|
||||
"heading": "সেটিংস",
|
||||
"page": {
|
||||
"format": {
|
||||
"primary": "কাগজের আকার",
|
||||
"secondary": "আপনার জীবনবৃত্তান্ত পৃষ্ঠাগুলির মাত্রা নির্ধারণ করে"
|
||||
},
|
||||
"break-line": {
|
||||
"primary": "লাইন ভেঙ্গে ফেলুন",
|
||||
"secondary": "একটি A4 পৃষ্ঠার উচ্চতা চিহ্নিত করতে সমস্ত পৃষ্ঠায় একটি লাইন দেখান৷"
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
"links": {
|
||||
"donate": "দান করুন",
|
||||
"github": "সোর্স কোড",
|
||||
"docs": "ডকুমেন্টেশন",
|
||||
"privacy": "গোপনীয়তা নীতি",
|
||||
"service": "সেবা পাবার শর্ত"
|
||||
}
|
||||
|
||||
@ -270,6 +270,7 @@
|
||||
"heading": "Dona a Reactive Curriculum vitae"
|
||||
},
|
||||
"github": "Codi font",
|
||||
"docs": "Documentació",
|
||||
"heading": "Enllaços"
|
||||
},
|
||||
"settings": {
|
||||
@ -289,6 +290,10 @@
|
||||
},
|
||||
"heading": "Configuració",
|
||||
"page": {
|
||||
"format": {
|
||||
"primary": "Mida del paper",
|
||||
"secondary": "Determina les dimensions de les pàgines del vostre currículum"
|
||||
},
|
||||
"break-line": {
|
||||
"primary": "Línia de trencament",
|
||||
"secondary": "Mostra una línia a totes les pàgines per marcar l'alçada d'una pàgina A4"
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
"links": {
|
||||
"donate": "Donar",
|
||||
"github": "Codi font",
|
||||
"docs": "Documentació",
|
||||
"privacy": "Política de privacitat",
|
||||
"service": "Termes del servei"
|
||||
}
|
||||
|
||||
@ -270,6 +270,7 @@
|
||||
"heading": "Přispějte na Reactive Resume"
|
||||
},
|
||||
"github": "Zdrojový kód",
|
||||
"docs": "Dokumentace",
|
||||
"heading": "Odkazy"
|
||||
},
|
||||
"settings": {
|
||||
@ -289,6 +290,10 @@
|
||||
},
|
||||
"heading": "Nastavení",
|
||||
"page": {
|
||||
"format": {
|
||||
"primary": "Velikost papíru",
|
||||
"secondary": "Určuje rozměry stránek vašeho životopisu"
|
||||
},
|
||||
"break-line": {
|
||||
"primary": "Nový řádek",
|
||||
"secondary": "Zobrazit čáru na všech stránkách pro označení výšky stránky A4"
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
"links": {
|
||||
"donate": "Darovat",
|
||||
"github": "Zdrojový kód",
|
||||
"docs": "Dokumentace",
|
||||
"privacy": "Zásady ochrany osobních údajů",
|
||||
"service": "Podmínky služby"
|
||||
}
|
||||
|
||||
@ -270,6 +270,7 @@
|
||||
"heading": "Donér til Reactive Resume"
|
||||
},
|
||||
"github": "Kildekode",
|
||||
"docs": "Dokumentation",
|
||||
"heading": "Links"
|
||||
},
|
||||
"settings": {
|
||||
@ -289,6 +290,10 @@
|
||||
},
|
||||
"heading": "Indstillinger",
|
||||
"page": {
|
||||
"format": {
|
||||
"primary": "Papirstørrelse",
|
||||
"secondary": "Bestemmer dimensionerne på dine CV-sider"
|
||||
},
|
||||
"break-line": {
|
||||
"primary": "Brudlinje",
|
||||
"secondary": "Vis en streg på alle sider for at markere højden på en A4-side"
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
"links": {
|
||||
"donate": "Donér",
|
||||
"github": "Kildekode",
|
||||
"docs": "Dokumentation",
|
||||
"privacy": "Fortrolighedspolitik",
|
||||
"service": "Servicevilkår"
|
||||
}
|
||||
|
||||
@ -270,6 +270,7 @@
|
||||
"heading": "Spenden an Reaktives Lebenslauf"
|
||||
},
|
||||
"github": "Quellcode",
|
||||
"docs": "Dokumentation",
|
||||
"heading": "Links"
|
||||
},
|
||||
"settings": {
|
||||
@ -289,6 +290,10 @@
|
||||
},
|
||||
"heading": "Einstellungen",
|
||||
"page": {
|
||||
"format": {
|
||||
"primary": "Papier größe",
|
||||
"secondary": "Legt die Abmessungen Ihrer Lebenslaufseiten fest"
|
||||
},
|
||||
"break-line": {
|
||||
"primary": "Linie anhalten",
|
||||
"secondary": "Zeile auf allen Seiten anzeigen, um die Höhe einer A4-Seite zu markieren"
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
"links": {
|
||||
"donate": "Spenden",
|
||||
"github": "Quellcode",
|
||||
"docs": "Dokumentation",
|
||||
"privacy": "Datenschutzerklärung",
|
||||
"service": "Nutzungsbedingungen"
|
||||
}
|
||||
|
||||
@ -270,6 +270,7 @@
|
||||
"heading": "Κάντε δωρεά στο Reactive βιογραφικό"
|
||||
},
|
||||
"github": "Πηγαίος κώδικας",
|
||||
"docs": "Τεκμηρίωση",
|
||||
"heading": "Σύνδεσμοι"
|
||||
},
|
||||
"settings": {
|
||||
@ -289,6 +290,10 @@
|
||||
},
|
||||
"heading": "Ρυθμίσεις",
|
||||
"page": {
|
||||
"format": {
|
||||
"primary": "Μέγεθος χαρτιού",
|
||||
"secondary": "Καθορίζει τις διαστάσεις των σελίδων του βιογραφικού σας"
|
||||
},
|
||||
"break-line": {
|
||||
"primary": "Γραμμή διακοπής",
|
||||
"secondary": "Εμφάνιση μιας γραμμής σε όλες τις σελίδες για να επισημάνετε το ύψος μιας σελίδας Α4"
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
"links": {
|
||||
"donate": "Δωρεά",
|
||||
"github": "Πηγαίος Κώδικας",
|
||||
"docs": "Τεκμηρίωση",
|
||||
"privacy": "Πολιτική Απορρήτου",
|
||||
"service": "Όρους παροχής υπηρεσιών"
|
||||
}
|
||||
|
||||
@ -3,7 +3,8 @@
|
||||
"actions": {
|
||||
"add": "Add New {{token}}",
|
||||
"delete": "Delete {{token}}",
|
||||
"edit": "Edit {{token}}"
|
||||
"edit": "Edit {{token}}",
|
||||
"duplicate": "Duplicate Section"
|
||||
},
|
||||
"columns": {
|
||||
"heading": "Columns",
|
||||
@ -244,7 +245,7 @@
|
||||
"pdf": {
|
||||
"loading": {
|
||||
"primary": "Generating PDF",
|
||||
"secondary": "Please wait as your PDF gets generated, this may take upto 15 seconds."
|
||||
"secondary": "Please wait as your PDF gets generated, this may take up to 15 seconds."
|
||||
},
|
||||
"normal": {
|
||||
"primary": "PDF",
|
||||
@ -270,6 +271,7 @@
|
||||
"heading": "Donate to Reactive Resume"
|
||||
},
|
||||
"github": "Source Code",
|
||||
"docs": "Documentation",
|
||||
"heading": "Links"
|
||||
},
|
||||
"settings": {
|
||||
@ -289,6 +291,10 @@
|
||||
},
|
||||
"heading": "Settings",
|
||||
"page": {
|
||||
"format": {
|
||||
"primary": "Paper Size",
|
||||
"secondary": "Determines the dimensions of your resume pages"
|
||||
},
|
||||
"break-line": {
|
||||
"primary": "Break Line",
|
||||
"secondary": "Show a line on all pages to mark the height of an A4 page"
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
"toast": {
|
||||
"error": {
|
||||
"upload-file-size": "Please upload only files under 2 megabytes.",
|
||||
"upload-photo-size": "Please upload only photos under 2 megabytes, preferrably square."
|
||||
"upload-photo-size": "Please upload only photos under 2 megabytes, preferably square."
|
||||
},
|
||||
"success": {
|
||||
"resume-link-copied": "A link to your resume has been copied to your clipboard."
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
"links": {
|
||||
"donate": "Donate",
|
||||
"github": "Source Code",
|
||||
"docs": "Documentation",
|
||||
"privacy": "Privacy Policy",
|
||||
"service": "Terms of Service"
|
||||
}
|
||||
|
||||
@ -270,6 +270,7 @@
|
||||
"heading": "Donar a Reactive Resume"
|
||||
},
|
||||
"github": "Código Fuente",
|
||||
"docs": "Documentación",
|
||||
"heading": "Enlaces"
|
||||
},
|
||||
"settings": {
|
||||
@ -289,6 +290,10 @@
|
||||
},
|
||||
"heading": "Preferencias",
|
||||
"page": {
|
||||
"format": {
|
||||
"primary": "Tamaño de papel",
|
||||
"secondary": "Determina las dimensiones de las páginas de tu currículum."
|
||||
},
|
||||
"break-line": {
|
||||
"primary": "Linea de separación",
|
||||
"secondary": "Mostrar una línea en todas las páginas para marcar la altura de una página A4"
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
"links": {
|
||||
"donate": "Donar",
|
||||
"github": "Código fuente",
|
||||
"docs": "Documentación",
|
||||
"privacy": "Política de Privacidad",
|
||||
"service": "Términos de Servicio"
|
||||
}
|
||||
|
||||
@ -270,6 +270,7 @@
|
||||
"heading": "کمک مالی به Reactive Resume"
|
||||
},
|
||||
"github": "کد منبع",
|
||||
"docs": "مستندات",
|
||||
"heading": "لینکها"
|
||||
},
|
||||
"settings": {
|
||||
@ -289,6 +290,10 @@
|
||||
},
|
||||
"heading": "تنظیمات",
|
||||
"page": {
|
||||
"format": {
|
||||
"primary": "اندازه کاغذ",
|
||||
"secondary": "ابعاد صفحات رزومه شما را تعیین می کند"
|
||||
},
|
||||
"break-line": {
|
||||
"primary": "خط شکست",
|
||||
"secondary": "برای مشخص کردن ارتفاع صفحه A4 یک خط در همه صفحات نشان داده شود"
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
"links": {
|
||||
"donate": "حمایت مالی",
|
||||
"github": "کد منبع",
|
||||
"docs": "مستندات",
|
||||
"privacy": "حریم خصوصی",
|
||||
"service": "شرایط سرویسدهی"
|
||||
}
|
||||
|
||||
@ -270,6 +270,7 @@
|
||||
"heading": "Lahjoita Reaktiiviselle ansioluettelolle"
|
||||
},
|
||||
"github": "Lähdekoodi",
|
||||
"docs": "Dokumentaatio",
|
||||
"heading": "Linkit"
|
||||
},
|
||||
"settings": {
|
||||
@ -289,6 +290,10 @@
|
||||
},
|
||||
"heading": "Asetukset",
|
||||
"page": {
|
||||
"format": {
|
||||
"primary": "Paperikoko",
|
||||
"secondary": "Määrittää ansioluettelosi sivujen mitat"
|
||||
},
|
||||
"break-line": {
|
||||
"primary": "Katkoviiva",
|
||||
"secondary": "Näytä viiva kaikilla sivuilla A4-sivun korkeuden merkitsemiseksi"
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
"links": {
|
||||
"donate": "Lahjoita",
|
||||
"github": "Lähdekoodi",
|
||||
"docs": "Dokumentaatio",
|
||||
"privacy": "Tietosuojakäytäntö",
|
||||
"service": "Käyttöehdot"
|
||||
}
|
||||
|
||||
@ -270,6 +270,7 @@
|
||||
"heading": "Faire un don à Reactive Resume"
|
||||
},
|
||||
"github": "Code source",
|
||||
"docs": "Documentation",
|
||||
"heading": "Liens"
|
||||
},
|
||||
"settings": {
|
||||
@ -289,6 +290,10 @@
|
||||
},
|
||||
"heading": "Paramètres",
|
||||
"page": {
|
||||
"format": {
|
||||
"primary": "Taille de papier",
|
||||
"secondary": "Détermine les dimensions de vos pages de CV"
|
||||
},
|
||||
"break-line": {
|
||||
"primary": "Indicateur de changement de page",
|
||||
"secondary": "Afficher une ligne sur toutes les pages pour marquer la hauteur d'une feuille A4"
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
"links": {
|
||||
"donate": "Faire un don",
|
||||
"github": "Code source",
|
||||
"docs": "Documentation",
|
||||
"privacy": "Politique de confidentialité",
|
||||
"service": "Conditions d'utilisation"
|
||||
}
|
||||
|
||||
@ -270,6 +270,7 @@
|
||||
"heading": "תרומה לקורות חיים ריאקטיביים"
|
||||
},
|
||||
"github": "קוד מקור",
|
||||
"docs": "תיעוד",
|
||||
"heading": "קישורים"
|
||||
},
|
||||
"settings": {
|
||||
@ -289,6 +290,10 @@
|
||||
},
|
||||
"heading": "הגדרות",
|
||||
"page": {
|
||||
"format": {
|
||||
"primary": "גודל נייר",
|
||||
"secondary": "קובע את הממדים של דפי קורות החיים שלך"
|
||||
},
|
||||
"break-line": {
|
||||
"primary": "קו עצירה",
|
||||
"secondary": "הצג קו בכל הדפים כדי לסמן את גובהו של דף A4"
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
"links": {
|
||||
"donate": "לִתְרוֹם",
|
||||
"github": "קוד מקור",
|
||||
"docs": "תיעוד",
|
||||
"privacy": "מדיניות פרטיות",
|
||||
"service": "תנאי השירות"
|
||||
}
|
||||
|
||||
@ -270,6 +270,7 @@
|
||||
"heading": "प्रतिक्रियाशील फिर से शुरू करने के लिए दान करें"
|
||||
},
|
||||
"github": "सोर्स कोड",
|
||||
"docs": "प्रलेखन",
|
||||
"heading": "लिंक"
|
||||
},
|
||||
"settings": {
|
||||
@ -289,6 +290,10 @@
|
||||
},
|
||||
"heading": "समायोजन",
|
||||
"page": {
|
||||
"format": {
|
||||
"primary": "काग़ज़ का आकार",
|
||||
"secondary": "आपके रेज़्यूमे पृष्ठों के आयाम निर्धारित करता है"
|
||||
},
|
||||
"break-line": {
|
||||
"primary": "अंतराल वाली लकीर",
|
||||
"secondary": "A4 पृष्ठ की ऊंचाई को चिह्नित करने के लिए सभी पृष्ठों पर एक पंक्ति दिखाएं"
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
"links": {
|
||||
"donate": "दान करना",
|
||||
"github": "सोर्स कोड",
|
||||
"docs": "प्रलेखन",
|
||||
"privacy": "गोपनीयता नीति",
|
||||
"service": "सेवा की शर्तें"
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"common": {
|
||||
"actions": {
|
||||
"add": "Új hozzáadása {{token}}",
|
||||
"add": "Új {{token}} hozzáadása",
|
||||
"delete": "{{token}} törlése",
|
||||
"edit": "{{token}} szerkesztése"
|
||||
},
|
||||
@ -20,7 +20,7 @@
|
||||
"label": "E-mail cím"
|
||||
},
|
||||
"end-date": {
|
||||
"help-text": "Hagyja üresen ezt a mezőt, ha még mindig tart van",
|
||||
"help-text": "Hagyja üresen ezt a mezőt, ha még folyamatban van",
|
||||
"label": "Befejezés dátuma"
|
||||
},
|
||||
"keywords": {
|
||||
@ -51,7 +51,7 @@
|
||||
"label": "Összegzés"
|
||||
},
|
||||
"title": {
|
||||
"label": "Cím"
|
||||
"label": "Titulus"
|
||||
},
|
||||
"url": {
|
||||
"label": "Honlap"
|
||||
@ -63,30 +63,30 @@
|
||||
"list": {
|
||||
"actions": {
|
||||
"delete": "Törlés",
|
||||
"duplicate": "Duplikálás",
|
||||
"duplicate": "Másolás",
|
||||
"edit": "Szerkesztés"
|
||||
},
|
||||
"empty-text": "Ez a lista üres."
|
||||
},
|
||||
"tooltip": {
|
||||
"delete-item": "Biztosan törli ezt az elemet? Ez egy visszafordíthatatlan művelet.",
|
||||
"delete-item": "Biztosan törli ezt az elemet? Ez a művelet nem visszavonható.",
|
||||
"delete-section": "Szakasz törlése",
|
||||
"rename-section": "Szakasz átnevezése",
|
||||
"toggle-visibility": "Láthatóság váltása"
|
||||
"toggle-visibility": "Láthatóság ki/be"
|
||||
}
|
||||
},
|
||||
"controller": {
|
||||
"tooltip": {
|
||||
"center-artboard": "Központi rajztábla",
|
||||
"copy-link": "Link másolása az önéletrajzba",
|
||||
"copy-link": "Önéletrajz link másolása",
|
||||
"export-pdf": "Exportálás PDF-be",
|
||||
"toggle-orientation": "Oldaltájolás váltása",
|
||||
"toggle-page-break-line": "Oldaltörés vonal váltása",
|
||||
"toggle-sidebars": "Az oldalsávok váltása",
|
||||
"toggle-orientation": "Oldaltájolás",
|
||||
"toggle-page-break-line": "Oldaltörés vonal ki/be",
|
||||
"toggle-sidebars": "Oldalsávok ki/be",
|
||||
"zoom-in": "Nagyítás",
|
||||
"zoom-out": "Kicsinyítés",
|
||||
"undo": "Undo",
|
||||
"redo": "Redo"
|
||||
"undo": "Visszavonás",
|
||||
"redo": "Mégis"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
@ -96,7 +96,7 @@
|
||||
"rename": "Átnevezés",
|
||||
"share-link": "Link megosztása",
|
||||
"tooltips": {
|
||||
"delete": "Biztos, hogy törölni szeretné ezt az önéletrajzot? Ez egy visszafordíthatatlan művelet.",
|
||||
"delete": "Biztos, hogy törölni szeretné ezt az önéletrajzot? Ez a művelet nem visszavonható.",
|
||||
"share-link": "Az önéletrajz láthatóságát nyilvánosra kell változtatnia, hogy mások számára is látható legyen."
|
||||
}
|
||||
}
|
||||
@ -138,7 +138,7 @@
|
||||
"heading": "Alak"
|
||||
},
|
||||
"size": {
|
||||
"heading": "Méret (px-ben)"
|
||||
"heading": "Méret (pixel)"
|
||||
}
|
||||
},
|
||||
"photo-upload": {
|
||||
@ -189,7 +189,7 @@
|
||||
"label": "Irányítószám"
|
||||
},
|
||||
"region": {
|
||||
"label": "Vidék"
|
||||
"label": "Régió"
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
@ -248,7 +248,7 @@
|
||||
},
|
||||
"normal": {
|
||||
"primary": "PDF",
|
||||
"secondary": "Töltse le önéletrajzának PDF formátumát, amelyet kinyomtathat és elküldhet álmai munkahelyére. Ez a fájl nem importálható vissza további szerkesztéshez."
|
||||
"secondary": "Töltse le önéletrajzát PDF formátumban, amelyet kinyomtathat és elküldhet álmai munkahelyére. Ez a fájl nem importálható vissza további szerkesztéshez."
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -265,23 +265,24 @@
|
||||
"heading": "Hibák? Funkciókérés?"
|
||||
},
|
||||
"donate": {
|
||||
"body": "Ha tetszett a Reactive Resume, kérjük, fontolja meg, hogy amennyit csak tud, adományozzon arra, hogy az alkalmazás folyamatosan működjön, hirdetések nélkül és örökké ingyenesen.",
|
||||
"body": "Ha elégedett a Reactive Resume alkalmazással, kérjük, fontolja meg, hogy tetszőleges összeggel támogassa munkánkat, hogy továbbra is ingyenes és hirdetésmentes lehessen.",
|
||||
"button": "Vegyél nekem egy kávét",
|
||||
"heading": "Adományozzon a Reactive Resume-nak"
|
||||
},
|
||||
"github": "Forráskód",
|
||||
"docs": "Dokumentáció",
|
||||
"heading": "Linkek"
|
||||
},
|
||||
"settings": {
|
||||
"global": {
|
||||
"date": {
|
||||
"primary": "Dátum",
|
||||
"secondary": "Az alkalmazásban használható dátumformátum"
|
||||
"secondary": "Az alkalmazásban használt dátumformátum"
|
||||
},
|
||||
"heading": "Globális",
|
||||
"language": {
|
||||
"primary": "Nyelv",
|
||||
"secondary": "Az alkalmazásban használható megjelenítési nyelv"
|
||||
"secondary": "Az alkalmazásban használt megjelenítési nyelv"
|
||||
},
|
||||
"theme": {
|
||||
"primary": "Téma"
|
||||
@ -289,6 +290,10 @@
|
||||
},
|
||||
"heading": "Beállítások",
|
||||
"page": {
|
||||
"format": {
|
||||
"primary": "Papírméret",
|
||||
"secondary": "Meghatározza az önéletrajz oldalméreteit"
|
||||
},
|
||||
"break-line": {
|
||||
"primary": "Törésvonal",
|
||||
"secondary": "Mutasson egy vonalat az összes oldalon, hogy megjelölje egy A4-es oldal magasságát"
|
||||
@ -296,7 +301,7 @@
|
||||
"heading": "oldal",
|
||||
"orientation": {
|
||||
"disabled": "Nincs hatása, ha csak egy oldal van",
|
||||
"primary": "Irányultság",
|
||||
"primary": "Tájolás",
|
||||
"secondary": "Az oldalak vízszintes vagy függőleges megjelenítése"
|
||||
}
|
||||
},
|
||||
@ -315,7 +320,7 @@
|
||||
"sharing": {
|
||||
"heading": "Megosztás",
|
||||
"short-url": {
|
||||
"label": "Rövid URL-t részesítsen előnyben"
|
||||
"label": "Rövid URL előnyben részesítése"
|
||||
},
|
||||
"visibility": {
|
||||
"subtitle": "A link birtokában bárki megtekintheti önéletrajzát",
|
||||
@ -331,7 +336,7 @@
|
||||
"label": "Háttér"
|
||||
},
|
||||
"primary": {
|
||||
"label": "Elsődleges"
|
||||
"label": "Elsődleges "
|
||||
},
|
||||
"text": {
|
||||
"label": "Szöveg"
|
||||
@ -351,7 +356,7 @@
|
||||
"heading": "Tipográfia",
|
||||
"widgets": {
|
||||
"body": {
|
||||
"label": "Test"
|
||||
"label": "Szövegtörzs"
|
||||
},
|
||||
"headings": {
|
||||
"label": "Címsorok"
|
||||
|
||||
@ -6,14 +6,14 @@
|
||||
}
|
||||
},
|
||||
"footer": {
|
||||
"credit": "<1>Amruth Pillai szenvedélyes projektje</1>",
|
||||
"credit": "<1>Amruth Pillai hobbi projektje</1>",
|
||||
"license": "A közösség által, a közösségért."
|
||||
},
|
||||
"markdown": {
|
||||
"help-text": "Ez a szakasz támogatja a <1>markdown</1> formázást."
|
||||
},
|
||||
"date": {
|
||||
"present": "Ajándék"
|
||||
"present": "Jelenleg is"
|
||||
},
|
||||
"subtitle": "Ingyenes és nyílt forráskódú önéletrajzkészítő.",
|
||||
"title": "Reactive Resume",
|
||||
|
||||
@ -4,18 +4,18 @@
|
||||
"title": "Új önéletrajz létrehozása"
|
||||
},
|
||||
"import-external": {
|
||||
"subtitle": "LinkedIn, JSON önéletrajz, reaktív önéletrajz",
|
||||
"subtitle": "LinkedIn, JSON önéletrajz, Reactive Resume",
|
||||
"title": "Importálás külső forrásokból"
|
||||
},
|
||||
"resume": {
|
||||
"menu": {
|
||||
"delete": "Törlés",
|
||||
"duplicate": "Másolat",
|
||||
"open": "Nyisd ki",
|
||||
"open": "Megnyitás",
|
||||
"rename": "Átnevezés",
|
||||
"share-link": "Link megosztása",
|
||||
"tooltips": {
|
||||
"delete": "Biztos, hogy törölni szeretné ezt az önéletrajzot? Ez egy visszafordíthatatlan művelet.",
|
||||
"delete": "Biztos, hogy törölni szeretné ezt az önéletrajzot? Ez a művelet nem visszavonható.",
|
||||
"share-link": "Az önéletrajz láthatóságát nyilvánosra kell változtatnia, hogy mások számára is látható legyen."
|
||||
}
|
||||
},
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"actions": {
|
||||
"app": "Lépjen az App",
|
||||
"app": "Alkalmazás indítása",
|
||||
"login": "Belépés",
|
||||
"logout": "Kijelentkezés",
|
||||
"register": "Regisztráció"
|
||||
@ -8,7 +8,7 @@
|
||||
"features": {
|
||||
"heading": "Jellemzők",
|
||||
"list": {
|
||||
"ads": "Nincs reklám",
|
||||
"ads": "Reklámmentes",
|
||||
"export": "Exportálja önéletrajzát JSON vagy PDF formátumba",
|
||||
"free": "Ingyenes, örökre",
|
||||
"import": "Adatok importálása a LinkedInből, JSON Resume",
|
||||
@ -20,10 +20,11 @@
|
||||
"links": {
|
||||
"heading": "Linkek",
|
||||
"links": {
|
||||
"donate": "Adományoz",
|
||||
"donate": "Adományozás",
|
||||
"github": "Forráskód",
|
||||
"docs": "Dokumentáció",
|
||||
"privacy": "Adatvédelmi irányelvek",
|
||||
"service": "Szolgáltatási feltételek"
|
||||
"service": "Felhasználói feltételek"
|
||||
}
|
||||
},
|
||||
"screenshots": {
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
"auth": {
|
||||
"forgot-password": {
|
||||
"actions": {
|
||||
"send-email": "Jelszó visszaállítása e-mail küldése"
|
||||
"send-email": "Jelszó helyreállító e-mail küldése"
|
||||
},
|
||||
"body": "Csak adja meg a helyreállítani kívánt fiókhoz társított e-mail címet.",
|
||||
"form": {
|
||||
@ -27,14 +27,14 @@
|
||||
"label": "Felhasználónév"
|
||||
}
|
||||
},
|
||||
"heading": "Jelentkezz be a fiókodba",
|
||||
"heading": "Jelentkezzen be a fiókjába",
|
||||
"recover-text": "Ha elfelejtette jelszavát, <1>visszaállíthatja fiókját</1> itt.",
|
||||
"register-text": "Ha nem rendelkezik fiókkal, <1>létrehozhat egy fiókot</1> itt."
|
||||
},
|
||||
"register": {
|
||||
"actions": {
|
||||
"register": "Regisztráció",
|
||||
"google": "Regisztráljon a Google-nál"
|
||||
"google": "Regisztráljon Google fiókkal"
|
||||
},
|
||||
"body": "Kérjük, adja meg személyes adatait fiók létrehozásához.",
|
||||
"form": {
|
||||
@ -87,7 +87,7 @@
|
||||
"label": "Nyilvánosan elérhető?"
|
||||
},
|
||||
"slug": {
|
||||
"label": "Meztelen csiga"
|
||||
"label": "Saját URL"
|
||||
}
|
||||
},
|
||||
"heading": "Új önéletrajz létrehozása"
|
||||
@ -126,7 +126,7 @@
|
||||
"label": "Név"
|
||||
},
|
||||
"slug": {
|
||||
"label": "Meztelen csiga"
|
||||
"label": "Saját URL"
|
||||
}
|
||||
},
|
||||
"heading": "Nevezze át önéletrajzát"
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
"label": "Tanggal"
|
||||
},
|
||||
"description": {
|
||||
"label": "Keterangan"
|
||||
"label": "Deskripsi"
|
||||
},
|
||||
"email": {
|
||||
"label": "Alamat Email"
|
||||
@ -130,7 +130,7 @@
|
||||
"label": "Batas"
|
||||
},
|
||||
"grayscale": {
|
||||
"label": "Grayscale"
|
||||
"label": "Tingkat keabuan"
|
||||
},
|
||||
"heading": "Efek"
|
||||
},
|
||||
@ -138,7 +138,7 @@
|
||||
"heading": "Bentuk"
|
||||
},
|
||||
"size": {
|
||||
"heading": "Besar (dalam px)"
|
||||
"heading": "Ukuran (dalam px)"
|
||||
}
|
||||
},
|
||||
"photo-upload": {
|
||||
@ -158,7 +158,7 @@
|
||||
"education": {
|
||||
"form": {
|
||||
"area-study": {
|
||||
"label": "Area belajar"
|
||||
"label": "Bidang Studi"
|
||||
},
|
||||
"courses": {
|
||||
"label": "Kursus"
|
||||
@ -170,7 +170,7 @@
|
||||
"label": "Tingkatan"
|
||||
},
|
||||
"institution": {
|
||||
"label": "Lembaga"
|
||||
"label": "Institusi"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -270,6 +270,7 @@
|
||||
"heading": "Donasi ke Reactive Resume"
|
||||
},
|
||||
"github": "Kode sumber",
|
||||
"docs": "Dokumentasi",
|
||||
"heading": "Link"
|
||||
},
|
||||
"settings": {
|
||||
@ -289,6 +290,10 @@
|
||||
},
|
||||
"heading": "Pengaturan",
|
||||
"page": {
|
||||
"format": {
|
||||
"primary": "Ukuran kertas",
|
||||
"secondary": "Menentukan dimensi halaman resume Anda"
|
||||
},
|
||||
"break-line": {
|
||||
"primary": "Break Line",
|
||||
"secondary": "Tampilkan garis di semua halaman untuk menandai ketinggian halaman A4"
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
"links": {
|
||||
"donate": "Donasi",
|
||||
"github": "Kode Sumber",
|
||||
"docs": "Dokumentasi",
|
||||
"privacy": "Kebijakan Pribadi",
|
||||
"service": "Persyaratan Layanan"
|
||||
}
|
||||
|
||||
@ -270,6 +270,7 @@
|
||||
"heading": "Dona a Reactive Resume"
|
||||
},
|
||||
"github": "Codice sorgente",
|
||||
"docs": "Documentazione",
|
||||
"heading": "Link"
|
||||
},
|
||||
"settings": {
|
||||
@ -289,6 +290,10 @@
|
||||
},
|
||||
"heading": "Impostazioni",
|
||||
"page": {
|
||||
"format": {
|
||||
"primary": "Dimensioni del foglio",
|
||||
"secondary": "Determina le dimensioni delle pagine del tuo curriculum"
|
||||
},
|
||||
"break-line": {
|
||||
"primary": "Linea di interruzione",
|
||||
"secondary": "Mostra su tutte le pagine una linea che indica l'altezza di un foglio A4"
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
"links": {
|
||||
"donate": "Dona",
|
||||
"github": "Codice sorgente",
|
||||
"docs": "Documentazione",
|
||||
"privacy": "Informativa sulla privacy",
|
||||
"service": "Condizioni d'uso"
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user