Compare commits

..
14 Commits
Author SHA1 Message Date
Amruth Pillai bcbe70d231 📦 v5.0.16 - https://docs.rxresu.me/changelog 2026-04-04 12:31:24 +02:00
Amruth Pillai 8b52b9d8fc update translations 2026-04-04 12:29:10 +02:00
Amruth Pillai 4ecc66d081 Update title/metadata of generated PDF (#2863) 2026-04-04 12:28:32 +02:00
Amruth Pillai 10d58175f1 refactor: update layout of resume items for better alignment and spacing 2026-04-04 12:21:05 +02:00
Amruth Pillai 923f5f6173 fixes #2733: Bug where date range is displayed on separate line (#2862) 2026-04-04 12:03:09 +02:00
Amruth Pillai 9332e1e3ff chore: update GitHub Actions workflows to use Node 24 and upgrade action versions 2026-04-02 00:28:36 +02:00
AaronJoel Dev 77f31fa127 fix: prevent desktop horizontal overflow in home hero (#2854) 2026-04-02 00:16:16 +02:00
Amruth Pillai 4fd43657dc 📦 v5.0.15 - https://docs.rxresu.me/changelog 2026-04-02 00:14:54 +02:00
Aman Gupta d9a24448e8 fix: refactor useCSSVariables to ensure valid highest font weights (#2852) 2026-03-31 22:41:24 +02:00
Amruth Pillai 69ff78b656 Sync Translations from Crowdin (#2848)
* New translations en-us.po (Romanian)
[ci skip]

* New translations en-us.po (French)
[ci skip]

* New translations en-us.po (Spanish)
[ci skip]

* New translations en-us.po (Afrikaans)
[ci skip]

* New translations en-us.po (Arabic)
[ci skip]

* New translations en-us.po (Bulgarian)
[ci skip]

* New translations en-us.po (Catalan)
[ci skip]

* New translations en-us.po (Czech)
[ci skip]

* New translations en-us.po (Danish)
[ci skip]

* New translations en-us.po (German)
[ci skip]

* New translations en-us.po (Greek)
[ci skip]

* New translations en-us.po (Finnish)
[ci skip]

* New translations en-us.po (Hebrew)
[ci skip]

* New translations en-us.po (Hungarian)
[ci skip]

* New translations en-us.po (Italian)
[ci skip]

* New translations en-us.po (Japanese)
[ci skip]

* New translations en-us.po (Korean)
[ci skip]

* New translations en-us.po (Lithuanian)
[ci skip]

* New translations en-us.po (Dutch)
[ci skip]

* New translations en-us.po (Norwegian)
[ci skip]

* New translations en-us.po (Polish)
[ci skip]

* New translations en-us.po (Portuguese)
[ci skip]

* New translations en-us.po (Russian)
[ci skip]

* New translations en-us.po (Slovak)
[ci skip]

* New translations en-us.po (Slovenian)
[ci skip]

* New translations en-us.po (Albanian)
[ci skip]

* New translations en-us.po (Serbian (Cyrillic))
[ci skip]

* New translations en-us.po (Swedish)
[ci skip]

* New translations en-us.po (Turkish)
[ci skip]

* New translations en-us.po (Ukrainian)
[ci skip]

* New translations en-us.po (Chinese Simplified)
[ci skip]

* New translations en-us.po (Chinese Traditional)
[ci skip]

* New translations en-us.po (Vietnamese)
[ci skip]

* New translations en-us.po (Portuguese, Brazilian)
[ci skip]

* New translations en-us.po (Indonesian)
[ci skip]

* New translations en-us.po (Persian)
[ci skip]

* New translations en-us.po (Khmer)
[ci skip]

* New translations en-us.po (Tamil)
[ci skip]

* New translations en-us.po (Bengali)
[ci skip]

* New translations en-us.po (Marathi)
[ci skip]

* New translations en-us.po (Thai)
[ci skip]

* New translations en-us.po (Latvian)
[ci skip]

* New translations en-us.po (Azerbaijani)
[ci skip]

* New translations en-us.po (Hindi)
[ci skip]

* New translations en-us.po (Malay)
[ci skip]

* New translations en-us.po (Telugu)
[ci skip]

* New translations en-us.po (English, United Kingdom)
[ci skip]

* New translations en-us.po (Malayalam)
[ci skip]

* New translations en-us.po (Uzbek)
[ci skip]

* New translations en-us.po (Kannada)
[ci skip]

* New translations en-us.po (Odia)
[ci skip]

* New translations en-us.po (Amharic)
[ci skip]

* New translations en-us.po (Nepali)
[ci skip]
2026-03-29 23:34:21 +02:00
Amruth Pillai 0794b5c955 update dependencies 2026-03-29 23:09:25 +02:00
Amruth Pillai 5c986cc68d Sync Translations from Crowdin (#2838)
* New translations en-us.po (Romanian)
[ci skip]

* New translations en-us.po (French)
[ci skip]

* New translations en-us.po (Spanish)
[ci skip]

* New translations en-us.po (Afrikaans)
[ci skip]

* New translations en-us.po (Arabic)
[ci skip]

* New translations en-us.po (Bulgarian)
[ci skip]

* New translations en-us.po (Catalan)
[ci skip]

* New translations en-us.po (Czech)
[ci skip]

* New translations en-us.po (Danish)
[ci skip]

* New translations en-us.po (German)
[ci skip]

* New translations en-us.po (Greek)
[ci skip]

* New translations en-us.po (Finnish)
[ci skip]

* New translations en-us.po (Hebrew)
[ci skip]

* New translations en-us.po (Hungarian)
[ci skip]

* New translations en-us.po (Italian)
[ci skip]

* New translations en-us.po (Japanese)
[ci skip]

* New translations en-us.po (Korean)
[ci skip]

* New translations en-us.po (Lithuanian)
[ci skip]

* New translations en-us.po (Dutch)
[ci skip]

* New translations en-us.po (Norwegian)
[ci skip]

* New translations en-us.po (Polish)
[ci skip]

* New translations en-us.po (Portuguese)
[ci skip]

* New translations en-us.po (Russian)
[ci skip]

* New translations en-us.po (Slovak)
[ci skip]

* New translations en-us.po (Slovenian)
[ci skip]

* New translations en-us.po (Albanian)
[ci skip]

* New translations en-us.po (Serbian (Cyrillic))
[ci skip]

* New translations en-us.po (Swedish)
[ci skip]

* New translations en-us.po (Turkish)
[ci skip]

* New translations en-us.po (Ukrainian)
[ci skip]

* New translations en-us.po (Chinese Simplified)
[ci skip]

* New translations en-us.po (Chinese Traditional)
[ci skip]

* New translations en-us.po (Vietnamese)
[ci skip]

* New translations en-us.po (Portuguese, Brazilian)
[ci skip]

* New translations en-us.po (Indonesian)
[ci skip]

* New translations en-us.po (Persian)
[ci skip]

* New translations en-us.po (Khmer)
[ci skip]

* New translations en-us.po (Tamil)
[ci skip]

* New translations en-us.po (Bengali)
[ci skip]

* New translations en-us.po (Marathi)
[ci skip]

* New translations en-us.po (Thai)
[ci skip]

* New translations en-us.po (Latvian)
[ci skip]

* New translations en-us.po (Azerbaijani)
[ci skip]

* New translations en-us.po (Hindi)
[ci skip]

* New translations en-us.po (Malay)
[ci skip]

* New translations en-us.po (Telugu)
[ci skip]

* New translations en-us.po (English, United Kingdom)
[ci skip]

* New translations en-us.po (Malayalam)
[ci skip]

* New translations en-us.po (Uzbek)
[ci skip]

* New translations en-us.po (Kannada)
[ci skip]

* New translations en-us.po (Odia)
[ci skip]

* New translations en-us.po (Amharic)
[ci skip]

* New translations en-us.po (Nepali)
[ci skip]

* New translations en-us.po (Russian)
[ci skip]
2026-03-29 23:07:48 +02:00
autofix-ci[bot] 688c002822 [autofix.ci] apply automated fixes 2026-03-24 10:58:09 +00:00
Amruth Pillai ced49d5314 Update Crowdin configuration file 2026-03-24 11:57:03 +01:00
188 changed files with 13967 additions and 3933 deletions
+8
View File
@@ -30,6 +30,10 @@ GOOGLE_CLIENT_SECRET=""
GITHUB_CLIENT_ID=""
GITHUB_CLIENT_SECRET=""
# Social Auth (LinkedIn, optional)
LINKEDIN_CLIENT_ID=""
LINKEDIN_CLIENT_SECRET=""
# Custom OAuth Provider (optional)
OAUTH_PROVIDER_NAME=""
OAUTH_CLIENT_ID=""
@@ -78,3 +82,7 @@ FLAG_DISABLE_IMAGE_PROCESSING="false"
# This is not used within Reactive Resume, but in src/scripts/fonts/generate.ts to generate a list of fonts served by Google Fonts.
# Note: Make sure "Google Fonts Developer API" is unrestricted.
GOOGLE_CLOUD_API_KEY=""
# --- Crowdin ---
CROWDIN_PROJECT_ID=""
CROWDIN_API_TOKEN=""
+3
View File
@@ -8,6 +8,9 @@ on:
permissions:
contents: read
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
jobs:
autofix:
runs-on: ubuntu-latest
+13 -12
View File
@@ -9,6 +9,7 @@ concurrency:
env:
IMAGE: ${{ github.repository }}
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
jobs:
build:
@@ -41,16 +42,16 @@ jobs:
run: echo "version=$(jq -r .version package.json)" >> "$GITHUB_OUTPUT"
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v4
- name: Login to Docker Hub
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
@@ -58,7 +59,7 @@ jobs:
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
uses: docker/metadata-action@v6
with:
images: |
ghcr.io/${{ env.IMAGE }}
@@ -68,7 +69,7 @@ jobs:
- name: Build and Push by Digest
id: build
uses: docker/build-push-action@v6
uses: docker/build-push-action@v7
with:
context: .
sbom: true
@@ -88,7 +89,7 @@ jobs:
touch "/tmp/digests/${digest#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: digests-${{ matrix.arch }}
path: /tmp/digests/*
@@ -118,23 +119,23 @@ jobs:
run: echo "version=$(jq -r .version package.json)" >> "$GITHUB_OUTPUT"
- name: Download digests
uses: actions/download-artifact@v7
uses: actions/download-artifact@v8
with:
path: /tmp/digests
pattern: digests-*
merge-multiple: true
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v4
- name: Login to Docker Hub
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
@@ -152,7 +153,7 @@ jobs:
- name: Extract metadata for Docker
id: meta
uses: docker/metadata-action@v5
uses: docker/metadata-action@v6
with:
images: |
ghcr.io/${{ env.IMAGE }}
@@ -189,7 +190,7 @@ jobs:
echo "docker_digest=$DOCKER_DIGEST" >> "$GITHUB_OUTPUT"
- name: Install Cosign
uses: sigstore/cosign-installer@v3
uses: sigstore/cosign-installer@v4
- name: Sign images with Cosign
run: |
+1 -3
View File
@@ -1,5 +1,3 @@
# AGENTS.md
## Overview
Reactive Resume is a single-package full-stack TypeScript app (not a monorepo) built with [TanStack Start](https://tanstack.com/start/latest/docs/framework/react/overview) (React, Vite, Nitro). It serves both frontend and API on port 3000.
@@ -130,4 +128,4 @@ Copy `.env.example` to `.env` if not present. Key notes for local dev:
## Review Checklist for Agents
- [ ] Run `vp install` after pulling remote changes and before getting started.
- [ ] Run `vp check` and `vp test` to validate changes.
- [ ] Run `pnpm lint:fix`, `pnpm fmt:fix`, `pnpm typecheck` and `vp test` to validate changes.
Symlink
+1
View File
@@ -0,0 +1 @@
AGENTS.md
+7 -5
View File
@@ -1,10 +1,12 @@
preserve_hierarchy: true
api_token_env: CROWDIN_API_TOKEN
project_id_env: CROWDIN_PROJECT_ID
commit_message: "[ci skip]"
pull_request_title: "Sync Translations from Crowdin"
pull_request_labels: ["l10n"]
pull_request_reviewers: ["amruthpillai"]
pull_request_title: Sync Translations from Crowdin
pull_request_labels:
- l10n
pull_request_reviewers:
- amruthpillai
files:
- source: /locales/en-US.po
translation: /locales/%locale%.%file_extension%
+45
View File
@@ -4,6 +4,51 @@ description: "List of all notable changes and updates to Reactive Resume"
rss: true
---
<Update label="v5.0.16" description="4th April 2026">
## Features & Improvements
- Updated shared resume item layouts (Experience, Education, Awards, Certifications, Publications, References, Volunteer) for better alignment and spacing consistency.
- Generated printer pages now set a meaningful document title from the resume owner's name (`<Name> - Resume`) for cleaner PDF metadata and tab titles. [#2863](https://github.com/amruthpillai/reactive-resume/pull/2863)
## Fixes
- Fixed [#2733](https://github.com/amruthpillai/reactive-resume/issues/2733), where date ranges could appear on a separate line unexpectedly in resume items. [#2862](https://github.com/amruthpillai/reactive-resume/pull/2862)
- Adjusted Experience section form field ordering/labels so `Location`, `Position`, and `Period` are mapped and displayed correctly.
## Maintenance & Localization
- Synced translation catalogs across all supported locales.
- Updated dependencies and lockfile, including AI SDK, TipTap, TanStack Query, and Vite+ package aliases.
</Update>
<Update label="v5.0.15" description="1st April 2026">
## Features & Improvements
- Added **LinkedIn sign-in** support for self-hosted instances, including sign-in on the auth page and account linking in settings.
- Improved the sign-in experience by showing loading placeholders while social login providers are being fetched.
- Resume builder panel sizes are now persisted more reliably, making the layout feel more consistent between sessions.
- Added clearer labels for resume sorting and filtering controls on the dashboard.
## Fixes
- Improved autosave reliability in the resume builder:
- Unsaved edits are flushed before page unload.
- You now get a clear persistent warning if changes fail to save (for example, due to network issues).
- Strengthened authentication defaults by increasing the minimum password length requirement to 8 characters.
- Improved reliability around resume deletion and server-side error handling for create/update operations.
- Fixed a rare language mix-up during printing/export when multiple print jobs run at the same time, so each PDF/screenshot now reliably uses the correct locale.
- Improved print stability under heavy usage by reusing in-progress PDF and screenshot generation requests for the same resume instead of starting duplicate jobs.
- Hardened printer token signing and token/session/API-key verification paths for better security.
- Improved resilience in AI tailoring output parsing and JSON Resume import normalization.
- Printer service now provides descriptive error messages ("Failed to generate PDF" / "Failed to capture screenshot") instead of generic internal server errors.
- Job descriptions in the job detail sheet now render HTML formatting (headings, lists, bold text) instead of showing raw tags.
- Fixed the "Tailor Resume" button being incorrectly disabled when AI is not configured — the dialog already supports plain resume duplication as a fallback.
- Fixed the tailor resume flow to open the resume builder in a new tab while keeping the job listing open for reference, instead of navigating away and auto-opening the application page.
- Apply option links in the job detail sheet are now validated before rendering, preventing malformed or potentially unsafe URLs.
- Improved job card loading skeletons to match the actual card layout (logo, title, badges) for a smoother loading experience.
- Centered the "Configure Job Search" empty state on the page.
- Extracted the `JobCard` component into its own file for better code organization.
## Docs & Localization
- Updated self-hosting and environment variable documentation to include LinkedIn OAuth configuration.
- Synced translations across locales for the latest authentication and save-status messaging.
</Update>
<Update label="v5.0.14" description="24th March 2026">
## Features
- Implemented OAuth 2.1 support for MCP authentication, thanks to @5queezer. [#2829](https://github.com/amruthpillai/reactive-resume/pull/2829)
+2
View File
@@ -138,6 +138,8 @@ Here's a complete list of environment variables you can configure:
| `GOOGLE_CLIENT_SECRET` | Google OAuth Client Secret | — |
| `GITHUB_CLIENT_ID` | GitHub OAuth Client ID | — |
| `GITHUB_CLIENT_SECRET` | GitHub OAuth Client Secret | — |
| `LINKEDIN_CLIENT_ID` | LinkedIn OAuth Client ID | — |
| `LINKEDIN_CLIENT_SECRET` | LinkedIn OAuth Client Secret | — |
| `OAUTH_PROVIDER_NAME` | Custom OAuth Provider Name | — |
| `OAUTH_CLIENT_ID` | Custom OAuth Client ID | — |
| `OAUTH_CLIENT_SECRET` | Custom OAuth Client Secret | — |
+7 -1
View File
@@ -73,6 +73,10 @@ GOOGLE_CLIENT_SECRET=""
GITHUB_CLIENT_ID=""
GITHUB_CLIENT_SECRET=""
# Social Auth (LinkedIn, optional)
LINKEDIN_CLIENT_ID=""
LINKEDIN_CLIENT_SECRET=""
# Custom OAuth Provider
OAUTH_PROVIDER_NAME=""
OAUTH_CLIENT_ID=""
@@ -338,6 +342,8 @@ openssl rand -hex 32
**`GITHUB_CLIENT_ID`** / **`GITHUB_CLIENT_SECRET`** (optional): Enables GitHub sign-in.
**`LINKEDIN_CLIENT_ID`** / **`LINKEDIN_CLIENT_SECRET`** (optional): Enables LinkedIn sign-in.
**Custom OAuth provider** (optional):
- **`OAUTH_PROVIDER_NAME`**: Display name in the UI
- **`OAUTH_CLIENT_ID`** / **`OAUTH_CLIENT_SECRET`**: Required for any custom OAuth provider
@@ -375,7 +381,7 @@ openssl rand -hex 32
<Accordion title="Feature Flags">
- **`FLAG_DEBUG_PRINTER`**: Bypasses the printer-only access restriction (useful when debugging `/printer/{resumeId}`). Recommended: keep `"false"` in production.
- **`FLAG_DISABLE_SIGNUPS`**: Disables new signups (web app and server). Useful for private instances.
- **`FLAG_DISABLE_EMAIL_AUTH`**: Disables email/password login entirely. Also disables email verification, forgot password, and reset password flows. Users can still sign up via social auth (Google/GitHub/Custom OAuth), unless FLAG_DISABLE_SIGNUPS is also set to true. Useful when only SSO is required.
- **`FLAG_DISABLE_EMAIL_AUTH`**: Disables email/password login entirely. Also disables email verification, forgot password, and reset password flows. Users can still sign up via social auth (Google/GitHub/LinkedIn/Custom OAuth), unless FLAG_DISABLE_SIGNUPS is also set to true. Useful when only SSO is required.
- **`FLAG_DISABLE_IMAGE_PROCESSING`**: Disables image processing. This is useful if you are using a machine with limited resources, like a Raspberry Pi.
</Accordion>
</AccordionGroup>
+2
View File
@@ -405,6 +405,8 @@ services:
- GOOGLE_CLIENT_SECRET=$GOOGLE_CLIENT_SECRET
- GITHUB_CLIENT_ID=$GITHUB_CLIENT_ID
- GITHUB_CLIENT_SECRET=$GITHUB_CLIENT_SECRET
- LINKEDIN_CLIENT_ID=$LINKEDIN_CLIENT_ID
- LINKEDIN_CLIENT_SECRET=$LINKEDIN_CLIENT_SECRET
- SMTP_HOST=$SMTP_HOST
- SMTP_PORT=$SMTP_PORT
- SMTP_USER=$SMTP_USER
+2
View File
@@ -253,6 +253,8 @@ AUTH_SECRET="your-32-byte-hex-secret"
# GOOGLE_CLIENT_SECRET=""
# GITHUB_CLIENT_ID=""
# GITHUB_CLIENT_SECRET=""
# LINKEDIN_CLIENT_ID=""
# LINKEDIN_CLIENT_SECRET=""
# Custom OAuth Provider (e.g., Authentik)
OAUTH_PROVIDER_NAME="Company SSO"
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: af\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:07\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Afrikaans\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -1234,6 +1234,7 @@ msgstr "Vaardighede kon nie gesinchroniseer word nie"
msgid "Features"
msgstr "Funksies"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "Filter volgens"
@@ -1911,14 +1912,6 @@ msgstr "Genommerde lys"
msgid "Organization"
msgstr "Organisasie"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "Totale tydperk"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "Algehele titel (opsioneel)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "Bladsy"
@@ -2167,9 +2160,9 @@ msgstr "Verfris"
msgid "Remember your password? <0/>"
msgstr "Onthou jy jou wagwoord? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "Afgeleë"
@@ -2517,6 +2510,7 @@ msgstr "Slak"
msgid "Something went wrong. Please try again."
msgstr "Iets het verkeerd geloop. Probeer asseblief weer."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "Sorteer volgens"
@@ -3186,6 +3180,10 @@ msgstr "Jou data word plaaslik gestoor"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "Jou data word veilig gestoor en nooit met derde partye gedeel nie. Jy kan ook Reactive Resume self-host op jou eie bedieners vir volledige beheer oor jou data."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "Jou wagwoord is suksesvol herstel. Jy kan nou met jou nuwe wagwoord aanmeld."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: am\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:08\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Amharic\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
@@ -1234,6 +1234,7 @@ msgstr ""
msgid "Features"
msgstr "መለያዎች"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "መመርመሪያ በ"
@@ -1911,14 +1912,6 @@ msgstr "ተደራሽ ዝርዝር"
msgid "Organization"
msgstr "ድርጅት"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "አጠቃላይ ጊዜ"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "አጠቃላይ ርዕስ (አማራጭ)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "ገጽ"
@@ -2167,9 +2160,9 @@ msgstr "ዳስ አድርግ"
msgid "Remember your password? <0/>"
msgstr "የይለፍ ቃልዎን ያስታውሳሉ? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr ""
@@ -2517,6 +2510,7 @@ msgstr "Slug"
msgid "Something went wrong. Please try again."
msgstr "የተሳሳተ ነገር ተፈጥሯል። እባክዎን ደግመው ይሞክሩ።"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "መደብ በ"
@@ -3186,6 +3180,10 @@ msgstr "መረጃዎ በአካባቢዎ መሣሪያ ላይ ይቀመጣል"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "መረጃዎ በደህና ይከማቻል እና ከሶስተኛ ወገኖች ጋር አይተካፈልም። ደግሞም በራስዎ ሰርቨር ላይ Reactive Resumeን በመጫን በመረጃዎ ላይ ሙሉ ቁጥጥር ማግኘት ትችላላችሁ።"
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "የይለፍ ቃልዎ በተሳካ ሁኔታ ዳግም ተጀምሯል። አሁን በአዲሱ የይለፍ ቃል መግባት ትችላላችሁ።"
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: ar\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:07\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Arabic\n"
"Plural-Forms: nplurals=6; plural=(n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5);\n"
@@ -1234,6 +1234,7 @@ msgstr "فشل في مزامنة المهارات"
msgid "Features"
msgstr "الميزات"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "تصفية حسب"
@@ -1911,14 +1912,6 @@ msgstr "قائمة مرتبة"
msgid "Organization"
msgstr "المنظمة"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "الفترة الإجمالية"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "العنوان الإجمالي (اختياري)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "صفحة"
@@ -2167,9 +2160,9 @@ msgstr "تحديث"
msgid "Remember your password? <0/>"
msgstr "تتذكر كلمة المرور؟ <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "جهاز التحكم عن بُعد"
@@ -2517,6 +2510,7 @@ msgstr "المعرّف النصي (Slug)"
msgid "Something went wrong. Please try again."
msgstr "حدث خطأ ما. يُرجى المحاولة مرة أخرى."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "فرز حسب"
@@ -3186,6 +3180,10 @@ msgstr "تُخزَّن بياناتك محليًا"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "تُخزَّن بياناتك بأمان ولا تتم مشاركتها أبدًا مع أطراف ثالثة. يمكنك أيضًا استضافة Reactive Resume ذاتيًا على خوادمك الخاصة للتحكم الكامل في بياناتك."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "تمت إعادة تعيين كلمة المرور الخاصة بك بنجاح. يمكنك الآن تسجيل الدخول باستخدام كلمة المرور الجديدة."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: az\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:08\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Azerbaijani\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -1234,6 +1234,7 @@ msgstr "Bacarıqları sinxronlaşdırmaq mümkün olmadı"
msgid "Features"
msgstr "Xüsusiyyətlər"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "Filtrlə"
@@ -1911,14 +1912,6 @@ msgstr "Nömrələnmiş Siyahı"
msgid "Organization"
msgstr "Təşkilat"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "Ümumi dövr"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "Ümumi başlıq (isteğe bağlı)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "Səhifə"
@@ -2167,9 +2160,9 @@ msgstr "Yenilə"
msgid "Remember your password? <0/>"
msgstr "Şifrənizi xatırlayırsınız? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "Uzaqdan"
@@ -2517,6 +2510,7 @@ msgstr "Slug"
msgid "Something went wrong. Please try again."
msgstr "Nəsə səhv getdi. Zəhmət olmasa, yenidən cəhd edin."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "Sırala"
@@ -3186,6 +3180,10 @@ msgstr "Məlumatlarınız lokal olaraq saxlanılır"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "Məlumatlarınız təhlükəsiz şəkildə saxlanılır və heç vaxt üçüncü tərəflərlə paylaşılmır. Məlumatlarınıza tam nəzarət üçün Reactive Resume‑ni öz serverlərinizdə də host edə bilərsiniz."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "Parolunuz uğurla sıfırlandı. İndi yeni parolunuzla daxil ola bilərsiniz."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: bg\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:07\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Bulgarian\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -1234,6 +1234,7 @@ msgstr "Неуспешно синхронизиране на умения"
msgid "Features"
msgstr "Функции"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "Филтриране по"
@@ -1911,14 +1912,6 @@ msgstr "Подреден списък"
msgid "Organization"
msgstr "Организация"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "Общ период"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "Обща длъжност (незадължително)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "Страница"
@@ -2167,9 +2160,9 @@ msgstr "Опресняване"
msgid "Remember your password? <0/>"
msgstr "Спомняте ли си паролата? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "Отдалечен"
@@ -2517,6 +2510,7 @@ msgstr "Слъг"
msgid "Something went wrong. Please try again."
msgstr "Нещо се обърка. Моля, опитайте отново."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "Сортиране по"
@@ -3186,6 +3180,10 @@ msgstr "Вашите данни се съхраняват локално"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "Вашите данни се съхраняват сигурно и никога не се споделят с трети страни. Можете също да хоствате Reactive Resume самостоятелно на свои сървъри за пълен контрол върху данните си."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "Паролата ви беше нулирана успешно. Сега можете да влезете с новата си парола."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: bn\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:08\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Bengali\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -1234,6 +1234,7 @@ msgstr "দক্ষতা সিঙ্ক করতে ব্যর্থ হ
msgid "Features"
msgstr "বৈশিষ্ট্যসমূহ"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "ফিল্টার করুন"
@@ -1911,14 +1912,6 @@ msgstr "ক্রমযুক্ত লিস্ট"
msgid "Organization"
msgstr "প্রতিষ্ঠান"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "সামগ্রিক সময়কাল"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "সামগ্রিক শিরোনাম (ঐচ্ছিক)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "পৃষ্ঠা"
@@ -2167,9 +2160,9 @@ msgstr "রিফ্রেশ"
msgid "Remember your password? <0/>"
msgstr "আপনার পাসওয়ার্ড মনে আছে? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "দূরবর্তী"
@@ -2517,6 +2510,7 @@ msgstr "স্লাগ"
msgid "Something went wrong. Please try again."
msgstr "কিছু একটা ভুল হয়েছে। অনুগ্রহ করে আবার চেষ্টা করুন।"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "সর্ট করুন"
@@ -3186,6 +3180,10 @@ msgstr "আপনার ডেটা স্থানীয়ভাবে সং
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "আপনার ডেটা নিরাপদভাবে সংরক্ষিত হয় এবং কখনোই তৃতীয় পক্ষের সঙ্গে শেয়ার করা হয় না। চাইলে আপনি নিজের সার্ভারে Reactive Resume নিজে হোস্ট করেও ডেটার পূর্ণ নিয়ন্ত্রণ রাখতে পারেন।"
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "আপনার পাসওয়ার্ড সফলভাবে রিসেট হয়েছে। এখন আপনি নতুন পাসওয়ার্ড দিয়ে সাইন ইন করতে পারবেন।"
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: ca\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:07\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Catalan\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -1234,6 +1234,7 @@ msgstr "Sincronització d'habilitats fallida"
msgid "Features"
msgstr "Funcions"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "Filtra per"
@@ -1911,14 +1912,6 @@ msgstr "Llista ordenada"
msgid "Organization"
msgstr "Organització"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "Període total"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "Títol global (opcional)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "Pàgina"
@@ -2167,9 +2160,9 @@ msgstr "Actualitza"
msgid "Remember your password? <0/>"
msgstr "Recordeu la contrasenya? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "A distància"
@@ -2517,6 +2510,7 @@ msgstr "Identificador llegible (slug)"
msgid "Something went wrong. Please try again."
msgstr "Alguna cosa ha anat malament. Torna-ho a provar."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "Ordena per"
@@ -3186,6 +3180,10 @@ msgstr "Les dades es desen localment"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "Les dades s’emmagatzemen de manera segura i mai no es comparteixen amb tercers. També pots autoallotjar Reactive Resume als teus propis servidors per tenir un control total sobre les dades."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "La contrasenya s’ha restablert correctament. Ara ja pots iniciar sessió amb la contrasenya nova."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: cs\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:07\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Czech\n"
"Plural-Forms: nplurals=4; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 3;\n"
@@ -1234,6 +1234,7 @@ msgstr "Nepodařilo se synchronizovat dovednosti"
msgid "Features"
msgstr "Funkce"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "Filtrovat podle"
@@ -1911,14 +1912,6 @@ msgstr "Číslovaný seznam"
msgid "Organization"
msgstr "Organizace"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "Celkové období"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "Celkový titul (volitelné)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "Stránka"
@@ -2167,9 +2160,9 @@ msgstr "Obnovit"
msgid "Remember your password? <0/>"
msgstr "Vzpomínáte si na heslo? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "Vzdálený"
@@ -2517,6 +2510,7 @@ msgstr "Slug"
msgid "Something went wrong. Please try again."
msgstr "Něco se pokazilo. Zkuste to prosím znovu."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "Seřadit podle"
@@ -3186,6 +3180,10 @@ msgstr "Vaše data jsou ukládána lokálně"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "Vaše data jsou ukládána bezpečně a nikdy nejsou sdílena s třetími stranami. Reactive Resume si můžete také hostovat sami na vlastních serverech a mít tak nad svými daty plnou kontrolu."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "Vaše heslo bylo úspěšně obnoveno. Nyní se můžete přihlásit pomocí nového hesla."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: da\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:07\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Danish\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -1234,6 +1234,7 @@ msgstr "Kunne ikke synkronisere færdigheder"
msgid "Features"
msgstr "Funktioner"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "Filtrér efter"
@@ -1911,14 +1912,6 @@ msgstr "Nummereret liste"
msgid "Organization"
msgstr "Organisation"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "Samlet periode"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "Overordnet titel (valgfrit)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "Side"
@@ -2167,9 +2160,9 @@ msgstr "Opdater"
msgid "Remember your password? <0/>"
msgstr "Husker du din adgangskode? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "Fjernbetjening"
@@ -2517,6 +2510,7 @@ msgstr "URL-segment"
msgid "Something went wrong. Please try again."
msgstr "Noget gik galt. Prøv igen."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "Sortér efter"
@@ -3186,6 +3180,10 @@ msgstr "Dine data gemmes lokalt"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "Dine data lagres sikkert og deles aldrig med tredjeparter. Du kan også selv-hoste Reactive Resume på dine egne servere for fuld kontrol over dine data."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "Din adgangskode er blevet nulstillet. Du kan nu logge ind med din nye adgangskode."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: de\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:07\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: German\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -1234,6 +1234,7 @@ msgstr "Synchronisierung der Fähigkeiten fehlgeschlagen"
msgid "Features"
msgstr "Funktionen"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "Filtern nach"
@@ -1911,14 +1912,6 @@ msgstr "Nummerierte Liste"
msgid "Organization"
msgstr "Organisation"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "Gesamtzeitraum"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "Gesamttitel (optional)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "Seite"
@@ -2167,9 +2160,9 @@ msgstr "Aktualisieren"
msgid "Remember your password? <0/>"
msgstr "Passwort noch parat? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "Fernbedienung"
@@ -2517,6 +2510,7 @@ msgstr "Slug"
msgid "Something went wrong. Please try again."
msgstr "Etwas ist schiefgelaufen. Bitte versuchen Sie es erneut."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "Sortieren nach"
@@ -3186,6 +3180,10 @@ msgstr "Deine Daten werden lokal gespeichert"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "Deine Daten werden sicher gespeichert und niemals an Dritte weitergegeben. Du kannst Reactive Resume außerdem auf deinen eigenen Servern selbst hosten, um die vollständige Kontrolle über deine Daten zu behalten."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "Ihr Passwort wurde erfolgreich zurückgesetzt. Sie können sich nun mit Ihrem neuen Passwort anmelden."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: el\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:07\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Greek\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -1234,6 +1234,7 @@ msgstr "Αποτυχία συγχρονισμού δεξιοτήτων"
msgid "Features"
msgstr "Λειτουργίες"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "Φιλτράρισμα κατά"
@@ -1911,14 +1912,6 @@ msgstr "Αριθμημένη λίστα"
msgid "Organization"
msgstr "Οργανισμός"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "Συνολική περίοδος"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "Γενικός τίτλος (προαιρετικό)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "Σελίδα"
@@ -2167,9 +2160,9 @@ msgstr "Ανανέωση"
msgid "Remember your password? <0/>"
msgstr "Θυμάστε τον κωδικό σας; <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "Απομακρυσμένο"
@@ -2517,6 +2510,7 @@ msgstr "Slug"
msgid "Something went wrong. Please try again."
msgstr "Κάτι πήγε στραβά. Παρακαλώ δοκιμάστε ξανά."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "Ταξινόμηση κατά"
@@ -3186,6 +3180,10 @@ msgstr "Τα δεδομένα σας αποθηκεύονται τοπικά"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "Τα δεδομένα σας αποθηκεύονται με ασφάλεια και δεν κοινοποιούνται ποτέ σε τρίτους. Μπορείτε επίσης να φιλοξενήσετε μόνοι σας το Reactive Resume στους δικούς σας διακομιστές για πλήρη έλεγχο των δεδομένων σας."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "Ο κωδικός πρόσβασής σας επαναφέρθηκε με επιτυχία. Τώρα μπορείτε να συνδεθείτε με τον νέο σας κωδικό πρόσβασης."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: en_GB\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:08\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: English, United Kingdom\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -1234,6 +1234,7 @@ msgstr "Failed to sync skills"
msgid "Features"
msgstr "Features"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "Filter by"
@@ -1911,14 +1912,6 @@ msgstr "Ordered List"
msgid "Organization"
msgstr "Organisation"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "Overall Period"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "Overall Title (optional)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "Page"
@@ -2167,9 +2160,9 @@ msgstr "Refresh"
msgid "Remember your password? <0/>"
msgstr "Remember your password? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "Remote"
@@ -2517,6 +2510,7 @@ msgstr "Slug"
msgid "Something went wrong. Please try again."
msgstr "Something went wrong. Please try again."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "Sort by"
@@ -3186,6 +3180,10 @@ msgstr "Your data is stored locally"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "Your password has been reset successfully. You can now sign in with your new password."
+7 -9
View File
@@ -1229,6 +1229,7 @@ msgstr "Failed to sync skills"
msgid "Features"
msgstr "Features"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "Filter by"
@@ -1906,14 +1907,6 @@ msgstr "Ordered List"
msgid "Organization"
msgstr "Organization"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "Overall Period"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "Overall Title (optional)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "Page"
@@ -2162,9 +2155,9 @@ msgstr "Refresh"
msgid "Remember your password? <0/>"
msgstr "Remember your password? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "Remote"
@@ -2512,6 +2505,7 @@ msgstr "Slug"
msgid "Something went wrong. Please try again."
msgstr "Something went wrong. Please try again."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "Sort by"
@@ -3181,6 +3175,10 @@ msgstr "Your data is stored locally"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "Your password has been reset successfully. You can now sign in with your new password."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: es\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:07\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Spanish\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -1234,6 +1234,7 @@ msgstr "Fallo en la sincronización de habilidades"
msgid "Features"
msgstr "Funciones"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "Filtrar por"
@@ -1911,14 +1912,6 @@ msgstr "Lista ordenada"
msgid "Organization"
msgstr "Organización"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "Periodo general"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "Título general (opcional)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "Página"
@@ -2167,9 +2160,9 @@ msgstr "Actualizar"
msgid "Remember your password? <0/>"
msgstr "¿Recuerdas tu contraseña? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "Remoto"
@@ -2517,6 +2510,7 @@ msgstr "Slug"
msgid "Something went wrong. Please try again."
msgstr "Algo salió mal. Vuelve a intentarlo."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "Ordenar por"
@@ -3186,6 +3180,10 @@ msgstr "Tus datos se almacenan localmente"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "Tus datos se almacenan de forma segura y nunca se comparten con terceros. También puedes auto alojar Reactive Resume en tus propios servidores para tener un control total sobre tus datos."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "Tu contraseña se ha restablecido correctamente. Ahora puedes iniciar sesión con tu nueva contraseña."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: fa\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:07\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Persian\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -1234,6 +1234,7 @@ msgstr "همگام‌سازی مهارت‌ها ناموفق بود"
msgid "Features"
msgstr "امکانات"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "فیلتر بر اساس"
@@ -1911,14 +1912,6 @@ msgstr "فهرست شماره‌دار"
msgid "Organization"
msgstr "سازمان"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "دوره کلی"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "عنوان کلی (اختیاری)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "صفحه"
@@ -2167,9 +2160,9 @@ msgstr "تازه‌سازی"
msgid "Remember your password? <0/>"
msgstr "رمز عبور را به خاطر دارید؟ <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "از راه دور"
@@ -2517,6 +2510,7 @@ msgstr "نام یکتا"
msgid "Something went wrong. Please try again."
msgstr "مشکلی پیش آمد. لطفاً دوباره تلاش کنید."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "مرتب‌سازی بر اساس"
@@ -3186,6 +3180,10 @@ msgstr "داده‌های شما به‌صورت محلی ذخیره می‌شو
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "داده‌های شما به‌طور ایمن ذخیره شده و هرگز با اشخاص ثالث به اشتراک گذاشته نمی‌شوند. همچنین می‌توانید Reactive Resume را روی سرورهای خود میزبانی کنید تا کنترل کامل بر داده‌های خود داشته باشید."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "گذرواژهٔ شما با موفقیت تنظیم مجدد شد. اکنون می‌توانید با گذرواژهٔ جدید خود وارد شوید."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: fi\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:07\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Finnish\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -1234,6 +1234,7 @@ msgstr "Taitojen synkronointi epäonnistui"
msgid "Features"
msgstr "Ominaisuudet"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "Suodata"
@@ -1911,14 +1912,6 @@ msgstr "Numeroitu lista"
msgid "Organization"
msgstr "Organisaatio"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "Kokonaisajanjakso"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "Yleinen nimike (valinnainen)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "Sivu"
@@ -2167,9 +2160,9 @@ msgstr "Päivitä"
msgid "Remember your password? <0/>"
msgstr "Muistatko salasanasi? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "Kaukosäädin"
@@ -2517,6 +2510,7 @@ msgstr "Polkutunnus"
msgid "Something went wrong. Please try again."
msgstr "Jokin meni pieleen. Yritä uudelleen."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "Lajittele"
@@ -3186,6 +3180,10 @@ msgstr "Tietosi tallennetaan paikallisesti"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "Tietosi tallennetaan turvallisesti eikä niitä koskaan jaeta kolmansille osapuolille. Voit myös itseisännöidä Reactive Resumen omilla palvelimillasi täydellisen tietokontrollin takaamiseksi."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "Salasanasi on palautettu onnistuneesti. Voit nyt kirjautua sisään uudella salasanallasi."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: fr\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-22 11:27\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: French\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
@@ -1234,6 +1234,7 @@ msgstr "Échec de la synchronisation des compétences"
msgid "Features"
msgstr "Fonctionnalités"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "Filtrer par"
@@ -1911,14 +1912,6 @@ msgstr "Liste triée"
msgid "Organization"
msgstr "Organisation"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "Période globale"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "Titre global (optionnel)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "Page"
@@ -2167,9 +2160,9 @@ msgstr "Actualiser"
msgid "Remember your password? <0/>"
msgstr "Vous vous souvenez de votre mot de passe ? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "A distance"
@@ -2517,6 +2510,7 @@ msgstr "Slug"
msgid "Something went wrong. Please try again."
msgstr "Une erreur s'est produite. Veuillez réessayer."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "Trier par"
@@ -3186,6 +3180,10 @@ msgstr "Vos données sont stockées localement"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "Vos données sont stockées en toute sécurité et ne sont jamais partagées avec des tiers. Vous pouvez également héberger Reactive Resume sur vos propres serveurs pour un contrôle total de vos données."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "Votre mot de passe a été réinitialisé avec succès. Vous pouvez maintenant vous connecter avec votre nouveau mot de passe."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: he\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:07\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Hebrew\n"
"Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3;\n"
@@ -1234,6 +1234,7 @@ msgstr "לא הצליח לסנכרן מיומנויות"
msgid "Features"
msgstr "יכולות"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "סינון לפי"
@@ -1911,14 +1912,6 @@ msgstr "רשימה ממוספרת"
msgid "Organization"
msgstr "ארגון"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "תקופה כוללת"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "כותרת כוללת (רשות)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "עמוד"
@@ -2167,9 +2160,9 @@ msgstr "רענון"
msgid "Remember your password? <0/>"
msgstr "זוכר את הסיסמה? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "מרחוק"
@@ -2517,6 +2510,7 @@ msgstr "שם ייצוגי"
msgid "Something went wrong. Please try again."
msgstr "משהו השתבש. נא לנסות שוב."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "מיון לפי"
@@ -3186,6 +3180,10 @@ msgstr "הנתונים שלך מאוחסנים באופן מקומי"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "הנתונים שלך מאוחסנים בצורה מאובטחת ולעולם אינם משותפים עם צדדים שלישיים. אפשר גם לארח את Reactive Resume בשרתים שלך כדי לשלוט לחלוטין בנתונים שלך."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "הסיסמה שלך אופסה בהצלחה. כעת אפשר להתחבר עם הסיסמה החדשה שלך."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: hi\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:08\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Hindi\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -1234,6 +1234,7 @@ msgstr "कौशल सिंक करने में असफल"
msgid "Features"
msgstr "विशेषताएँ"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "फ़िल्टर करें"
@@ -1911,14 +1912,6 @@ msgstr "क्रमबद्ध सूची"
msgid "Organization"
msgstr "संगठन"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "कुल अवधि"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "समग्र शीर्षक (वैकल्पिक)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "पृष्ठ"
@@ -2167,9 +2160,9 @@ msgstr "रिफ़्रेश"
msgid "Remember your password? <0/>"
msgstr "अपना पासवर्ड याद है? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "दूरस्थ"
@@ -2517,6 +2510,7 @@ msgstr "काउंटर"
msgid "Something went wrong. Please try again."
msgstr "कुछ गड़बड़ हो गई। कृपया फिर से प्रयास करें।"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "क्रमबद्ध करें"
@@ -3186,6 +3180,10 @@ msgstr "आपका डेटा लोकल रूप से संग्र
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "आपका डेटा सुरक्षित रूप से संग्रहीत है और कभी भी थर्ड पार्टियों के साथ साझा नहीं किया जाता। आप अपने सर्वर्स पर Reactive Resume को स्व‑होस्ट भी कर सकते हैं ताकि अपने डेटा पर पूर्ण नियंत्रण रख सकें।"
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "आपका पासवर्ड सफलतापूर्वक रीसेट कर दिया गया है। अब आप अपने नए पासवर्ड से साइन इन कर सकते हैं।"
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: hu\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:07\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Hungarian\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -1234,6 +1234,7 @@ msgstr "Nem sikerült szinkronizálni a készségeket"
msgid "Features"
msgstr "Funkciók"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "Szűrés alapja"
@@ -1911,14 +1912,6 @@ msgstr "Sorszámozott lista"
msgid "Organization"
msgstr "Szervezet"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "Teljes időszak"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "Teljes cím (opcionális)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "Oldal"
@@ -2167,9 +2160,9 @@ msgstr "Frissítés"
msgid "Remember your password? <0/>"
msgstr "Emlékszik a jelszavára? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "Távoli"
@@ -2517,6 +2510,7 @@ msgstr "Keresőbarát azonosító"
msgid "Something went wrong. Please try again."
msgstr "Valami hiba történt. Kérjük, próbáld újra."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "Rendezés alapja"
@@ -3186,6 +3180,10 @@ msgstr "Az adataid helyben tárolódnak"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "Az adataid biztonságosan tároljuk, és soha nem osztjuk meg harmadik felekkel. A Reactive Resume‑t saját szervereiden is hosztolhatod, hogy teljes kontrollod legyen az adataid felett."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "A jelszavadat sikeresen visszaállítottuk. Mostantól az új jelszóval jelentkezhetsz be."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: id\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:07\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Indonesian\n"
"Plural-Forms: nplurals=1; plural=0;\n"
@@ -1234,6 +1234,7 @@ msgstr "Gagal menyinkronkan keterampilan"
msgid "Features"
msgstr "Fitur"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "Filter berdasarkan"
@@ -1911,14 +1912,6 @@ msgstr "Daftar Bernomor"
msgid "Organization"
msgstr "Organisasi"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "Periode Keseluruhan"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "Judul Keseluruhan (opsional)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "Halaman"
@@ -2167,9 +2160,9 @@ msgstr "Muat Ulang"
msgid "Remember your password? <0/>"
msgstr "Ingat kata sandi Anda? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "Jarak jauh"
@@ -2517,6 +2510,7 @@ msgstr "Slug"
msgid "Something went wrong. Please try again."
msgstr "Terjadi sesuatu yang salah. Silakan coba lagi."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "Urutkan berdasarkan"
@@ -3186,6 +3180,10 @@ msgstr "Data Anda disimpan secara lokal"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "Data Anda disimpan dengan aman dan tidak pernah dibagikan dengan pihak ketiga. Anda juga dapat self-host Reactive Resume di server Anda sendiri untuk kontrol penuh atas data Anda."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "Kata sandi Anda telah berhasil diatur ulang. Anda sekarang dapat masuk dengan kata sandi baru Anda."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: it\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:07\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Italian\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -1234,6 +1234,7 @@ msgstr "Impossibile sincronizzare le competenze"
msgid "Features"
msgstr "Funzionalità"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "Filtra per"
@@ -1911,14 +1912,6 @@ msgstr "Elenco numerato"
msgid "Organization"
msgstr "Organizzazione"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "Periodo complessivo"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "Titolo complessivo (opzionale)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "Pagina"
@@ -2167,9 +2160,9 @@ msgstr "Aggiorna"
msgid "Remember your password? <0/>"
msgstr "Ricordi la tua password? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "Remoto"
@@ -2517,6 +2510,7 @@ msgstr "Slug"
msgid "Something went wrong. Please try again."
msgstr "Qualcosa è andato storto. Riprova."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "Ordina per"
@@ -3186,6 +3180,10 @@ msgstr "I tuoi dati vengono memorizzati localmente"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "I tuoi dati sono archiviati in modo sicuro e non vengono mai condivisi con terze parti. Puoi anche fare self-host di Reactive Resume sui tuoi server per avere il pieno controllo dei tuoi dati."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "La tua password è stata reimpostata correttamente. Ora puoi accedere con la tua nuova password."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: ja\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:07\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Japanese\n"
"Plural-Forms: nplurals=1; plural=0;\n"
@@ -1234,6 +1234,7 @@ msgstr "スキルの同期に失敗"
msgid "Features"
msgstr "機能"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "絞り込み条件"
@@ -1911,14 +1912,6 @@ msgstr "番号付きリスト"
msgid "Organization"
msgstr "団体名"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "全体の期間"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "全体タイトル(任意)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "ページ"
@@ -2167,9 +2160,9 @@ msgstr "再読み込み"
msgid "Remember your password? <0/>"
msgstr "パスワードを思い出しましたか? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "リモート"
@@ -2517,6 +2510,7 @@ msgstr "スラッグ"
msgid "Something went wrong. Please try again."
msgstr "問題が発生しました。もう一度お試しください。"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "並べ替え条件"
@@ -3186,6 +3180,10 @@ msgstr "あなたのデータはローカルに保存されます。"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "あなたのデータは安全に保存され、第三者と共有されることはありません。また、完全にデータを管理したい場合は、Reactive Resume を自分のサーバーにセルフホストすることもできます。"
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "パスワードを正常にリセットしました。新しいパスワードでサインインできます。"
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: km\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:08\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Khmer\n"
"Plural-Forms: nplurals=1; plural=0;\n"
@@ -1234,6 +1234,7 @@ msgstr ""
msgid "Features"
msgstr "មុខងារ"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "ត្រង​តាម"
@@ -1911,14 +1912,6 @@ msgstr "បញ្ជី​មាន​លេខ"
msgid "Organization"
msgstr "អង្គការ"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "រយៈពេលទាំងមូល"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "ចំណងជើងទាំងមូល (ជាជម្រើស)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "ទំព័រ"
@@ -2167,9 +2160,9 @@ msgstr "ផ្ទៀងផ្ទាត់​ម្ដងទៀត"
msgid "Remember your password? <0/>"
msgstr "ចាំពាក្យសម្ងាត់របស់អ្នក? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr ""
@@ -2517,6 +2510,7 @@ msgstr "Slug"
msgid "Something went wrong. Please try again."
msgstr "មាន​អ្វីមួយ​ខុសប្រក្រតី។ សូម​ព្យាយាម​ម្ដង​ទៀត។"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "តម្រៀប​តាម"
@@ -3186,6 +3180,10 @@ msgstr "ទិន្នន័យ​របស់​អ្នក​ត្រូវ
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "ទិន្នន័យ​របស់​អ្នក​ត្រូវ​បាន​រក្សាទុក​ដោយ​សុវត្ថិភាព ហើយ​មិនដែល​ត្រូវ​បាន​ចែករំលែក​ជាមួយ​ភាគី​ទីបី​ទេ។ អ្នក​ក៏​អាច​ដំឡើង Reactive Resume លើ​ម៉ាស៊ីន​បម្រើ​ផ្ទាល់ខ្លួន​របស់​អ្នក ដើម្បី​មាន​សិទ្ធિ​ត្រួតត្រា​លើ​ទិន្នន័យ​របស់​អ្នក​ដល់​ខ្ពស់​បំផុត​ផង​ដែរ។"
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "ពាក្យសម្ងាត់​របស់​អ្នក​ត្រូវ​បាន​កំណត់​ឡើងវិញ​ដោយ​ជោគជ័យ។ ឥឡូវ​អ្នក​អាច​ចូល​ដោយ​ប្រើ​ពាក្យសម្ងាត់​ថ្មី​របស់​អ្នកបាន​ហើយ។"
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: kn\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:08\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Kannada\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -1234,6 +1234,7 @@ msgstr ""
msgid "Features"
msgstr "ವೈಶಿಷ್ಟ್ಯಗಳು"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "ಫಿಲ್ಟರ್ ಆಧಾರಿತವಾಗಿ"
@@ -1911,14 +1912,6 @@ msgstr "ಕ್ರಮಿತ ಪಟ್ಟ್ತಿ"
msgid "Organization"
msgstr "ಸಂಸ್ಥೆ"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "ಒಟ್ಟಾರೆ ಅವಧಿ"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "ಒಟ್ಟಾರೆ ಶೀರ್ಷಿಕೆ (ಐಚ್ಛಿಕ)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "ಪುಟ"
@@ -2167,9 +2160,9 @@ msgstr "ರಿಫ್ರೆಶ್ ಮಾಡಿ"
msgid "Remember your password? <0/>"
msgstr "ನಿಮ್ಮ ಪಾಸ್‌ವರ್ಡ್ ನೆನಪಿದೆಯೇ? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr ""
@@ -2517,6 +2510,7 @@ msgstr "ಸ್ಲಗ್"
msgid "Something went wrong. Please try again."
msgstr "ಏನೋ ತಪ್ಪಾಗಿದೆ. ದಯವಿಟ್ಟು ಮರುಪ್ರಯತ್ನಿಸಿ."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "ವಿನ್ಯಾಸ ಆಧಾರದ ಮೇಲೆ ವಿಂಗಡಿಸಿ"
@@ -3186,6 +3180,10 @@ msgstr "ನಿಮ್ಮ ಡೇಟಾವನ್ನು ಸ್ಥಳೀಯವಾಗ
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "ನಿಮ್ಮ ಡೇಟಾವನ್ನು ಸುರಕ್ಷಿತವಾಗಿ ಸಂಗ್ರಹಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಎಂದಿಗೂ ತೃತೀಯಪಕ್ಷಗಳೊಂದಿಗೆ ಹಂಚಿಕೊಳ್ಳಲಾಗುವುದಿಲ್ಲ. ನಿಮ್ಮ ಡೇಟಾದ ಮೇಲೆ ಸಂಪೂರ್ಣ ನಿಯಂತ್ರಣಕ್ಕಾಗಿ ನಿಮ್ಮದೇ ಸರ್ವರ್‌ಗಳಲ್ಲಿ Reactive Resume ಅನ್ನು ಸ್ವಯಂ-ಹೋಸ್ಟ್ ಮಾಡಬಹುದು."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "ನಿಮ್ಮ ಪಾಸ್‌ವರ್ಡ್ ಅನ್ನು ಯಶಸ್ವಿಯಾಗಿ ಮರುಹೊಂದಿಸಲಾಗಿದೆ. ಈಗ ನೀವು ನಿಮ್ಮ ಹೊಸ ಪಾಸ್‌ವರ್ಡ್ ಬಳಸಿಕೊಂಡು ಸೈನ್ ಇನ್ ಮಾಡಬಹುದು."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: ko\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:07\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Korean\n"
"Plural-Forms: nplurals=1; plural=0;\n"
@@ -1234,6 +1234,7 @@ msgstr "스킬 동기화에 실패했습니다."
msgid "Features"
msgstr "기능"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "다음 기준으로 필터링"
@@ -1911,14 +1912,6 @@ msgstr "번호 매기기 목록"
msgid "Organization"
msgstr "기관"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "전체 기간"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "전체 제목 (선택 사항)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "페이지"
@@ -2167,9 +2160,9 @@ msgstr "새로고침"
msgid "Remember your password? <0/>"
msgstr "비밀번호가 기억나시나요? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "원격"
@@ -2517,6 +2510,7 @@ msgstr "슬러그"
msgid "Something went wrong. Please try again."
msgstr "문제가 발생했습니다. 다시 시도해 주세요."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "정렬 기준"
@@ -3186,6 +3180,10 @@ msgstr "데이터는 브라우저에 로컬로 저장됩니다"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "데이터는 안전하게 저장되며 제3자와 공유되지 않습니다. 또한 Reactive Resume를 직접 서버에 호스팅해 데이터에 대한 완전한 제어권을 가질 수 있습니다."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "비밀번호가 성공적으로 재설정되었습니다. 이제 새 비밀번호로 로그인할 수 있습니다."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: lt\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:07\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Lithuanian\n"
"Plural-Forms: nplurals=4; plural=(n%10==1 && (n%100>19 || n%100<11) ? 0 : (n%10>=2 && n%10<=9) && (n%100>19 || n%100<11) ? 1 : n%1!=0 ? 2: 3);\n"
@@ -1234,6 +1234,7 @@ msgstr "Nepavyko sinchronizuoti įgūdžių"
msgid "Features"
msgstr "Funkcijos"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "Filtruoti pagal"
@@ -1911,14 +1912,6 @@ msgstr "Sunumeruotas sąrašas"
msgid "Organization"
msgstr "Organizacija"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "Bendras laikotarpis"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "Bendrasis pavadinimas (neprivaloma)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "Puslapis"
@@ -2167,9 +2160,9 @@ msgstr "Perkrauti"
msgid "Remember your password? <0/>"
msgstr "Prisimenate slaptažodį? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "Nuotolinis"
@@ -2517,6 +2510,7 @@ msgstr "Nuorodos dalis"
msgid "Something went wrong. Please try again."
msgstr "Kažkas nepavyko. Bandykite dar kartą."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "Rikiuoti pagal"
@@ -3186,6 +3180,10 @@ msgstr "Jūsų duomenys saugomi vietoje"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "Jūsų duomenys saugiai laikomi ir niekada nebendrinami su trečiosiomis šalimis. Taip pat galite savarankiškai talpinti „Reactive Resume“ savo serveriuose ir visiškai kontroliuoti savo duomenis."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "Jūsų slaptažodis sėkmingai atstatytas. Dabar galite prisijungti naudodami naują slaptažodį."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: lv\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:08\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Latvian\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2;\n"
@@ -1234,6 +1234,7 @@ msgstr "Neizdevās sinhronizēt prasmes"
msgid "Features"
msgstr "Funkcijas"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "Filtrēt pēc"
@@ -1911,14 +1912,6 @@ msgstr "Numurēts saraksts"
msgid "Organization"
msgstr "Organizācija"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "Kopējais periods"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "Kopējais nosaukums (neobligāts)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "Lapa"
@@ -2167,9 +2160,9 @@ msgstr "Atsvaidzināt"
msgid "Remember your password? <0/>"
msgstr "Atceraties paroli? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "Tālvadības pults"
@@ -2517,6 +2510,7 @@ msgstr "Tīmekļa adrese (slug)"
msgid "Something went wrong. Please try again."
msgstr "Kaut kas nogāja greizi. Lūdzu, mēģiniet vēlreiz."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "Kārtot pēc"
@@ -3186,6 +3180,10 @@ msgstr "Jūsu dati tiek glabāti lokāli"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "Jūsu dati tiek glabāti droši un nekad netiek kopīgoti ar trešajām pusēm. Reactive Resume varat arī pašhostēt uz saviem serveriem, lai pilnībā kontrolētu savus datus."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "Jūsu parole ir veiksmīgi atiestatīta. Tagad varat pieteikties ar jauno paroli."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: ml\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:08\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Malayalam\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -1234,6 +1234,7 @@ msgstr "നൈപുണ്യങ്ങൾ സിങ്ക് ചെയ്യു
msgid "Features"
msgstr "സവിശേഷതകൾ"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "ഫിൽറ്റർ ചെയ്യുക"
@@ -1911,14 +1912,6 @@ msgstr "ഓർഡേർഡ് ലിസ്റ്റ്"
msgid "Organization"
msgstr "സ്ഥാപനം"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "മൊത്തം കാലയളവ്"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "മൊത്തം ശീർഷകം (ഐച്ഛികം)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "പേജ്"
@@ -2167,9 +2160,9 @@ msgstr "റിഫ്രെഷ് ചെയ്യുക"
msgid "Remember your password? <0/>"
msgstr "നിങ്ങളുടെ പാസ്‌വേഡ് ഓർമ്മയുണ്ടോ? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "ദൂരസ്ഥ"
@@ -2517,6 +2510,7 @@ msgstr "സ്ലഗ്"
msgid "Something went wrong. Please try again."
msgstr "എന്തോ പിശക് സംഭവിച്ചു. ദയവായി വീണ്ടും ശ്രമിക്കുക."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "സോർട്ട് ചെയ്യുക"
@@ -3186,6 +3180,10 @@ msgstr "നിങ്ങളുടെ ഡാറ്റ നിങ്ങളുടെ
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "നിങ്ങളുടെ ഡാറ്റ സുരക്ഷിതമായി സൂക്ഷിക്കപ്പെടുന്നു, ഒരിക്കലും മൂന്നാം കക്ഷികളുമായി പങ്കിടുന്നില്ല. നിങ്ങളുടെ ഡാറ്റയ്‌ക്ക് പൂർണ്ണ നിയന്ത്രണം നേടാൻ Reactive Resume നിങ്ങളുടെ സ്വന്തം സെർവറുകളിൽ സെൽഫ്‑ഹോസ്റ്റ് ചെയ്യാനും നിങ്ങൾക്ക് കഴിയും."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "നിങ്ങളുടെ പാസ്‌വേഡ് വിജയകരമായി റീസെറ്റ് ചെയ്തിട്ടുണ്ട്. ഇനി നിങ്ങൾക്ക് പുതിയ പാസ്‌വേഡ് ഉപയോഗിച്ച് സൈൻ ഇൻ ചെയ്യാം."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: mr\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:08\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Marathi\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -1234,6 +1234,7 @@ msgstr "कौशल्ये समक्रमित करण्यात अ
msgid "Features"
msgstr "वैशिष्ट्ये"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "यावरून फिल्टर करा"
@@ -1911,14 +1912,6 @@ msgstr "क्रमबद्ध यादी"
msgid "Organization"
msgstr "संघटना"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "एकूण कालावधी"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "एकूण शीर्षक (पर्यायी)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "पान"
@@ -2167,9 +2160,9 @@ msgstr "ताजेतवाने करा"
msgid "Remember your password? <0/>"
msgstr "तुमचा पासवर्ड आठवतो? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "दूरस्थ"
@@ -2517,6 +2510,7 @@ msgstr "युआरएल"
msgid "Something went wrong. Please try again."
msgstr "काही तरी चूक झाली. कृपया पुन्हा प्रयत्न करा."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "यावरून क्रम लावा"
@@ -3186,6 +3180,10 @@ msgstr "तुमचा डेटा लोकली साठवला जा
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "तुमचा डेटा सुरक्षितपणे साठवला जातो आणि तृतीय पक्षांसोबत कधीही शेअर केला जात नाही. तुम्ही पूर्ण डेटा कंट्रोलसाठी Reactive Resume स्वतःच्या सर्व्हरवरही होस्ट करू शकता."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "तुमचा पासवर्ड यशस्वीरित्या रिसेट केला गेला आहे. तुम्ही आता नवीन पासवर्डने साइन इन करू शकता."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: ms\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:08\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Malay\n"
"Plural-Forms: nplurals=1; plural=0;\n"
@@ -1234,6 +1234,7 @@ msgstr "Gagal menyegerakkan kemahiran"
msgid "Features"
msgstr "Ciri"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "Tapis mengikut"
@@ -1911,14 +1912,6 @@ msgstr "Senarai Bernombor"
msgid "Organization"
msgstr "Organisasi"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "Tempoh Keseluruhan"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "Tajuk Keseluruhan (pilihan)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "Halaman"
@@ -2167,9 +2160,9 @@ msgstr "Muat semula"
msgid "Remember your password? <0/>"
msgstr "Ingat kata laluan anda? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "Jauh"
@@ -2517,6 +2510,7 @@ msgstr "Slug"
msgid "Something went wrong. Please try again."
msgstr "Ada sesuatu yang tidak kena. Sila cuba lagi."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "Isih mengikut"
@@ -3186,6 +3180,10 @@ msgstr "Data anda disimpan secara setempat"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "Data anda disimpan dengan selamat dan tidak pernah dikongsi dengan pihak ketiga. Anda juga boleh menghoskan sendiri Reactive Resume pada pelayan anda untuk kawalan penuh ke atas data anda."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "Kata laluan anda telah berjaya ditetapkan semula. Anda kini boleh log masuk dengan kata laluan baharu anda."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: ne\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:08\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Nepali\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -1234,6 +1234,7 @@ msgstr "कौशलहरू सिङ्क गर्न असफल भय
msgid "Features"
msgstr "विशेषताहरू"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "यसद्वारा फिल्टर गर्नुहोस्"
@@ -1911,14 +1912,6 @@ msgstr "क्रमबद्ध सूची"
msgid "Organization"
msgstr "संस्था"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "समग्र अवधि"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "समग्र शीर्षक (ऐच्छिक)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "पृष्ठ"
@@ -2167,9 +2160,9 @@ msgstr "रिफ्रेस गर्नुहोस्"
msgid "Remember your password? <0/>"
msgstr "पासवर्ड सम्झनुभयो? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "दूरस्थ"
@@ -2517,6 +2510,7 @@ msgstr "स्लग"
msgid "Something went wrong. Please try again."
msgstr "केही समस्या भयो। कृपया पुनः प्रयास गर्नुहोस्।"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "यसअनुसार क्रमबद्ध गर्नुहोस्"
@@ -3186,6 +3180,10 @@ msgstr "तपाईंको डाटा स्थानीय रूपमा
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "तपाईंको डाटा सुरक्षित रूपमा भण्डारण गरिएको छ र तेस्रो पक्षसँग कहिल्यै सेयर गरिँदैन। तपाईंले चाहनु भएमा आफ्नै सर्भरमा Reactive Resume लाई self-host गरेर आफ्नो डाटामा पूर्ण नियन्त्रण राख्न सक्नुहुन्छ।"
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "तपाईंको पासवर्ड सफलतापूर्वक रिसेट भयो। अब नयाँ पासवर्ड प्रयोग गरेर साइन इन गर्न सक्नुहुन्छ।"
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: nl\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:07\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Dutch\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -1234,6 +1234,7 @@ msgstr "Synchronisatie van vaardigheden mislukt"
msgid "Features"
msgstr "Functies"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "Filteren op"
@@ -1911,14 +1912,6 @@ msgstr "Genummerde lijst"
msgid "Organization"
msgstr "Organisatie"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "Totale periode"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "Algemene titel (optioneel)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "Pagina"
@@ -2167,9 +2160,9 @@ msgstr "Vernieuwen"
msgid "Remember your password? <0/>"
msgstr "Wachtwoord nog weten? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "Op afstand"
@@ -2517,6 +2510,7 @@ msgstr "Korte naam"
msgid "Something went wrong. Please try again."
msgstr "Er is iets misgegaan. Probeer het alstublieft opnieuw."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "Sorteren op"
@@ -3186,6 +3180,10 @@ msgstr "Uw gegevens worden lokaal opgeslagen"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "Uw gegevens worden veilig opgeslagen en nooit met derden gedeeld. U kunt Reactive Resume ook zelf op uw eigen servers hosten voor volledige controle over uw gegevens."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "Uw wachtwoord is succesvol gereset. U kunt nu met uw nieuwe wachtwoord inloggen."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: no\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:07\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Norwegian\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -1234,6 +1234,7 @@ msgstr ""
msgid "Features"
msgstr "Funksjoner"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "Filtrer etter"
@@ -1911,14 +1912,6 @@ msgstr "Nummerert liste"
msgid "Organization"
msgstr "Organisasjon"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "Samlet periode"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "Overordnet tittel (valgfritt)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "Side"
@@ -2167,9 +2160,9 @@ msgstr "Oppdater"
msgid "Remember your password? <0/>"
msgstr "Husker du passordet ditt? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr ""
@@ -2517,6 +2510,7 @@ msgstr "Forkortelse"
msgid "Something went wrong. Please try again."
msgstr "Noe gikk galt. Vennligst prøv igjen."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "Sorter etter"
@@ -3186,6 +3180,10 @@ msgstr "Dataene dine lagres lokalt"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "Dataene dine lagres sikkert og deles aldri med tredjeparter. Du kan også selv-hoste Reactive Resume på egne servere for full kontroll over dataene dine."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "Passordet ditt er tilbakestilt. Du kan nå logge inn med det nye passordet ditt."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: or\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:08\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Odia\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -1234,6 +1234,7 @@ msgstr ""
msgid "Features"
msgstr "ବିଶେଷତାଗୁଡିକ"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "ଏହା ଦ୍ୱାରା ଫିଲ୍ଟର୍ କରନ୍ତୁ"
@@ -1911,14 +1912,6 @@ msgstr "କ୍ରମିକ ତାଲିକା"
msgid "Organization"
msgstr "ସଂଗଠନ"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "ସାମଗ୍ରିକ ସମୟସୀମା"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "ସାମଗ୍ରିକ ଶୀର୍ଷକ (ଐଚ୍ଛିକ)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "ପେଜ୍"
@@ -2167,9 +2160,9 @@ msgstr "ରିଫ୍ରେଶ କରନ୍ତୁ"
msgid "Remember your password? <0/>"
msgstr "ଆପଣଙ୍କ ପାସୱାର୍ଡ ମନେ ଅଛି? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr ""
@@ -2517,6 +2510,7 @@ msgstr "ସ୍ଲଗ୍"
msgid "Something went wrong. Please try again."
msgstr "କିଛି ଭୁଲ୍ ହୋଇଛି। ଦୟାକରି ପୁନଃ ଚେଷ୍ଟା କରନ୍ତୁ।"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "ଏହା ଦ୍ୱାରା ସଜାଇବେ"
@@ -3186,6 +3180,10 @@ msgstr "ଆପଣଙ୍କ ତଥ୍ୟ ସ୍ଥାନୀୟ ଭାବରେ
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "ଆପଣଙ୍କ ତଥ୍ୟ ସୁରକ୍ଷିତ ଭାବରେ ସଞ୍ଚୟ ହୋଇଛି ଏବଂ କେବେ ମଧ୍ୟ ତୃତୀୟ ପକ୍ଷ ସହ ସେୟାର ହୋଇନାହିଁ। ଆପଣ ଆପଣଙ୍କ ତଥ୍ୟ ଉପରେ ପୂର୍ଣ୍ଣ ନିୟନ୍ତ୍ରଣ ପାଇଁ ଆପଣଙ୍କ ନିଜ ସର୍ଭରଗୁଡିକରେ Reactive Resume କୁ ସ୍ୱୟଂ‑ହୋଷ୍ଟ କରିପାରିବେ।"
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "ଆପଣଙ୍କ ପାସୱାର୍ଡ ସଫଳତାର ସହ ପୁନଃ ସେଟ୍ କରାଯାଇଛି। ଆପଣ ଏବେ ନୂତନ ପାସୱାର୍ଡ ସହ ସାଇନ୍ ଇନ୍ କରିପାରିବେ।"
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: pl\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:07\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Polish\n"
"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n"
@@ -1234,6 +1234,7 @@ msgstr "Nie udało się zsynchronizować umiejętności"
msgid "Features"
msgstr "Funkcje"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "Filtruj według"
@@ -1911,14 +1912,6 @@ msgstr "Lista numerowana"
msgid "Organization"
msgstr "Organizacja"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "Okres ogólny"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "Ogólny tytuł (opcjonalnie)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "Strona"
@@ -2167,9 +2160,9 @@ msgstr "Odśwież"
msgid "Remember your password? <0/>"
msgstr "Pamiętasz hasło? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "Zdalny"
@@ -2517,6 +2510,7 @@ msgstr "Krótka nazwa"
msgid "Something went wrong. Please try again."
msgstr "Coś poszło nie tak. Spróbuj ponownie."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "Sortuj według"
@@ -3186,6 +3180,10 @@ msgstr "Twoje dane są przechowywane lokalnie"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "Twoje dane są przechowywane w bezpieczny sposób i nigdy nie są udostępniane podmiotom trzecim. Możesz też samodzielnie hostować Reactive Resume na własnych serwerach, aby mieć pełną kontrolę nad swoimi danymi."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "Twoje hasło zostało pomyślnie zresetowane. Możesz teraz zalogować się przy użyciu nowego hasła."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: pt\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:07\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Portuguese, Brazilian\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -1234,6 +1234,7 @@ msgstr "Falha na sincronização de habilidades"
msgid "Features"
msgstr "Recursos"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "Filtrar por"
@@ -1911,14 +1912,6 @@ msgstr "Lista numerada"
msgid "Organization"
msgstr "Organização"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "Período geral"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "Título geral (opcional)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "Página"
@@ -2167,9 +2160,9 @@ msgstr "Atualizar"
msgid "Remember your password? <0/>"
msgstr "Lembrou sua senha? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "Remoto"
@@ -2517,6 +2510,7 @@ msgstr "Permalink"
msgid "Something went wrong. Please try again."
msgstr "Algo deu errado. Tente novamente."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "Ordenar por"
@@ -3186,6 +3180,10 @@ msgstr "Seus dados são armazenados localmente"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "Seus dados são armazenados com segurança e nunca são compartilhados com terceiros. Você também pode auto-hospedar o Reactive Resume em seus próprios servidores para ter controle total sobre seus dados."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "Sua senha foi redefinida com sucesso. Agora você pode entrar com sua nova senha."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: pt\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:07\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Portuguese\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -1234,6 +1234,7 @@ msgstr "Falha na sincronização de competências"
msgid "Features"
msgstr "Funcionalidades"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "Filtrar por"
@@ -1911,14 +1912,6 @@ msgstr "Lista ordenada"
msgid "Organization"
msgstr "Organização"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "Período geral"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "Título geral (opcional)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "Página"
@@ -2167,9 +2160,9 @@ msgstr "Recarregar"
msgid "Remember your password? <0/>"
msgstr "Lembra-se da sua palavra-passe? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "Remoto"
@@ -2517,6 +2510,7 @@ msgstr "Slug"
msgid "Something went wrong. Please try again."
msgstr "Algo correu mal. Tente novamente."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "Ordenar por"
@@ -3186,6 +3180,10 @@ msgstr "Os seus dados são armazenados localmente"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "Os seus dados são armazenados em segurança e nunca são partilhados com terceiros. Também pode auto-hospedar o Reactive Resume nos seus próprios servidores para ter controlo total sobre os seus dados."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "A sua senha foi reposta com sucesso. Já pode iniciar sessão com a sua nova senha."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: ro\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:07\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Romanian\n"
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : (n==0 || (n%100>0 && n%100<20)) ? 1 : 2);\n"
@@ -1234,6 +1234,7 @@ msgstr "A eșuat sincronizarea competențelor"
msgid "Features"
msgstr "Funcționalități"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "Filtrați după"
@@ -1911,14 +1912,6 @@ msgstr "Listă ordonată"
msgid "Organization"
msgstr "Organizație"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "Perioadă generală"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "Titlu general (opțional)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "Pagină"
@@ -2167,9 +2160,9 @@ msgstr "Reîncarcă"
msgid "Remember your password? <0/>"
msgstr "Îți amintești parola? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "La distanță"
@@ -2517,6 +2510,7 @@ msgstr "Slug"
msgid "Something went wrong. Please try again."
msgstr "Ceva nu a funcționat. Vă rugăm să încercați din nou."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "Sortați după"
@@ -3186,6 +3180,10 @@ msgstr "Datele dvs. sunt stocate local"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "Datele dvs. sunt stocate în siguranță și nu sunt niciodată partajate cu terți. De asemenea, puteți auto-găzdui Reactive Resume pe propriile servere pentru control complet asupra datelor."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "Parola a fost resetată cu succes. Vă puteți autentifica acum cu noua parolă."
+9 -11
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: ru\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:07\n"
"PO-Revision-Date: 2026-03-29 21:15\n"
"Last-Translator: \n"
"Language-Team: Russian\n"
"Plural-Forms: nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));\n"
@@ -1234,6 +1234,7 @@ msgstr "Не удалось синхронизировать навыки"
msgid "Features"
msgstr "Возможности"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "Фильтровать по"
@@ -1911,14 +1912,6 @@ msgstr "Нумерованный список"
msgid "Organization"
msgstr "Организация"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "Общий период"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "Общее название (необязательно)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "Страница"
@@ -2167,9 +2160,9 @@ msgstr "Обновить"
msgid "Remember your password? <0/>"
msgstr "Вспомнили пароль? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "Удаленный"
@@ -2505,7 +2498,7 @@ msgstr "Словацкий"
#: src/utils/locale.ts
msgid "Slovenian"
msgstr ""
msgstr "Английский"
#: src/dialogs/resume/index.tsx
msgid "Slug"
@@ -2517,6 +2510,7 @@ msgstr "URL"
msgid "Something went wrong. Please try again."
msgstr "Что-то пошло не так. Пожалуйста, попробуйте еще раз."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "Сортировать по"
@@ -3186,6 +3180,10 @@ msgstr "Ваши данные хранятся локально"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "Ваши данные надежно хранятся и никогда не передаются третьим лицам. Вы также можете развернуть Reactive Resume на своих серверах, чтобы полностью контролировать свои данные."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "Ваш пароль был успешно сброшен. Теперь вы можете войти с новым паролем."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: sk\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:07\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Slovak\n"
"Plural-Forms: nplurals=4; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 3;\n"
@@ -1234,6 +1234,7 @@ msgstr "Nepodarilo sa synchronizovať zručnosti"
msgid "Features"
msgstr "Funkcie"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "Filtrovať podľa"
@@ -1911,14 +1912,6 @@ msgstr "Číslovaný zoznam"
msgid "Organization"
msgstr "Organizácia"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "Celkové obdobie"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "Celkový titul (voliteľné)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "Strana"
@@ -2167,9 +2160,9 @@ msgstr "Obnoviť"
msgid "Remember your password? <0/>"
msgstr "Pamätáte si heslo? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "Vzdialená adresa"
@@ -2517,6 +2510,7 @@ msgstr "Slug"
msgid "Something went wrong. Please try again."
msgstr "Niečo sa pokazilo. Skús to, prosím, znova."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "Zoradiť podľa"
@@ -3186,6 +3180,10 @@ msgstr "Tvoje dáta sú uložené lokálne"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "Tvoje dáta sú bezpečne uložené a nikdy sa nezdieľajú s tretími stranami. Reactive Resume si môžeš tiež hostovať na vlastných serveroch a mať nad dátami úplnú kontrolu."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "Tvoje heslo bolo úspešne obnovené. Teraz sa môžeš prihlásiť s novým heslom."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: sl\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:07\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Slovenian\n"
"Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3;\n"
@@ -1234,6 +1234,7 @@ msgstr "Ni uspelo sinhronizirati veščin"
msgid "Features"
msgstr "Funkcionalnosti"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "Filtriraj po"
@@ -1911,14 +1912,6 @@ msgstr "Oštevilčen seznam"
msgid "Organization"
msgstr "Organizacija"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "Skupno obdobje"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "Skupni naziv (neobvezno)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "Stran"
@@ -2167,9 +2160,9 @@ msgstr "Osveži"
msgid "Remember your password? <0/>"
msgstr ""
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "Oddaljena stran"
@@ -2517,6 +2510,7 @@ msgstr "Polž"
msgid "Something went wrong. Please try again."
msgstr "Nekaj je šlo narobe. Prosimo, poskusite znova."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "Razvrsti po"
@@ -3186,6 +3180,10 @@ msgstr "Vaši podatki so shranjeni lokalno"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "Vaši podatki so varno shranjeni in se nikoli ne delijo s tretjimi osebami. Reactive Življenjepis lahko tudi gostite sami na svojih strežnikih za popoln nadzor nad svojimi podatki."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "Vaše geslo je bilo uspešno ponastavljeno. Zdaj se lahko prijavite z novim geslom."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: sq\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:07\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Albanian\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -1234,6 +1234,7 @@ msgstr "Dështoi sinkronizimi i aftësive"
msgid "Features"
msgstr "Veçori"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "Filtro sipas"
@@ -1911,14 +1912,6 @@ msgstr "Listë e renditur"
msgid "Organization"
msgstr "Organizata"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "Periudha e përgjithshme"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "Titulli i përgjithshëm (opsional)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "Faqja"
@@ -2167,9 +2160,9 @@ msgstr "Rifresko"
msgid "Remember your password? <0/>"
msgstr "Ju kujtohet fjalëkalimi? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "Në distancë"
@@ -2517,6 +2510,7 @@ msgstr "Linku i normalizuar"
msgid "Something went wrong. Please try again."
msgstr "Diçka shkoi keq. Ju lutemi provoni përsëri."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "Rendit sipas"
@@ -3186,6 +3180,10 @@ msgstr "Të dhënat tuaja ruhen lokalisht"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "Të dhënat tuaja ruhen në mënyrë të sigurt dhe nuk ndahen kurrë me palë të treta. Ju gjithashtu mund ta self-host-oni Reactive Resume në serverët tuaj për kontroll të plotë mbi të dhënat tuaja."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "Fjalëkalimi juaj u rivendos me sukses. Tani mund të hyni me fjalëkalimin tuaj të ri."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: sr\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:07\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Serbian (Cyrillic)\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
@@ -1234,6 +1234,7 @@ msgstr "Синхронизација вештина није успела"
msgid "Features"
msgstr "Функције"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "Филтрирај по"
@@ -1911,14 +1912,6 @@ msgstr "Нумерисана листа"
msgid "Organization"
msgstr "Организација"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "Укупан период"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "Укупна титула (опционо)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "Страница"
@@ -2167,9 +2160,9 @@ msgstr "Освежи"
msgid "Remember your password? <0/>"
msgstr "Сећате се лозинке? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "Даљински"
@@ -2517,6 +2510,7 @@ msgstr "Идентификатор (slug)"
msgid "Something went wrong. Please try again."
msgstr "Нешто је пошло наопако. Покушајте поново."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "Сортирај по"
@@ -3186,6 +3180,10 @@ msgstr "Ваши подаци се чувају локално"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "Ваши подаци се чувају безбедно и никада се не деле са трећим странама. Такође можете самостално хостовати Реактивни Резиме на сопственим серверима за потпуну контролу над подацима."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "Ваша лозинка је успешно ресетована. Сада можете да се пријавите новом лозинком."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: sv\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:07\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Swedish\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -1234,6 +1234,7 @@ msgstr "Misslyckades med att synkronisera färdigheter"
msgid "Features"
msgstr "Funktioner"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "Filtrera efter"
@@ -1911,14 +1912,6 @@ msgstr "Numrerad lista"
msgid "Organization"
msgstr "Organisation"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "Övergripande period"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "Övergripande titel (valfritt)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "Sida"
@@ -2167,9 +2160,9 @@ msgstr "Uppdatera"
msgid "Remember your password? <0/>"
msgstr "Kommer du ihåg ditt lösenord? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "Fjärrkontroll"
@@ -2517,6 +2510,7 @@ msgstr "Slug"
msgid "Something went wrong. Please try again."
msgstr "Något gick fel. Försök igen."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "Sortera efter"
@@ -3186,6 +3180,10 @@ msgstr "Dina data lagras lokalt"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "Dina data lagras säkert och delas aldrig med tredje part. Du kan också själv hosta Reactive Resume på dina egna servrar för full kontroll över dina data."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "Ditt lösenord har återställts. Du kan nu logga in med ditt nya lösenord."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: ta\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:08\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Tamil\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -1234,6 +1234,7 @@ msgstr "திறன்களை ஒத்திசைக்கத் தவற
msgid "Features"
msgstr "அம்சங்கள்"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "இதன்படி வடிகட்டு"
@@ -1911,14 +1912,6 @@ msgstr "வரிசைப்படுத்தப்பட்ட பட்ட
msgid "Organization"
msgstr "நிறுவனம் / அமைப்பு"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "ஒட்டுமொத்த காலம்"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "ஒட்டுமொத்த தலைப்பு (விருப்பத்தேர்வு)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "பக்கம்"
@@ -2167,9 +2160,9 @@ msgstr "மீண்டும் ஏற்று"
msgid "Remember your password? <0/>"
msgstr "உங்கள் கடவுச்சொல் நினைவிருக்கிறதா? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "தொலைநிலை"
@@ -2517,6 +2510,7 @@ msgstr "ஸ்லக்"
msgid "Something went wrong. Please try again."
msgstr "ஏதோ தவறு நடந்துள்ளது. தயவுசெய்து மீண்டும் முயற்சிக்கவும்."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "இதன்படி வரிசைப்படுத்து"
@@ -3186,6 +3180,10 @@ msgstr "உங்கள் தரவு உங்கள் உலாவியி
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "உங்கள் தரவு பாதுகாப்பாக சேமிக்கப்படுகிறது மற்றும் மூன்றாம் தரப்புகளுடன் ஒருபோதும் பகிரப்படாது. உங்கள் தரவு மீது முழு கட்டுப்பாட்டிற்காக Reactive Resume-ஐ உங்கள் சொந்த சேவையகங்களில் தானே ஹோஸ்ட் செய்யவும் முடியும்."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "உங்கள் கடவுச்சொல் வெற்றிகரமாக மீட்டமைக்கப்பட்டுள்ளது. இப்போது உங்கள் புதிய கடவுச்சொல்லைப் பயன்படுத்தி உள்நுழையலாம்."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: te\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:08\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Telugu\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -1234,6 +1234,7 @@ msgstr "నైపుణ్యాలను సింక్ చేయడంలో
msgid "Features"
msgstr "ఫీచర్లు"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "ద్వారా ఫిల్టర్ చేయండి"
@@ -1911,14 +1912,6 @@ msgstr "ఆర్డర్డ్ లిస్ట్"
msgid "Organization"
msgstr "ఆర్గనైజేషన్"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "మొత్తం కాలం"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "మొత్తం శీర్షిక (ఐచ్ఛికం)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "పేజ్"
@@ -2167,9 +2160,9 @@ msgstr "రిఫ్రెష్ చేయండి"
msgid "Remember your password? <0/>"
msgstr "మీ పాస్‌వర్డ్ గుర్తుందా? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "రిమోట్"
@@ -2517,6 +2510,7 @@ msgstr "స్లగ్"
msgid "Something went wrong. Please try again."
msgstr "ఏదో తప్పు జరిగింది. దయచేసి మళ్లీ ప్రయత్నించండి."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "సორტ్ చేయండి"
@@ -3186,6 +3180,10 @@ msgstr "మీ డేటా లోకల్‌గా నిల్వ చేయ
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "మీ డేటా భద్రంగా నిల్వ చేయబడుతుంది, మూడవ పక్షాలతో ఎప్పుడూ పంచుకోబడదు. మీ డేటాపై పూర్తి నియంత్రణ కోసం మీరు Reactive Resumeను మీ సొంత సర్వర్లపై హోస్ట్ చేసుకోవచ్చు."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "మీ పాస్‌వర్డ్ విజయవంతంగా రీసెట్ చేయబడింది. ఇప్పుడు మీ కొత్త పాస్‌వర్డ్‌తో సైన్ ఇన్ చేయవచ్చు."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: th\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:08\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Thai\n"
"Plural-Forms: nplurals=1; plural=0;\n"
@@ -1234,6 +1234,7 @@ msgstr "ไม่สามารถซิงค์ทักษะได้"
msgid "Features"
msgstr "คุณสมบัติ"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "กรองโดย"
@@ -1911,14 +1912,6 @@ msgstr "ลำดับรายการแบบเรียงลำดับ
msgid "Organization"
msgstr "องค์กร"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "ช่วงเวลาโดยรวม"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "ตำแหน่งโดยรวม (ไม่บังคับ)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "หน้า"
@@ -2167,9 +2160,9 @@ msgstr "รีเฟรช"
msgid "Remember your password? <0/>"
msgstr "จำรหัสผ่านได้? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "ระยะไกล"
@@ -2517,6 +2510,7 @@ msgstr "ชื่อ"
msgid "Something went wrong. Please try again."
msgstr "เกิดข้อผิดพลาดบางอย่าง กรุณาลองใหม่อีกครั้ง"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "เรียงตาม"
@@ -3186,6 +3180,10 @@ msgstr "ข้อมูลของคุณถูกจัดเก็บไว
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "ข้อมูลของคุณถูกจัดเก็บไว้อย่างปลอดภัยและจะไม่ถูกแชร์กับบุคคลที่สาม คุณยังสามารถโฮสต์ Reactive Resume ด้วยตัวเองบนเซิร์ฟเวอร์ของคุณเพื่อควบคุมข้อมูลได้อย่างสมบูรณ์."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "รหัสผ่านของคุณถูกรีเซ็ตเรียบร้อยแล้ว ตอนนี้คุณสามารถเข้าสู่ระบบด้วยรหัสผ่านใหม่ของคุณได้."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: tr\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:07\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Turkish\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -1234,6 +1234,7 @@ msgstr "Beceriler senkronize edilemedi"
msgid "Features"
msgstr "Özellikler"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "Filtrele"
@@ -1911,14 +1912,6 @@ msgstr "Sıralı Liste"
msgid "Organization"
msgstr "Organizasyon"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "Genel Dönem"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "Genel Başlık (isteğe bağlı)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "Sayfa"
@@ -2167,9 +2160,9 @@ msgstr "Yenile"
msgid "Remember your password? <0/>"
msgstr "Şifrenizi hatırladınız mı? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "Uzaktan Kumanda"
@@ -2517,6 +2510,7 @@ msgstr "Slug"
msgid "Something went wrong. Please try again."
msgstr "Bir hata oluştu. Lütfen tekrar deneyin."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "Sırala"
@@ -3186,6 +3180,10 @@ msgstr "Verileriniz yerel olarak depolanıyor"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "Verileriniz güvenli bir şekilde saklanır ve asla üçüncü partilerle paylaşılmaz. Kendi sunucularınızda Reactive Resume'u barındırarak verileriniz üzerinde tam kontrol sahibi olabilirsiniz."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "Şifreniz başarıyla sıfırlandı. Artık yeni şifrenizle giriş yapabilirsiniz."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: uk\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:07\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Ukrainian\n"
"Plural-Forms: nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));\n"
@@ -1234,6 +1234,7 @@ msgstr "Не вдалося синхронізувати навички"
msgid "Features"
msgstr "Функції"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "Фільтрувати за"
@@ -1911,14 +1912,6 @@ msgstr "Нумерований список"
msgid "Organization"
msgstr "Організація"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "Загальний період"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "Загальна назва (необов'язково)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "Сторінка"
@@ -2167,9 +2160,9 @@ msgstr "Оновити"
msgid "Remember your password? <0/>"
msgstr "Пригадали пароль? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "Пульт дистанційного керування"
@@ -2517,6 +2510,7 @@ msgstr "Посилання"
msgid "Something went wrong. Please try again."
msgstr "Щось пішло не так. Будь ласка, спробуйте ще раз."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "Сортувати за"
@@ -3186,6 +3180,10 @@ msgstr "Ваші дані зберігаються локально"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "Ваші дані зберігаються безпечно і ніколи не передаються третім особам. Ви також можете самостійно розгорнути Reactive Resume на власних серверах для повного контролю над своїми даними."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "Ваш пароль було успішно скинуто. Тепер ви можете увійти з новим паролем."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: uz\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:08\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Uzbek\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
@@ -1234,6 +1234,7 @@ msgstr "Mahoratlarni sinxronlashtirish muvaffaqiyatsiz bo'ldi"
msgid "Features"
msgstr "Xususiyatlar"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "Saralash"
@@ -1911,14 +1912,6 @@ msgstr "Tartibli roʻyxat"
msgid "Organization"
msgstr "Tashkilot"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "Umumiy davr"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "Umumiy sarlavha (ixtiyoriy)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "Sahifa"
@@ -2167,9 +2160,9 @@ msgstr "Yangilash"
msgid "Remember your password? <0/>"
msgstr "Parolingizni eslaysizmi? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "Masofaviy"
@@ -2517,6 +2510,7 @@ msgstr "Slug"
msgid "Something went wrong. Please try again."
msgstr "Nimadir xato ketdi. Iltimos, qayta urinib koʻring."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "Saralash boʻyicha"
@@ -3186,6 +3180,10 @@ msgstr "Maʼlumotlaringiz lokal tarzda saqlanadi"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "Maʼlumotlaringiz xavfsiz saqlanadi va uchinchi tomonlarga hech qachon ulashilmaydi. Shuningdek, rezyume qurilmasini o‘z serverlaringizda mustaqil joylashtirishingiz va maʼlumotlaringiz ustidan to‘liq nazorat qilishingiz mumkin."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "Parolingiz muvaffaqiyatli tiklandi. Endi yangi parolingiz bilan tizimga kirishingiz mumkin."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: vi\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:07\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Vietnamese\n"
"Plural-Forms: nplurals=1; plural=0;\n"
@@ -1234,6 +1234,7 @@ msgstr "Không đồng bộ hóa được các kỹ năng"
msgid "Features"
msgstr "Tính năng"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "Lọc theo"
@@ -1911,14 +1912,6 @@ msgstr "Danh sách có thứ tự"
msgid "Organization"
msgstr "Tổ chức"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "Thời gian tổng thể"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "Chức danh tổng thể (tùy chọn)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "Trang"
@@ -2167,9 +2160,9 @@ msgstr "Làm mới"
msgid "Remember your password? <0/>"
msgstr "Nhớ mật khẩu? <0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "Từ xa"
@@ -2517,6 +2510,7 @@ msgstr "Slug"
msgid "Something went wrong. Please try again."
msgstr "Đã xảy ra lỗi. Vui lòng thử lại."
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "Sắp xếp theo"
@@ -3186,6 +3180,10 @@ msgstr "Dữ liệu của bạn được lưu trữ cục bộ"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "Dữ liệu của bạn được lưu trữ an toàn và không bao giờ chia sẻ với bên thứ ba. Bạn cũng có thể tự host Reactive Resume trên máy chủ của riêng mình để kiểm soát hoàn toàn dữ liệu của mình."
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "Mật khẩu của bạn đã được đặt lại thành công. Bây giờ bạn có thể đăng nhập bằng mật khẩu mới."
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: zh\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:07\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Chinese Simplified\n"
"Plural-Forms: nplurals=1; plural=0;\n"
@@ -1234,6 +1234,7 @@ msgstr "同步技能失败"
msgid "Features"
msgstr "功能"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "筛选条件"
@@ -1911,14 +1912,6 @@ msgstr "有序列表"
msgid "Organization"
msgstr "组织"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "总时间段"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "总标题(可选)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "页面"
@@ -2167,9 +2160,9 @@ msgstr "刷新"
msgid "Remember your password? <0/>"
msgstr "记得密码?<0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "远程"
@@ -2517,6 +2510,7 @@ msgstr "短链接"
msgid "Something went wrong. Please try again."
msgstr "出现了一些问题。请重试。"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "排序方式"
@@ -3186,6 +3180,10 @@ msgstr "你的数据将存储在本地"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "你的数据会被安全存储,且绝不会与第三方共享。你也可以在自己的服务器上自托管 Reactive Resume,以完全掌控你的数据。"
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "你的密码已成功重置。你现在可以使用新密码登录。"
+8 -10
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: zh\n"
"Project-Id-Version: reactive-resume\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-03-19 09:07\n"
"PO-Revision-Date: 2026-03-29 21:05\n"
"Last-Translator: \n"
"Language-Team: Chinese Traditional\n"
"Plural-Forms: nplurals=1; plural=0;\n"
@@ -1234,6 +1234,7 @@ msgstr "同步技能失敗"
msgid "Features"
msgstr "功能"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr "篩選條件"
@@ -1911,14 +1912,6 @@ msgstr "編號清單"
msgid "Organization"
msgstr "組織"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr "整體期間"
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr "整體標題(選填)"
#: src/utils/resume/section.tsx
msgid "Page"
msgstr "頁"
@@ -2167,9 +2160,9 @@ msgstr "重新整理"
msgid "Remember your password? <0/>"
msgstr "記得密碼?<0/>"
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr "遙控"
@@ -2517,6 +2510,7 @@ msgstr "標示碼"
msgid "Something went wrong. Please try again."
msgstr "發生錯誤。請再試一次。"
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr "排序方式"
@@ -3186,6 +3180,10 @@ msgstr "您的資料將儲存在本機裝置中"
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr "您的資料會被安全保存,且絕不會分享給第三方。您也可以在自有伺服器上自行託管 Reactive Resume,完全掌控自己的資料。"
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr "您的密碼已成功重設。您現在可以使用新密碼登入。"
+7 -9
View File
@@ -1229,6 +1229,7 @@ msgstr ""
msgid "Features"
msgstr ""
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Filter by"
msgstr ""
@@ -1906,14 +1907,6 @@ msgstr ""
msgid "Organization"
msgstr ""
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Period"
msgstr ""
#: src/dialogs/resume/sections/experience.tsx
msgid "Overall Title (optional)"
msgstr ""
#: src/utils/resume/section.tsx
msgid "Page"
msgstr ""
@@ -2162,9 +2155,9 @@ msgstr ""
msgid "Remember your password? <0/>"
msgstr ""
#: src/routes/dashboard/job-search/-components/job-card.tsx
#: src/routes/dashboard/job-search/-components/job-detail.tsx
#: src/routes/dashboard/job-search/-components/search-filters.tsx
#: src/routes/dashboard/job-search/index.tsx
msgid "Remote"
msgstr ""
@@ -2512,6 +2505,7 @@ msgstr ""
msgid "Something went wrong. Please try again."
msgstr ""
#: src/routes/dashboard/resumes/index.tsx
#: src/routes/dashboard/resumes/index.tsx
msgid "Sort by"
msgstr ""
@@ -3181,6 +3175,10 @@ msgstr ""
msgid "Your data is stored securely and is never shared with third parties. You can also self-host Reactive Resume on your own servers for complete control over your data."
msgstr ""
#: src/components/resume/store/resume.ts
msgid "Your latest changes could not be saved. Please make sure you are connected to the internet and try again."
msgstr ""
#: src/routes/auth/reset-password.tsx
msgid "Your password has been reset successfully. You can now sign in with your new password."
msgstr ""
@@ -0,0 +1,5 @@
ALTER TABLE "session" ADD COLUMN "impersonated_by" text;--> statement-breakpoint
ALTER TABLE "user" ADD COLUMN "role" text DEFAULT 'user';--> statement-breakpoint
ALTER TABLE "user" ADD COLUMN "banned" boolean DEFAULT false;--> statement-breakpoint
ALTER TABLE "user" ADD COLUMN "ban_reason" text;--> statement-breakpoint
ALTER TABLE "user" ADD COLUMN "ban_expires" timestamp(6) with time zone;
File diff suppressed because it is too large Load Diff
+48 -46
View File
@@ -1,6 +1,6 @@
{
"name": "reactive-resume",
"version": "5.0.14",
"version": "5.0.16",
"description": "Reactive Resume is a free and open-source resume builder that simplifies the process of creating, updating, and sharing your resume.",
"license": "MIT",
"author": {
@@ -31,13 +31,14 @@
"preview": "vp preview",
"start": "node .output/server/index.mjs",
"test": "vp test",
"test:coverage": "vp test --coverage --run",
"typecheck": "tsgo --noEmit"
},
"dependencies": {
"@ai-sdk/anthropic": "^3.0.64",
"@ai-sdk/google": "^3.0.53",
"@ai-sdk/openai": "^3.0.48",
"@aws-sdk/client-s3": "^3.1015.0",
"@ai-sdk/anthropic": "^3.0.66",
"@ai-sdk/google": "^3.0.58",
"@ai-sdk/openai": "^3.0.50",
"@aws-sdk/client-s3": "^3.1024.0",
"@base-ui/react": "^1.3.0",
"@better-auth/api-key": "^1.5.6",
"@better-auth/drizzle-adapter": "^1.5.6",
@@ -48,34 +49,34 @@
"@dnd-kit/utilities": "^3.2.2",
"@fontsource-variable/ibm-plex-sans": "^5.2.8",
"@hookform/resolvers": "^5.2.2",
"@lingui/core": "^5.9.3",
"@lingui/react": "^5.9.3",
"@modelcontextprotocol/sdk": "^1.27.1",
"@lingui/core": "^5.9.4",
"@lingui/react": "^5.9.4",
"@modelcontextprotocol/sdk": "^1.29.0",
"@monaco-editor/react": "4.8.0-rc.3",
"@orpc/client": "^1.13.9",
"@orpc/json-schema": "^1.13.9",
"@orpc/openapi": "^1.13.9",
"@orpc/server": "^1.13.9",
"@orpc/tanstack-query": "^1.13.9",
"@orpc/zod": "^1.13.9",
"@orpc/client": "^1.13.13",
"@orpc/json-schema": "^1.13.13",
"@orpc/openapi": "^1.13.13",
"@orpc/server": "^1.13.13",
"@orpc/tanstack-query": "^1.13.13",
"@orpc/zod": "^1.13.13",
"@phosphor-icons/react": "^2.1.10",
"@phosphor-icons/web": "^2.1.2",
"@sindresorhus/slugify": "^3.0.0",
"@t3-oss/env-core": "^0.13.11",
"@tanstack/react-query": "^5.95.2",
"@tanstack/react-router": "^1.168.3",
"@tanstack/react-query": "^5.96.2",
"@tanstack/react-router": "^1.168.10",
"@tanstack/react-router-ssr-query": "^1.166.10",
"@tanstack/react-start": "^1.167.5",
"@tanstack/react-start": "^1.167.16",
"@tanstack/zod-adapter": "^1.166.9",
"@tiptap/extension-highlight": "^3.20.4",
"@tiptap/extension-table": "^3.20.4",
"@tiptap/extension-text-align": "^3.20.4",
"@tiptap/pm": "^3.20.4",
"@tiptap/react": "^3.20.4",
"@tiptap/starter-kit": "^3.20.4",
"@tiptap/extension-highlight": "^3.22.1",
"@tiptap/extension-table": "^3.22.1",
"@tiptap/extension-text-align": "^3.22.1",
"@tiptap/pm": "^3.22.1",
"@tiptap/react": "^3.22.1",
"@tiptap/starter-kit": "^3.22.1",
"@uiw/color-convert": "^2.9.6",
"@uiw/react-color-colorful": "^2.9.6",
"ai": "^6.0.137",
"ai": "^6.0.146",
"ai-sdk-ollama": "^3.8.2",
"bcrypt": "^6.0.0",
"better-auth": "^1.5.6",
@@ -84,32 +85,32 @@
"cmdk": "^1.1.1",
"docx": "^9.6.1",
"dompurify": "^3.3.3",
"drizzle-orm": "1.0.0-beta.19",
"drizzle-zod": "^1.0.0-beta.14-a36c63d",
"drizzle-orm": "1.0.0-beta.20",
"drizzle-zod": "1.0.0-beta.9-e89174b",
"es-toolkit": "^1.45.1",
"fast-deep-equal": "^3.1.3",
"fast-json-patch": "^3.1.1",
"fuse.js": "^7.1.0",
"fuse.js": "^7.2.0",
"immer": "^11.1.4",
"js-cookie": "^3.0.5",
"jsonrepair": "^3.13.3",
"monaco-editor": "^0.55.1",
"motion": "^12.38.0",
"nodemailer": "^8.0.3",
"nodemailer": "^8.0.4",
"pg": "^8.20.0",
"puppeteer-core": "^24.40.0",
"qrcode.react": "^4.2.0",
"react": "^19.2.4",
"react-dom": "^19.2.4",
"react-hook-form": "^7.72.0",
"react-hook-form": "^7.72.1",
"react-hotkeys-hook": "^5.2.4",
"react-resizable-panels": "^4.7.5",
"react-resizable-panels": "^4.9.0",
"react-window": "^2.2.7",
"react-zoom-pan-pinch": "^3.7.0",
"shadcn": "^4.1.0",
"shadcn": "^4.1.2",
"sharp": "^0.34.5",
"sonner": "^2.0.7",
"srvx": "^0.11.13",
"srvx": "^0.11.15",
"tailwind-merge": "^3.5.0",
"tailwindcss": "^4.2.2",
"ts-pattern": "^5.9.0",
@@ -124,36 +125,37 @@
},
"devDependencies": {
"@babel/core": "^7.29.0",
"@lingui/babel-plugin-lingui-macro": "^5.9.3",
"@lingui/cli": "^5.9.3",
"@lingui/vite-plugin": "^5.9.3",
"@lingui/babel-plugin-lingui-macro": "^5.9.4",
"@lingui/cli": "^5.9.4",
"@lingui/vite-plugin": "^5.9.4",
"@rolldown/plugin-babel": "^0.2.2",
"@tailwindcss/vite": "^4.2.2",
"@testing-library/react": "^16.3.2",
"@types/bcrypt": "^6.0.0",
"@types/js-cookie": "^3.0.6",
"@types/node": "^25.5.0",
"@types/node": "^25.5.2",
"@types/nodemailer": "^7.0.11",
"@types/pg": "^8.20.0",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"@typescript/native-preview": "7.0.0-dev.20260324.1",
"@typescript/native-preview": "7.0.0-dev.20260404.1",
"@vitejs/plugin-react": "^6.0.1",
"@vitest/coverage-v8": "^4.1.2",
"babel-plugin-macros": "^3.1.0",
"drizzle-kit": "1.0.0-beta.19",
"drizzle-kit": "1.0.0-beta.20",
"happy-dom": "^20.8.9",
"jose": "^6.2.2",
"jsdom": "^29.0.1",
"knip": "^6.0.4",
"knip": "^6.3.0",
"nitro": "3.0.260311-beta",
"node-addon-api": "^8.6.0",
"node-addon-api": "^8.7.0",
"node-gyp": "^12.2.0",
"npm-check-updates": "^19.6.5",
"tsx": "^4.21.0",
"vite": "npm:@voidzero-dev/vite-plus-core@latest",
"npm-check-updates": "^20.0.0",
"vite": "npm:@voidzero-dev/vite-plus-core@^0.1.15",
"vite-plugin-pwa": "^1.2.0",
"vite-plus": "latest",
"vitest": "npm:@voidzero-dev/vite-plus-test@latest"
"vitest": "npm:@voidzero-dev/vite-plus-test@^0.1.15"
},
"packageManager": "pnpm@10.32.1+sha512.a706938f0e89ac1456b6563eab4edf1d1faf3368d1191fc5c59790e96dc918e4456ab2e67d613de1043d2e8c81f87303e6b40d4ffeca9df15ef1ad567348f2be",
"packageManager": "pnpm@10.33.0+sha512.10568bb4a6afb58c9eb3630da90cc9516417abebd3fabbe6739f0ae795728da1491e9db5a544c76ad8eb7570f5c4bb3d6c637b2cb41bfdcdb47fa823c8649319",
"pnpm": {
"overrides": {
"@isaacs/brace-expansion": "^5.0.1",
+2369 -2053
View File
File diff suppressed because it is too large Load Diff
+2 -4
View File
@@ -192,8 +192,7 @@ export async function migrateResumes() {
process.exit(0);
};
process.on("SIGINT", handleShutdown);
process.on("SIGTERM", handleShutdown);
process.on("exit", handleShutdown);
// Initialize the importer
const importer = new ReactiveResumeV4JSONImporter();
@@ -465,8 +464,7 @@ export async function migrateResumes() {
}
// Remove signal handlers
process.off("SIGINT", handleShutdown);
process.off("SIGTERM", handleShutdown);
process.off("exit", handleShutdown);
const migrationEnd = performance.now();
const migrationDurationMs = migrationEnd - migrationStart;
+2 -4
View File
@@ -186,8 +186,7 @@ export async function migrateUsers() {
process.exit(0);
};
process.on("SIGINT", handleShutdown);
process.on("SIGTERM", handleShutdown);
process.on("exit", handleShutdown);
while (hasMore) {
// Check if shutdown was requested
@@ -409,8 +408,7 @@ export async function migrateUsers() {
}
// Remove signal handlers
process.off("SIGINT", handleShutdown);
process.off("SIGTERM", handleShutdown);
process.off("exit", handleShutdown);
const migrationEnd = performance.now();
const migrationDurationMs = migrationEnd - migrationStart;
+5 -15
View File
@@ -69,28 +69,18 @@ export const CometCard = ({
<motion.div
ref={ref}
initial={{ scale: 1, z: 0 }}
className="relative rounded-md"
style={{
rotateX: rotateX,
rotateY: rotateY,
translateX: translateX,
translateY: translateY,
willChange: "transform",
}}
whileHover={{ z: 50, scale: scaleFactor, transition: { duration: 0.2 } }}
onMouseMove={handleMouseMove}
onMouseLeave={handleMouseLeave}
className="relative rounded-md will-change-transform"
whileHover={{ z: 50, scale: scaleFactor, transition: { duration: 0.2 } }}
style={{ rotateX: rotateX, rotateY: rotateY, translateX: translateX, translateY: translateY }}
>
{children}
<motion.div
transition={{ duration: 0.2 }}
style={{
background: glareBackground,
opacity: glareOpacity,
willChange: "opacity",
}}
className="pointer-events-none absolute inset-0 z-50 h-full w-full rounded-md mix-blend-overlay"
style={{ background: glareBackground, opacity: glareOpacity }}
className="pointer-events-none absolute inset-0 z-50 h-full w-full rounded-md mix-blend-overlay will-change-[opacity]"
/>
</motion.div>
</div>
+3 -10
View File
@@ -33,8 +33,7 @@ export const Spotlight = ({
<motion.div
animate={{ x: [0, xOffset, 0] }}
transition={{ duration, repeat: Infinity, repeatType: "reverse", ease: "easeInOut" }}
className="pointer-events-none absolute inset-s-0 top-0 z-40 h-svh w-svw"
style={{ willChange: "transform" }}
className="pointer-events-none absolute inset-s-0 top-0 z-40 h-svh w-svw will-change-transform"
>
<div
className="absolute inset-s-0 top-0"
@@ -69,14 +68,8 @@ export const Spotlight = ({
<motion.div
animate={{ x: [0, -xOffset, 0] }}
className="pointer-events-none absolute inset-e-0 top-0 z-40 h-svh w-svw"
transition={{
duration,
repeat: Infinity,
ease: "easeInOut",
repeatType: "reverse",
}}
style={{ willChange: "transform" }}
transition={{ duration, repeat: Infinity, ease: "easeInOut", repeatType: "reverse" }}
className="pointer-events-none absolute inset-e-0 top-0 z-40 h-svh w-svw will-change-transform"
>
<div
className="absolute inset-e-0 top-0"
+251
View File
@@ -0,0 +1,251 @@
import { cleanup, fireEvent, render, screen } from "@testing-library/react";
import { afterEach, describe, expect, it, vi } from "vite-plus/test";
afterEach(cleanup);
// Mock dnd-kit
vi.mock("@dnd-kit/core", () => ({
DndContext: ({ children }: { children: React.ReactNode }) => <>{children}</>,
closestCenter: vi.fn(),
KeyboardSensor: vi.fn(),
PointerSensor: vi.fn(),
useSensor: vi.fn(() => ({})),
useSensors: vi.fn(() => []),
}));
vi.mock("@dnd-kit/sortable", () => ({
SortableContext: ({ children }: { children: React.ReactNode }) => <>{children}</>,
horizontalListSortingStrategy: vi.fn(),
sortableKeyboardCoordinates: vi.fn(),
useSortable: () => ({
attributes: {},
listeners: {},
setNodeRef: vi.fn(),
transform: null,
transition: null,
isDragging: false,
}),
}));
vi.mock("@dnd-kit/utilities", () => ({
CSS: { Transform: { toString: () => "" } },
}));
// Mock framer motion
vi.mock("motion/react", () => ({
motion: {
div: ({ children, ...props }: any) => <div {...props}>{children}</div>,
},
}));
// Mock lingui
vi.mock("@lingui/react/macro", () => ({
Trans: ({ children }: { children: React.ReactNode }) => <>{children}</>,
}));
// Mock phosphor icons
vi.mock("@phosphor-icons/react", () => ({
PencilSimpleIcon: ({ className }: any) => <span data-testid="edit-icon" className={className} />,
XIcon: ({ className }: any) => <span data-testid="remove-icon" className={className} />,
}));
import { ChipInput } from "./chip-input";
describe("ChipInput", () => {
describe("rendering", () => {
it("renders the input field", () => {
render(<ChipInput />);
expect(screen.getByRole("textbox")).toBeDefined();
});
it("renders existing chips", () => {
render(<ChipInput value={["React", "TypeScript", "Node"]} />);
expect(screen.getByText("React")).toBeDefined();
expect(screen.getByText("TypeScript")).toBeDefined();
expect(screen.getByText("Node")).toBeDefined();
});
it("renders no chips when value is empty", () => {
render(<ChipInput value={[]} />);
// Only the input area, no chip badges
expect(screen.queryByText("React")).toBeNull();
});
it("shows description by default", () => {
render(<ChipInput />);
expect(screen.getByText(/Enter/)).toBeDefined();
});
it("hides description when hideDescription is true", () => {
render(<ChipInput hideDescription />);
expect(screen.queryByText(/Enter/)).toBeNull();
});
});
describe("adding chips via Enter key", () => {
it("adds a chip when Enter is pressed", () => {
const onChange = vi.fn();
render(<ChipInput value={[]} onChange={onChange} />);
const input = screen.getByRole("textbox");
fireEvent.change(input, { target: { value: "React" } });
fireEvent.keyDown(input, { key: "Enter" });
expect(onChange).toHaveBeenCalledWith(["React"]);
});
it("does not add empty chips", () => {
const onChange = vi.fn();
render(<ChipInput value={[]} onChange={onChange} />);
const input = screen.getByRole("textbox");
fireEvent.change(input, { target: { value: " " } });
fireEvent.keyDown(input, { key: "Enter" });
expect(onChange).not.toHaveBeenCalled();
});
it("trims whitespace from chips", () => {
const onChange = vi.fn();
render(<ChipInput value={[]} onChange={onChange} />);
const input = screen.getByRole("textbox");
fireEvent.change(input, { target: { value: " React " } });
fireEvent.keyDown(input, { key: "Enter" });
expect(onChange).toHaveBeenCalledWith(["React"]);
});
it("prevents duplicate chips", () => {
const onChange = vi.fn();
render(<ChipInput value={["React"]} onChange={onChange} />);
const input = screen.getByRole("textbox");
fireEvent.change(input, { target: { value: "React" } });
fireEvent.keyDown(input, { key: "Enter" });
// Set is used, so duplicates are filtered — onChange should be called with same array
expect(onChange).toHaveBeenCalledWith(["React"]);
});
});
describe("adding chips via comma", () => {
it("adds a chip when comma is typed in the input", () => {
const onChange = vi.fn();
render(<ChipInput value={[]} onChange={onChange} />);
const input = screen.getByRole("textbox");
fireEvent.change(input, { target: { value: "React," } });
expect(onChange).toHaveBeenCalledWith(["React"]);
});
it("handles multiple comma-separated values", () => {
const onChange = vi.fn();
render(<ChipInput value={[]} onChange={onChange} />);
const input = screen.getByRole("textbox");
fireEvent.change(input, { target: { value: "React,TypeScript," } });
// First call adds "React", second call adds "TypeScript"
expect(onChange).toHaveBeenCalled();
});
});
describe("removing chips", () => {
it("calls onChange without the removed chip when remove button is clicked", () => {
const onChange = vi.fn();
render(<ChipInput value={["React", "Vue", "Angular"]} onChange={onChange} />);
// Find all remove buttons
const removeButtons = screen.getAllByLabelText(/Remove/);
fireEvent.click(removeButtons[1]); // Remove "Vue"
expect(onChange).toHaveBeenCalledWith(["React", "Angular"]);
});
it("removes the first chip correctly", () => {
const onChange = vi.fn();
render(<ChipInput value={["A", "B", "C"]} onChange={onChange} />);
const removeButtons = screen.getAllByLabelText(/Remove/);
fireEvent.click(removeButtons[0]);
expect(onChange).toHaveBeenCalledWith(["B", "C"]);
});
it("removes the last chip correctly", () => {
const onChange = vi.fn();
render(<ChipInput value={["A", "B", "C"]} onChange={onChange} />);
const removeButtons = screen.getAllByLabelText(/Remove/);
fireEvent.click(removeButtons[2]);
expect(onChange).toHaveBeenCalledWith(["A", "B"]);
});
});
describe("editing chips", () => {
it("enters edit mode when edit button is clicked", () => {
render(<ChipInput value={["React", "Vue"]} />);
const editButtons = screen.getAllByLabelText(/Edit/);
fireEvent.click(editButtons[0]);
const input = screen.getByRole("textbox");
expect((input as HTMLInputElement).value).toBe("React");
expect(input.getAttribute("aria-label")).toBe("Edit keyword");
});
it("exits edit mode with Escape key", () => {
render(<ChipInput value={["React"]} />);
const editButton = screen.getByLabelText("Edit React");
fireEvent.click(editButton);
const input = screen.getByRole("textbox");
fireEvent.keyDown(input, { key: "Escape" });
expect((input as HTMLInputElement).value).toBe("");
expect(input.getAttribute("aria-label")).toBe("Add keyword");
});
it("saves edit when Enter is pressed", () => {
const onChange = vi.fn();
render(<ChipInput value={["React"]} onChange={onChange} />);
const editButton = screen.getByLabelText("Edit React");
fireEvent.click(editButton);
const input = screen.getByRole("textbox");
fireEvent.change(input, { target: { value: "React.js" } });
fireEvent.keyDown(input, { key: "Enter" });
expect(onChange).toHaveBeenCalledWith(["React.js"]);
});
});
describe("input placeholder", () => {
it("shows 'Add a keyword...' by default", () => {
render(<ChipInput />);
expect(screen.getByPlaceholderText("Add a keyword...")).toBeDefined();
});
it("shows 'Editing keyword...' in edit mode", () => {
render(<ChipInput value={["Test"]} />);
const editButton = screen.getByLabelText("Edit Test");
fireEvent.click(editButton);
expect(screen.getByPlaceholderText("Editing keyword...")).toBeDefined();
});
});
describe("uncontrolled mode", () => {
it("works with defaultValue", () => {
render(<ChipInput defaultValue={["Initial"]} />);
expect(screen.getByText("Initial")).toBeDefined();
});
});
});
+2 -3
View File
@@ -70,11 +70,10 @@ function ChipItem({ id, chip, index, isEditing, onEdit, onRemove }: ChipItemProp
>
<span className="max-w-32 truncate">{chip}</span>
<motion.div
initial={false}
initial="false"
animate={isHovered ? { opacity: 1, scaleX: 1, x: 0 } : { opacity: 0, scaleX: 0.95, x: -3 }}
transition={{ duration: 0.12, ease: "easeOut" }}
className="ms-2 flex w-10 shrink-0 origin-left items-center gap-x-1 overflow-hidden"
style={{ willChange: "transform, opacity" }}
className="ms-2 flex w-10 shrink-0 origin-left items-center gap-x-1 overflow-hidden will-change-[transform,opacity]"
>
<button
type="button"
+119
View File
@@ -0,0 +1,119 @@
import { cleanup, fireEvent, render, screen } from "@testing-library/react";
import { afterEach, describe, expect, it, vi } from "vite-plus/test";
afterEach(cleanup);
// Mock lingui macros
vi.mock("@lingui/core/macro", () => ({
t: (strings: TemplateStringsArray) => strings[0],
}));
vi.mock("@lingui/react/macro", () => ({
Trans: ({ children }: { children: React.ReactNode }) => <>{children}</>,
}));
// Mock phosphor icons
vi.mock("@phosphor-icons/react", () => ({
TagIcon: () => <span data-testid="tag-icon" />,
}));
import { URLInput } from "./url-input";
describe("URLInput", () => {
describe("URL prefix handling", () => {
it("displays URL without https:// prefix", () => {
const onChange = vi.fn();
render(<URLInput value={{ url: "https://example.com", label: "" }} onChange={onChange} />);
const input = screen.getByDisplayValue("example.com");
expect(input).toBeDefined();
});
it("displays empty string when URL is empty", () => {
const onChange = vi.fn();
render(<URLInput value={{ url: "", label: "" }} onChange={onChange} />);
const inputs = screen.getAllByRole("textbox");
const urlInput = inputs[0];
expect((urlInput as HTMLInputElement).value).toBe("");
});
it("adds https:// prefix when user types", () => {
const onChange = vi.fn();
render(<URLInput value={{ url: "", label: "" }} onChange={onChange} />);
const inputs = screen.getAllByRole("textbox");
fireEvent.change(inputs[0], { target: { value: "example.com" } });
expect(onChange).toHaveBeenCalledWith({
url: "https://example.com",
label: "",
});
});
it("does not double-prefix when user types https://", () => {
const onChange = vi.fn();
render(<URLInput value={{ url: "", label: "" }} onChange={onChange} />);
const inputs = screen.getAllByRole("textbox");
fireEvent.change(inputs[0], { target: { value: "https://example.com" } });
expect(onChange).toHaveBeenCalledWith({
url: "https://example.com",
label: "",
});
});
it("sends empty URL when input is cleared", () => {
const onChange = vi.fn();
render(<URLInput value={{ url: "https://example.com", label: "" }} onChange={onChange} />);
const inputs = screen.getAllByRole("textbox");
fireEvent.change(inputs[0], { target: { value: "" } });
expect(onChange).toHaveBeenCalledWith({
url: "",
label: "",
});
});
});
describe("label preservation", () => {
it("preserves label when URL changes", () => {
const onChange = vi.fn();
render(<URLInput value={{ url: "https://old.com", label: "My Site" }} onChange={onChange} />);
const inputs = screen.getAllByRole("textbox");
fireEvent.change(inputs[0], { target: { value: "new.com" } });
expect(onChange).toHaveBeenCalledWith({
url: "https://new.com",
label: "My Site",
});
});
});
describe("hideLabelButton prop", () => {
it("hides the label button when hideLabelButton is true", () => {
const onChange = vi.fn();
render(<URLInput value={{ url: "", label: "" }} onChange={onChange} hideLabelButton={true} />);
expect(screen.queryByTestId("tag-icon")).toBeNull();
});
it("shows the label button by default", () => {
const onChange = vi.fn();
render(<URLInput value={{ url: "", label: "" }} onChange={onChange} />);
expect(screen.getByTestId("tag-icon")).toBeDefined();
});
});
describe("displays the https:// prefix text", () => {
it("shows https:// as static text", () => {
const onChange = vi.fn();
render(<URLInput value={{ url: "", label: "" }} onChange={onChange} />);
expect(screen.getByText("https://")).toBeDefined();
});
});
});
+142
View File
@@ -0,0 +1,142 @@
import { cleanup, render, screen } from "@testing-library/react";
import { afterEach, describe, expect, it, vi } from "vite-plus/test";
afterEach(cleanup);
// Mock @lingui/core/macro
vi.mock("@lingui/core/macro", () => ({
t: (strings: TemplateStringsArray, ...values: unknown[]) => {
let result = strings[0];
for (let i = 0; i < values.length; i++) {
result += String(values[i]) + strings[i + 1];
}
return result;
},
}));
// Mock PageIcon to avoid deep dependency chain
vi.mock("../resume/shared/page-icon", () => ({
PageIcon: ({ icon, className }: { icon: string; className?: string }) => (
<span data-testid="page-icon" data-icon={icon} className={className} />
),
}));
import { LevelDisplay } from "./display";
describe("LevelDisplay", () => {
describe("returns null for invalid states", () => {
it("returns null when level is 0", () => {
const { container } = render(<LevelDisplay icon="star" type="circle" level={0} />);
expect(container.firstChild).toBeNull();
});
it("returns null when type is 'hidden'", () => {
const { container } = render(<LevelDisplay icon="star" type="hidden" level={3} />);
expect(container.firstChild).toBeNull();
});
it("returns null when icon is empty string", () => {
const { container } = render(<LevelDisplay icon="" type="circle" level={3} />);
expect(container.firstChild).toBeNull();
});
});
describe("renders correct number of elements", () => {
it("always renders 5 elements for non-zero level", () => {
const { container } = render(<LevelDisplay icon="star" type="circle" level={3} />);
const wrapper = container.firstChild as HTMLElement;
expect(wrapper.children).toHaveLength(5);
});
it("renders 5 elements for level 1", () => {
const { container } = render(<LevelDisplay icon="star" type="square" level={1} />);
const wrapper = container.firstChild as HTMLElement;
expect(wrapper.children).toHaveLength(5);
});
it("renders 5 elements for level 5", () => {
const { container } = render(<LevelDisplay icon="star" type="circle" level={5} />);
const wrapper = container.firstChild as HTMLElement;
expect(wrapper.children).toHaveLength(5);
});
});
describe("active state for circle/square/rectangle types", () => {
it("marks correct number of items as active for level 3", () => {
const { container } = render(<LevelDisplay icon="star" type="circle" level={3} />);
const items = Array.from((container.firstChild as HTMLElement).children);
const activeItems = items.filter((el) => el.getAttribute("data-active") === "true");
expect(activeItems).toHaveLength(3);
});
it("marks 1 item active for level 1", () => {
const { container } = render(<LevelDisplay icon="star" type="square" level={1} />);
const items = Array.from((container.firstChild as HTMLElement).children);
const activeItems = items.filter((el) => el.getAttribute("data-active") === "true");
expect(activeItems).toHaveLength(1);
});
it("marks all 5 items active for level 5", () => {
const { container } = render(<LevelDisplay icon="star" type="circle" level={5} />);
const items = Array.from((container.firstChild as HTMLElement).children);
const activeItems = items.filter((el) => el.getAttribute("data-active") === "true");
expect(activeItems).toHaveLength(5);
});
});
describe("progress-bar type", () => {
it("renders progress bar elements", () => {
const { container } = render(<LevelDisplay icon="star" type="progress-bar" level={3} />);
const wrapper = container.firstChild as HTMLElement;
expect(wrapper.children).toHaveLength(5);
});
it("has correct active count for progress-bar", () => {
const { container } = render(<LevelDisplay icon="star" type="progress-bar" level={2} />);
const items = Array.from((container.firstChild as HTMLElement).children);
const activeItems = items.filter((el) => el.getAttribute("data-active") === "true");
expect(activeItems).toHaveLength(2);
});
});
describe("icon type", () => {
it("renders PageIcon components", () => {
render(<LevelDisplay icon="star" type="icon" level={3} />);
const icons = screen.getAllByTestId("page-icon");
expect(icons).toHaveLength(5);
});
it("passes the icon name to PageIcon", () => {
render(<LevelDisplay icon="star" type="icon" level={2} />);
const icons = screen.getAllByTestId("page-icon");
expect(icons[0].getAttribute("data-icon")).toBe("star");
});
it("applies opacity to inactive icons", () => {
render(<LevelDisplay icon="star" type="icon" level={2} />);
const icons = screen.getAllByTestId("page-icon");
// First 2 should be active (no opacity-40), last 3 inactive (opacity-40)
expect(icons[0].className).not.toContain("opacity-40");
expect(icons[1].className).not.toContain("opacity-40");
expect(icons[2].className).toContain("opacity-40");
expect(icons[3].className).toContain("opacity-40");
expect(icons[4].className).toContain("opacity-40");
});
});
describe("aria attributes", () => {
it("has aria-label showing level out of 5", () => {
render(<LevelDisplay icon="star" type="circle" level={3} />);
const el = screen.getByRole("presentation");
expect(el.getAttribute("aria-label")).toContain("3");
expect(el.getAttribute("aria-label")).toContain("5");
});
});
describe("className prop", () => {
it("applies custom className to the wrapper", () => {
const { container } = render(<LevelDisplay icon="star" type="circle" level={3} className="custom-level" />);
expect((container.firstChild as HTMLElement).className).toContain("custom-level");
});
});
});
@@ -13,10 +13,19 @@ export const useCSSVariables = ({ picture, metadata }: UseCssVariablesProps) =>
const lowestBodyFontWeight = Math.min(...metadata.typography.body.fontWeights.map(Number));
const lowestHeadingFontWeight = Math.min(...metadata.typography.heading.fontWeights.map(Number));
const highestBodyFontWeight = Math.max(...metadata.typography.body.fontWeights.map(Number));
const highestHeadingFontWeight = Math.max(...metadata.typography.heading.fontWeights.map(Number));
const rawHighestBodyFontWeight = Math.max(...metadata.typography.body.fontWeights.map(Number));
const rawHighestHeadingFontWeight = Math.max(...metadata.typography.heading.fontWeights.map(Number));
return { lowestBodyFontWeight, lowestHeadingFontWeight, highestBodyFontWeight, highestHeadingFontWeight };
const highestBodyFontWeight = rawHighestBodyFontWeight <= lowestBodyFontWeight ? 700 : rawHighestBodyFontWeight;
const highestHeadingFontWeight =
rawHighestHeadingFontWeight <= lowestHeadingFontWeight ? 700 : rawHighestHeadingFontWeight;
return {
lowestBodyFontWeight,
lowestHeadingFontWeight,
highestBodyFontWeight,
highestHeadingFontWeight,
};
}, [metadata.typography.body.fontWeights, metadata.typography.heading.fontWeights]);
return {
@@ -1,6 +1,7 @@
import type { SectionItem } from "@/schema/resume/data";
import { TiptapContent } from "@/components/input/rich-input";
import { filterFieldValues } from "@/utils/field";
import { stripHtml } from "@/utils/string";
import { cn } from "@/utils/style";
@@ -12,24 +13,44 @@ type AwardsItemProps = SectionItem<"awards"> & {
};
export function AwardsItem({ className, ...item }: AwardsItemProps) {
const headerValues = {
title: item.title,
date: item.date,
awarder: item.awarder,
};
const headerFields = filterFieldValues(
headerValues,
{
key: "title",
content: (
<LinkedTitle
title={item.title}
website={item.website}
showLinkInTitle={item.options?.showLinkInTitle}
className="section-item-title awards-item-title"
/>
),
},
{
key: "date",
content: <span className="section-item-metadata awards-item-date">{item.date}</span>,
},
{
key: "awarder",
content: <span className="section-item-metadata awards-item-awarder">{item.awarder}</span>,
},
);
return (
<div className={cn("awards-item", className)}>
{/* Header */}
<div className="section-item-header awards-item-header">
{/* Row 1 */}
<div className="flex items-start justify-between gap-x-2">
<LinkedTitle
title={item.title}
website={item.website}
showLinkInTitle={item.options?.showLinkInTitle}
className="section-item-title awards-item-title"
/>
<span className="section-item-metadata awards-item-date shrink-0 text-end">{item.date}</span>
</div>
{/* Row 2 */}
<div className="flex items-start justify-between gap-x-2">
<span className="section-item-metadata awards-item-awarder">{item.awarder}</span>
<div className="grid grid-cols-2 items-start justify-between gap-x-2">
{headerFields.map((field, index) => (
<div key={field.key} className={cn(index % 2 === 1 && "text-end whitespace-nowrap")}>
{field.content}
</div>
))}
</div>
</div>
@@ -1,6 +1,7 @@
import type { SectionItem } from "@/schema/resume/data";
import { TiptapContent } from "@/components/input/rich-input";
import { filterFieldValues } from "@/utils/field";
import { stripHtml } from "@/utils/string";
import { cn } from "@/utils/style";
@@ -12,24 +13,44 @@ type CertificationsItemProps = SectionItem<"certifications"> & {
};
export function CertificationsItem({ className, ...item }: CertificationsItemProps) {
const headerValues = {
title: item.title,
date: item.date,
issuer: item.issuer,
};
const headerFields = filterFieldValues(
headerValues,
{
key: "title",
content: (
<LinkedTitle
title={item.title}
website={item.website}
showLinkInTitle={item.options?.showLinkInTitle}
className="section-item-title certifications-item-title"
/>
),
},
{
key: "date",
content: <span className="section-item-metadata certifications-item-date">{item.date}</span>,
},
{
key: "issuer",
content: <span className="section-item-metadata certifications-item-issuer">{item.issuer}</span>,
},
);
return (
<div className={cn("certifications-item", className)}>
{/* Header */}
<div className="section-item-header certifications-item-header">
{/* Row 1 */}
<div className="flex items-start justify-between gap-x-2">
<LinkedTitle
title={item.title}
website={item.website}
showLinkInTitle={item.options?.showLinkInTitle}
className="section-item-title certifications-item-title"
/>
<span className="section-item-metadata certifications-item-date shrink-0 text-end">{item.date}</span>
</div>
{/* Row 2 */}
<div className="flex items-start justify-between gap-x-2">
<span className="section-item-metadata certifications-item-issuer">{item.issuer}</span>
<div className="grid grid-cols-2 items-start justify-between gap-x-2">
{headerFields.map((field, index) => (
<div key={field.key} className={cn(index % 2 === 1 && "text-end whitespace-nowrap")}>
{field.content}
</div>
))}
</div>
</div>
@@ -1,6 +1,7 @@
import type { SectionItem } from "@/schema/resume/data";
import { TiptapContent } from "@/components/input/rich-input";
import { filterFieldValues } from "@/utils/field";
import { stripHtml } from "@/utils/string";
import { cn } from "@/utils/style";
@@ -12,29 +13,51 @@ type EducationItemProps = SectionItem<"education"> & {
};
export function EducationItem({ className, ...item }: EducationItemProps) {
const degreeAndGrade = [item.degree, item.grade].filter(Boolean).join(" • ");
const locationAndPeriod = [item.location, item.period].filter(Boolean).join(" • ");
const headerValues = {
school: item.school,
degreeAndGrade,
area: item.area,
locationAndPeriod,
};
const headerFields = filterFieldValues(
headerValues,
{
key: "school",
content: (
<LinkedTitle
title={item.school}
website={item.website}
showLinkInTitle={item.options?.showLinkInTitle}
className="section-item-title education-item-title"
/>
),
},
{
key: "degreeAndGrade",
content: <span className="section-item-metadata education-item-degree-grade">{degreeAndGrade}</span>,
},
{
key: "area",
content: <span className="section-item-metadata education-item-area">{item.area}</span>,
},
{
key: "locationAndPeriod",
content: <span className="section-item-metadata education-item-location-period">{locationAndPeriod}</span>,
},
);
return (
<div className={cn("education-item", className)}>
{/* Header */}
<div className="section-item-header education-item-header mb-2">
{/* Row 1 */}
<div className="flex items-start justify-between gap-x-2">
<LinkedTitle
title={item.school}
website={item.website}
showLinkInTitle={item.options?.showLinkInTitle}
className="section-item-title education-item-title"
/>
<span className="section-item-metadata education-item-degree-grade shrink-0 text-end">
{[item.degree, item.grade].filter(Boolean).join(" • ")}
</span>
</div>
{/* Row 2 */}
<div className="flex items-start justify-between gap-x-2">
<span className="section-item-metadata education-item-area">{item.area}</span>
<span className="section-item-metadata education-item-location-period shrink-0 text-end">
{[item.location, item.period].filter(Boolean).join(" • ")}
</span>
<div className="grid grid-cols-2 items-start justify-between gap-x-2">
{headerFields.map((field, index) => (
<div key={field.key} className={cn(index % 2 === 1 && "text-end whitespace-nowrap")}>
{field.content}
</div>
))}
</div>
</div>
@@ -1,6 +1,7 @@
import type { SectionItem } from "@/schema/resume/data";
import { TiptapContent } from "@/components/input/rich-input";
import { filterFieldValues } from "@/utils/field";
import { stripHtml } from "@/utils/string";
import { cn } from "@/utils/style";
@@ -13,36 +14,50 @@ type ExperienceItemProps = SectionItem<"experience"> & {
export function ExperienceItem({ className, ...item }: ExperienceItemProps) {
const hasRoles = Array.isArray(item.roles) && item.roles.length > 0;
const headerValues = {
company: item.company,
location: item.location,
position: item.position,
period: item.period,
};
const headerFields = filterFieldValues(
headerValues,
{
key: "company",
content: (
<LinkedTitle
title={item.company}
website={item.website}
showLinkInTitle={item.options?.showLinkInTitle}
className="section-item-title experience-item-title"
/>
),
},
{
key: "location",
content: <span className="section-item-metadata experience-item-location">{item.location}</span>,
},
{
key: "position",
content: <span className="section-item-metadata experience-item-position">{item.position}</span>,
},
{
key: "period",
content: <span className="section-item-metadata experience-item-period">{item.period}</span>,
},
);
return (
<div className={cn("experience-item", className)}>
{/* Header */}
<div className="section-item-header experience-item-header">
{/* Row 1: Company + Location */}
<div className="flex items-start justify-between gap-x-2">
<LinkedTitle
title={item.company}
website={item.website}
showLinkInTitle={item.options?.showLinkInTitle}
className="section-item-title experience-item-title"
/>
<span className="section-item-metadata experience-item-location shrink-0 text-end">{item.location}</span>
<div className="grid grid-cols-2 items-start justify-between gap-x-2">
{headerFields.map((field, index) => (
<div key={field.key} className={cn(index % 2 === 1 && "text-end whitespace-nowrap")}>
{field.content}
</div>
))}
</div>
{/* Row 2: Position + Period */}
{(!hasRoles || item.position) && (
<div className="flex items-start justify-between gap-x-2">
<span className="section-item-metadata experience-item-position">{item.position}</span>
<span className="section-item-metadata experience-item-period shrink-0 text-end">{item.period}</span>
</div>
)}
{/* Overall period when hasRoles and no summary position */}
{hasRoles && !item.position && item.period && (
<div className="flex items-start justify-end gap-x-2">
<span className="section-item-metadata experience-item-period shrink-0 text-end">{item.period}</span>
</div>
)}
</div>
{/* Role Progression */}
@@ -50,11 +65,11 @@ export function ExperienceItem({ className, ...item }: ExperienceItemProps) {
<div className="experience-item-roles mt-0 flex flex-col gap-y-1">
{item.roles.map((role) => (
<div key={role.id} className="experience-item-role">
<div className="flex items-start justify-between gap-x-2">
<span className="section-item-metadata experience-item-role-position">{role.position}</span>
<span className="section-item-metadata experience-item-role-period shrink-0 text-end">
<div className="grid grid-cols-2 items-start justify-between gap-x-2">
<div className="section-item-metadata experience-item-role-position">{role.position}</div>
<div className="section-item-metadata experience-item-role-period text-end whitespace-nowrap">
{role.period}
</span>
</div>
</div>
{stripHtml(role.description) && (
@@ -1,6 +1,7 @@
import type { SectionItem } from "@/schema/resume/data";
import { TiptapContent } from "@/components/input/rich-input";
import { filterFieldValues } from "@/utils/field";
import { stripHtml } from "@/utils/string";
import { cn } from "@/utils/style";
@@ -12,24 +13,44 @@ type PublicationsItemProps = SectionItem<"publications"> & {
};
export function PublicationsItem({ className, ...item }: PublicationsItemProps) {
const headerValues = {
title: item.title,
date: item.date,
publisher: item.publisher,
};
const headerFields = filterFieldValues(
headerValues,
{
key: "title",
content: (
<LinkedTitle
title={item.title}
website={item.website}
showLinkInTitle={item.options?.showLinkInTitle}
className="section-item-title publications-item-title"
/>
),
},
{
key: "date",
content: <span className="section-item-metadata publications-item-date">{item.date}</span>,
},
{
key: "publisher",
content: <span className="section-item-metadata publications-item-publisher">{item.publisher}</span>,
},
);
return (
<div className={cn("publications-item", className)}>
{/* Header */}
<div className="section-item-header publications-item-header">
{/* Row 1 */}
<div className="flex items-start justify-between gap-x-2">
<LinkedTitle
title={item.title}
website={item.website}
showLinkInTitle={item.options?.showLinkInTitle}
className="section-item-title publications-item-title"
/>
<span className="section-item-metadata publications-item-date shrink-0 text-end">{item.date}</span>
</div>
{/* Row 2 */}
<div className="flex items-start justify-between gap-x-2">
<span className="section-item-metadata publications-item-publisher">{item.publisher}</span>
<div className="grid grid-cols-2 items-start justify-between gap-x-2">
{headerFields.map((field, index) => (
<div key={field.key} className={cn(index % 2 === 1 && "text-end whitespace-nowrap")}>
{field.content}
</div>
))}
</div>
</div>
@@ -1,6 +1,7 @@
import type { SectionItem } from "@/schema/resume/data";
import { TiptapContent } from "@/components/input/rich-input";
import { filterFieldValues } from "@/utils/field";
import { stripHtml } from "@/utils/string";
import { cn } from "@/utils/style";
@@ -12,23 +13,39 @@ type ReferencesItemProps = SectionItem<"references"> & {
};
export function ReferencesItem({ className, ...item }: ReferencesItemProps) {
const headerValues = {
name: item.name,
position: item.position,
};
const headerFields = filterFieldValues(
headerValues,
{
key: "name",
content: (
<LinkedTitle
title={item.name}
website={item.website}
showLinkInTitle={item.options?.showLinkInTitle}
className="section-item-title references-item-name"
/>
),
},
{
key: "position",
content: <span className="section-item-metadata references-item-position">{item.position}</span>,
},
);
return (
<div className={cn("references-item", className)}>
{/* Header */}
<div className="section-item-header references-item-header">
{/* Row 1 */}
<div className="flex items-start justify-between gap-x-2">
<LinkedTitle
title={item.name}
website={item.website}
showLinkInTitle={item.options?.showLinkInTitle}
className="section-item-title references-item-name"
/>
</div>
{/* Row 2 */}
<div className="flex items-start justify-between gap-x-2">
<span className="section-item-metadata references-item-position">{item.position}</span>
<div className="grid grid-cols-2 items-start justify-between gap-x-2">
{headerFields.map((field, index) => (
<div key={field.key} className={cn(index % 2 === 1 && "text-end whitespace-nowrap")}>
{field.content}
</div>
))}
</div>
</div>
@@ -1,6 +1,7 @@
import type { SectionItem } from "@/schema/resume/data";
import { TiptapContent } from "@/components/input/rich-input";
import { filterFieldValues } from "@/utils/field";
import { stripHtml } from "@/utils/string";
import { cn } from "@/utils/style";
@@ -12,24 +13,44 @@ type VolunteerItemProps = SectionItem<"volunteer"> & {
};
export function VolunteerItem({ className, ...item }: VolunteerItemProps) {
const headerValues = {
organization: item.organization,
period: item.period,
location: item.location,
};
const headerFields = filterFieldValues(
headerValues,
{
key: "organization",
content: (
<LinkedTitle
title={item.organization}
website={item.website}
showLinkInTitle={item.options?.showLinkInTitle}
className="section-item-title volunteer-item-title"
/>
),
},
{
key: "period",
content: <span className="section-item-metadata volunteer-item-period">{item.period}</span>,
},
{
key: "location",
content: <span className="section-item-metadata volunteer-item-location">{item.location}</span>,
},
);
return (
<div className={cn("volunteer-item", className)}>
{/* Header */}
<div className="section-item-header volunteer-item-header">
{/* Row 1 */}
<div className="flex items-start justify-between gap-x-2">
<LinkedTitle
title={item.organization}
website={item.website}
showLinkInTitle={item.options?.showLinkInTitle}
className="section-item-title volunteer-item-title"
/>
<span className="section-item-metadata volunteer-item-period shrink-0 text-end">{item.period}</span>
</div>
{/* Row 2 */}
<div className="flex items-start justify-between gap-x-2">
<span className="section-item-metadata volunteer-item-location">{item.location}</span>
<div className="grid grid-cols-2 items-start justify-between gap-x-2">
{headerFields.map((field, index) => (
<div key={field.key} className={cn(index % 2 === 1 && "text-end whitespace-nowrap")}>
{field.content}
</div>
))}
</div>
</div>
@@ -0,0 +1,95 @@
import { cleanup, render, screen } from "@testing-library/react";
import { afterEach, describe, expect, it } from "vite-plus/test";
afterEach(cleanup);
import { LinkedTitle } from "./linked-title";
describe("LinkedTitle", () => {
describe("renders as link when showLinkInTitle and website.url are provided", () => {
it("renders an anchor tag", () => {
render(
<LinkedTitle title="Acme Corp" website={{ url: "https://acme.com", label: "Acme" }} showLinkInTitle={true} />,
);
const link = screen.getByRole("link", { name: "Acme Corp" });
expect(link).toBeDefined();
expect(link.getAttribute("href")).toBe("https://acme.com");
});
it("sets target=_blank and rel=noopener on the link", () => {
render(
<LinkedTitle title="Company" website={{ url: "https://example.com", label: "" }} showLinkInTitle={true} />,
);
const link = screen.getByRole("link");
expect(link.getAttribute("target")).toBe("_blank");
expect(link.getAttribute("rel")).toBe("noopener");
});
it("wraps the title in a strong tag inside the link", () => {
render(
<LinkedTitle title="Bold Title" website={{ url: "https://example.com", label: "" }} showLinkInTitle={true} />,
);
const strong = screen.getByText("Bold Title");
expect(strong.tagName).toBe("STRONG");
});
});
describe("renders as plain strong tag otherwise", () => {
it("renders strong when showLinkInTitle is false", () => {
render(
<LinkedTitle title="Plain Title" website={{ url: "https://example.com", label: "" }} showLinkInTitle={false} />,
);
const strong = screen.getByText("Plain Title");
expect(strong.tagName).toBe("STRONG");
expect(screen.queryByRole("link")).toBeNull();
});
it("renders strong when showLinkInTitle is undefined", () => {
render(<LinkedTitle title="No Link" />);
expect(screen.getByText("No Link").tagName).toBe("STRONG");
expect(screen.queryByRole("link")).toBeNull();
});
it("renders strong when website is undefined", () => {
render(<LinkedTitle title="No Website" showLinkInTitle={true} />);
expect(screen.getByText("No Website").tagName).toBe("STRONG");
expect(screen.queryByRole("link")).toBeNull();
});
it("renders strong when website.url is empty", () => {
render(<LinkedTitle title="Empty URL" website={{ url: "", label: "" }} showLinkInTitle={true} />);
expect(screen.getByText("Empty URL").tagName).toBe("STRONG");
expect(screen.queryByRole("link")).toBeNull();
});
});
describe("className prop", () => {
it("applies className to the link element", () => {
render(
<LinkedTitle
title="Styled"
website={{ url: "https://x.com", label: "" }}
showLinkInTitle={true}
className="custom-class"
/>,
);
const link = screen.getByRole("link");
expect(link.className).toContain("custom-class");
});
it("applies className to the strong element", () => {
render(<LinkedTitle title="Styled Strong" className="my-class" />);
const strong = screen.getByText("Styled Strong");
expect(strong.className).toContain("my-class");
});
});
});
+272
View File
@@ -0,0 +1,272 @@
import { afterEach, describe, expect, it, vi } from "vite-plus/test";
// Mock dependencies before importing the store
vi.mock("@lingui/core/macro", () => ({
t: (strings: TemplateStringsArray) => strings[0],
}));
vi.mock("sonner", () => ({
toast: {
error: vi.fn(() => "toast-id"),
dismiss: vi.fn(),
},
}));
vi.mock("@/integrations/orpc/client", () => ({
orpc: {
resume: {
update: {
call: vi.fn(() => Promise.resolve()),
},
},
},
}));
import { defaultResumeData } from "@/schema/resume/data";
import { useResumeStore } from "./resume";
// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------
function makeResume(overrides?: Record<string, unknown>) {
return {
id: "test-resume-id",
name: "Test Resume",
slug: "test-resume",
tags: ["test"],
isLocked: false,
data: structuredClone(defaultResumeData),
...overrides,
};
}
afterEach(() => {
// Reset store between tests
useResumeStore.getState().initialize(null);
});
// ---------------------------------------------------------------------------
// initialize
// ---------------------------------------------------------------------------
describe("useResumeStore — initialize", () => {
it("sets resume and isReady to true", () => {
const resume = makeResume();
useResumeStore.getState().initialize(resume);
const state = useResumeStore.getState();
expect(state.isReady).toBe(true);
expect(state.resume.id).toBe("test-resume-id");
expect(state.resume.name).toBe("Test Resume");
});
it("sets isReady to false when initialized with null", () => {
useResumeStore.getState().initialize(null);
const state = useResumeStore.getState();
expect(state.isReady).toBe(false);
});
it("replaces previous resume data", () => {
useResumeStore.getState().initialize(makeResume({ name: "First" }));
expect(useResumeStore.getState().resume.name).toBe("First");
useResumeStore.getState().initialize(makeResume({ name: "Second" }));
expect(useResumeStore.getState().resume.name).toBe("Second");
});
});
// ---------------------------------------------------------------------------
// updateResumeData
// ---------------------------------------------------------------------------
describe("useResumeStore — updateResumeData", () => {
it("updates resume data via immer draft", () => {
useResumeStore.getState().initialize(makeResume());
useResumeStore.getState().updateResumeData((draft) => {
draft.basics.name = "Jane Doe";
});
expect(useResumeStore.getState().resume.data.basics.name).toBe("Jane Doe");
});
it("can update nested fields", () => {
useResumeStore.getState().initialize(makeResume());
useResumeStore.getState().updateResumeData((draft) => {
draft.basics.website.url = "https://example.com";
draft.basics.email = "jane@example.com";
});
expect(useResumeStore.getState().resume.data.basics.website.url).toBe("https://example.com");
expect(useResumeStore.getState().resume.data.basics.email).toBe("jane@example.com");
});
it("can add items to sections", () => {
useResumeStore.getState().initialize(makeResume());
useResumeStore.getState().updateResumeData((draft) => {
draft.sections.skills.items.push({
id: "s1",
hidden: false,
icon: "",
name: "TypeScript",
proficiency: "Advanced",
level: 4,
keywords: [],
});
});
expect(useResumeStore.getState().resume.data.sections.skills.items).toHaveLength(1);
expect(useResumeStore.getState().resume.data.sections.skills.items[0].name).toBe("TypeScript");
});
it("does not update when resume is not initialized", () => {
// Store starts with null resume
useResumeStore.getState().initialize(null);
// Should not throw
useResumeStore.getState().updateResumeData((draft) => {
draft.basics.name = "Should not apply";
});
});
it("blocks updates when resume is locked", async () => {
const { toast } = await import("sonner");
useResumeStore.getState().initialize(makeResume({ isLocked: true }));
useResumeStore.getState().updateResumeData((draft) => {
draft.basics.name = "Should not apply";
});
// Name should remain unchanged
expect(useResumeStore.getState().resume.data.basics.name).toBe("");
// Should show error toast
expect(toast.error).toHaveBeenCalled();
});
it("does not block updates on unlocked resume", () => {
useResumeStore.getState().initialize(makeResume({ isLocked: false }));
useResumeStore.getState().updateResumeData((draft) => {
draft.basics.name = "Updated";
});
expect(useResumeStore.getState().resume.data.basics.name).toBe("Updated");
});
});
// ---------------------------------------------------------------------------
// Multiple updates
// ---------------------------------------------------------------------------
describe("useResumeStore — multiple updates", () => {
it("applies sequential updates correctly", () => {
useResumeStore.getState().initialize(makeResume());
useResumeStore.getState().updateResumeData((draft) => {
draft.basics.name = "First Update";
});
useResumeStore.getState().updateResumeData((draft) => {
draft.basics.headline = "Developer";
});
const data = useResumeStore.getState().resume.data;
expect(data.basics.name).toBe("First Update");
expect(data.basics.headline).toBe("Developer");
});
it("preserves unmodified sections across updates", () => {
useResumeStore.getState().initialize(makeResume());
useResumeStore.getState().updateResumeData((draft) => {
draft.basics.name = "Jane";
});
// Metadata and other sections should be untouched
expect(useResumeStore.getState().resume.data.metadata.template).toBe("onyx");
expect(useResumeStore.getState().resume.data.sections.skills.items).toHaveLength(0);
});
});
// ---------------------------------------------------------------------------
// Temporal store (undo/redo)
// ---------------------------------------------------------------------------
describe("useResumeStore — temporal", () => {
it("has a temporal store accessible", () => {
expect(useResumeStore.temporal).toBeDefined();
expect(useResumeStore.temporal.getState).toBeDefined();
});
it("temporal store has undo/redo actions", () => {
const temporal = useResumeStore.temporal.getState();
expect(typeof temporal.undo).toBe("function");
expect(typeof temporal.redo).toBe("function");
expect(typeof temporal.clear).toBe("function");
});
});
// ---------------------------------------------------------------------------
// Edge cases
// ---------------------------------------------------------------------------
describe("useResumeStore — edge cases", () => {
it("can update metadata fields", () => {
useResumeStore.getState().initialize(makeResume());
useResumeStore.getState().updateResumeData((draft) => {
draft.metadata.template = "pikachu";
});
expect(useResumeStore.getState().resume.data.metadata.template).toBe("pikachu");
});
it("can update picture settings", () => {
useResumeStore.getState().initialize(makeResume());
useResumeStore.getState().updateResumeData((draft) => {
draft.picture.url = "https://example.com/photo.jpg";
draft.picture.size = 120;
});
expect(useResumeStore.getState().resume.data.picture.url).toBe("https://example.com/photo.jpg");
expect(useResumeStore.getState().resume.data.picture.size).toBe(120);
});
it("can remove all items from a section", () => {
const resume = makeResume();
resume.data.sections.skills.items = [
{ id: "s1", hidden: false, icon: "", name: "JS", proficiency: "", level: 0, keywords: [] },
];
useResumeStore.getState().initialize(resume);
useResumeStore.getState().updateResumeData((draft) => {
draft.sections.skills.items = [];
});
expect(useResumeStore.getState().resume.data.sections.skills.items).toHaveLength(0);
});
it("can update custom sections", () => {
useResumeStore.getState().initialize(makeResume());
useResumeStore.getState().updateResumeData((draft) => {
draft.customSections.push({
id: "custom-1",
type: "experience",
title: "Freelance",
columns: 1,
hidden: false,
items: [],
});
});
expect(useResumeStore.getState().resume.data.customSections).toHaveLength(1);
expect(useResumeStore.getState().resume.data.customSections[0].title).toBe("Freelance");
});
});
+27 -2
View File
@@ -32,12 +32,37 @@ type ResumeStore = ResumeStoreState & ResumeStoreActions;
const controller = new AbortController();
const signal = controller.signal;
const _syncResume = (resume: Resume) => {
void orpc.resume.update.call({ id: resume.id, data: resume.data }, { signal });
let syncErrorToastId: string | number | undefined;
const _syncResume = async (resume: Resume) => {
try {
await orpc.resume.update.call({ id: resume.id, data: resume.data }, { signal });
// Dismiss error toast on successful sync
if (syncErrorToastId !== undefined) {
toast.dismiss(syncErrorToastId);
syncErrorToastId = undefined;
}
} catch (error: unknown) {
// Ignore aborted requests (e.g. page navigation)
if (error instanceof DOMException && error.name === "AbortError") return;
syncErrorToastId = toast.error(
t`Your latest changes could not be saved. Please make sure you are connected to the internet and try again.`,
{ id: syncErrorToastId, duration: Infinity },
);
}
};
const syncResume = debounce(_syncResume, 500, { signal });
// Flush pending sync before the page unloads to prevent data loss
if (typeof window !== "undefined") {
window.addEventListener("beforeunload", () => {
syncResume.flush();
});
}
let errorToastId: string | number | undefined;
type PartializedState = { resume: Resume | null };
+1 -1
View File
@@ -38,7 +38,7 @@ function AccordionContent({ className, children, ...props }: AccordionPrimitive.
>
<div
className={cn(
"h-(--accordion-panel-height) pt-0 pb-4 data-ending-style:h-0 data-starting-style:h-0 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground [&_p:not(:last-child)]:mb-4",
"h-(--accordion-panel-height) pt-0 pb-4 data-ending-style:h-0 data-starting-style:h-0 [&_p:not(:last-child)]:mb-4",
className,
)}
>
+3 -15
View File
@@ -18,6 +18,7 @@ import { Switch } from "@/components/ui/switch";
import { useDialogStore } from "@/dialogs/store";
import { useFormBlocker } from "@/hooks/use-form-blocker";
import { awardItemSchema } from "@/schema/resume/data";
import { createSectionItem, updateSectionItem } from "@/utils/resume/section-actions";
import { generateId } from "@/utils/string";
const formSchema = awardItemSchema;
@@ -44,12 +45,7 @@ export function CreateAwardDialog({ data }: DialogProps<"resume.sections.awards.
const onSubmit = (formData: FormValues) => {
updateResumeData((draft) => {
if (data?.customSectionId) {
const section = draft.customSections.find((s) => s.id === data.customSectionId);
if (section) section.items.push(formData);
} else {
draft.sections.awards.items.push(formData);
}
createSectionItem(draft, "awards", formData, data?.customSectionId);
});
closeDialog();
};
@@ -105,15 +101,7 @@ export function UpdateAwardDialog({ data }: DialogProps<"resume.sections.awards.
const onSubmit = (formData: FormValues) => {
updateResumeData((draft) => {
if (data?.customSectionId) {
const section = draft.customSections.find((s) => s.id === data.customSectionId);
if (!section) return;
const index = section.items.findIndex((item) => item.id === formData.id);
if (index !== -1) section.items[index] = formData;
} else {
const index = draft.sections.awards.items.findIndex((item) => item.id === formData.id);
if (index !== -1) draft.sections.awards.items[index] = formData;
}
updateSectionItem(draft, "awards", formData, data?.customSectionId);
});
closeDialog();
};
+3 -15
View File
@@ -18,6 +18,7 @@ import { Switch } from "@/components/ui/switch";
import { useDialogStore } from "@/dialogs/store";
import { useFormBlocker } from "@/hooks/use-form-blocker";
import { certificationItemSchema } from "@/schema/resume/data";
import { createSectionItem, updateSectionItem } from "@/utils/resume/section-actions";
import { generateId } from "@/utils/string";
const formSchema = certificationItemSchema;
@@ -44,12 +45,7 @@ export function CreateCertificationDialog({ data }: DialogProps<"resume.sections
const onSubmit = (formData: FormValues) => {
updateResumeData((draft) => {
if (data?.customSectionId) {
const section = draft.customSections.find((s) => s.id === data.customSectionId);
if (section) section.items.push(formData);
} else {
draft.sections.certifications.items.push(formData);
}
createSectionItem(draft, "certifications", formData, data?.customSectionId);
});
closeDialog();
};
@@ -105,15 +101,7 @@ export function UpdateCertificationDialog({ data }: DialogProps<"resume.sections
const onSubmit = (formData: FormValues) => {
updateResumeData((draft) => {
if (data?.customSectionId) {
const section = draft.customSections.find((s) => s.id === data.customSectionId);
if (!section) return;
const index = section.items.findIndex((item) => item.id === formData.id);
if (index !== -1) section.items[index] = formData;
} else {
const index = draft.sections.certifications.items.findIndex((item) => item.id === formData.id);
if (index !== -1) draft.sections.certifications.items[index] = formData;
}
updateSectionItem(draft, "certifications", formData, data?.customSectionId);
});
closeDialog();
};
+7 -19
View File
@@ -18,6 +18,7 @@ import { Switch } from "@/components/ui/switch";
import { useDialogStore } from "@/dialogs/store";
import { useFormBlocker } from "@/hooks/use-form-blocker";
import { educationItemSchema } from "@/schema/resume/data";
import { createSectionItem, updateSectionItem } from "@/utils/resume/section-actions";
import { generateId } from "@/utils/string";
const formSchema = educationItemSchema;
@@ -47,12 +48,7 @@ export function CreateEducationDialog({ data }: DialogProps<"resume.sections.edu
const onSubmit = (formData: FormValues) => {
updateResumeData((draft) => {
if (data?.customSectionId) {
const section = draft.customSections.find((s) => s.id === data.customSectionId);
if (section) section.items.push(formData);
} else {
draft.sections.education.items.push(formData);
}
createSectionItem(draft, "education", formData, data?.customSectionId);
});
closeDialog();
};
@@ -111,15 +107,7 @@ export function UpdateEducationDialog({ data }: DialogProps<"resume.sections.edu
const onSubmit = (formData: FormValues) => {
updateResumeData((draft) => {
if (data?.customSectionId) {
const section = draft.customSections.find((s) => s.id === data.customSectionId);
if (!section) return;
const index = section.items.findIndex((item) => item.id === formData.id);
if (index !== -1) section.items[index] = formData;
} else {
const index = draft.sections.education.items.findIndex((item) => item.id === formData.id);
if (index !== -1) draft.sections.education.items[index] = formData;
}
updateSectionItem(draft, "education", formData, data?.customSectionId);
});
closeDialog();
};
@@ -176,11 +164,11 @@ function EducationForm() {
<FormField
control={form.control}
name="degree"
name="area"
render={({ field }) => (
<FormItem>
<FormLabel>
<Trans>Degree</Trans>
<Trans>Area of Study</Trans>
</FormLabel>
<FormControl render={<Input {...field} />} />
<FormMessage />
@@ -190,11 +178,11 @@ function EducationForm() {
<FormField
control={form.control}
name="area"
name="degree"
render={({ field }) => (
<FormItem>
<FormLabel>
<Trans>Area of Study</Trans>
<Trans>Degree</Trans>
</FormLabel>
<FormControl render={<Input {...field} />} />
<FormMessage />
+21 -33
View File
@@ -21,6 +21,7 @@ import { Switch } from "@/components/ui/switch";
import { useDialogStore } from "@/dialogs/store";
import { useFormBlocker } from "@/hooks/use-form-blocker";
import { experienceItemSchema } from "@/schema/resume/data";
import { createSectionItem, updateSectionItem } from "@/utils/resume/section-actions";
import { generateId } from "@/utils/string";
const formSchema = experienceItemSchema;
@@ -49,14 +50,8 @@ export function CreateExperienceDialog({ data }: DialogProps<"resume.sections.ex
const onSubmit = (formData: FormValues) => {
updateResumeData((draft) => {
if (data?.customSectionId) {
const section = draft.customSections.find((s) => s.id === data.customSectionId);
if (section) section.items.push(formData);
} else {
draft.sections.experience.items.push(formData);
}
createSectionItem(draft, "experience", formData, data?.customSectionId);
});
closeDialog();
};
@@ -113,17 +108,8 @@ export function UpdateExperienceDialog({ data }: DialogProps<"resume.sections.ex
const onSubmit = (formData: FormValues) => {
updateResumeData((draft) => {
if (data?.customSectionId) {
const section = draft.customSections.find((s) => s.id === data.customSectionId);
if (!section) return;
const index = section.items.findIndex((item) => item.id === formData.id);
if (index !== -1) section.items[index] = formData;
} else {
const index = draft.sections.experience.items.findIndex((item) => item.id === formData.id);
if (index !== -1) draft.sections.experience.items[index] = formData;
}
updateSectionItem(draft, "experience", formData, data?.customSectionId);
});
closeDialog();
};
@@ -276,20 +262,6 @@ function ExperienceForm() {
)}
/>
<FormField
control={form.control}
name="position"
render={({ field }) => (
<FormItem>
<FormLabel>{hasRoles ? <Trans>Overall Title (optional)</Trans> : <Trans>Position</Trans>}</FormLabel>
<FormControl
render={<Input {...field} placeholder={hasRoles ? "e.g. Software Engineer → Senior Engineer" : ""} />}
/>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="location"
@@ -304,13 +276,29 @@ function ExperienceForm() {
)}
/>
<FormField
control={form.control}
name="position"
render={({ field }) => (
<FormItem>
<FormLabel>
<Trans>Position</Trans>
</FormLabel>
<FormControl render={<Input {...field} />} />
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="period"
render={({ field }) => (
<FormItem>
<FormLabel>{hasRoles ? <Trans>Overall Period</Trans> : <Trans>Period</Trans>}</FormLabel>
<FormControl render={<Input {...field} placeholder={hasRoles ? "e.g. 2018 – Present" : ""} />} />
<FormLabel>
<Trans>Period</Trans>
</FormLabel>
<FormControl render={<Input {...field} />} />
<FormMessage />
</FormItem>
)}
+3 -15
View File
@@ -18,6 +18,7 @@ import { Input } from "@/components/ui/input";
import { useDialogStore } from "@/dialogs/store";
import { useFormBlocker } from "@/hooks/use-form-blocker";
import { interestItemSchema } from "@/schema/resume/data";
import { createSectionItem, updateSectionItem } from "@/utils/resume/section-actions";
import { generateId } from "@/utils/string";
import { cn } from "@/utils/style";
@@ -42,12 +43,7 @@ export function CreateInterestDialog({ data }: DialogProps<"resume.sections.inte
const onSubmit = (formData: FormValues) => {
updateResumeData((draft) => {
if (data?.customSectionId) {
const section = draft.customSections.find((s) => s.id === data.customSectionId);
if (section) section.items.push(formData);
} else {
draft.sections.interests.items.push(formData);
}
createSectionItem(draft, "interests", formData, data?.customSectionId);
});
closeDialog();
};
@@ -100,15 +96,7 @@ export function UpdateInterestDialog({ data }: DialogProps<"resume.sections.inte
const onSubmit = (formData: FormValues) => {
updateResumeData((draft) => {
if (data?.customSectionId) {
const section = draft.customSections.find((s) => s.id === data.customSectionId);
if (!section) return;
const index = section.items.findIndex((item) => item.id === formData.id);
if (index !== -1) section.items[index] = formData;
} else {
const index = draft.sections.interests.items.findIndex((item) => item.id === formData.id);
if (index !== -1) draft.sections.interests.items[index] = formData;
}
updateSectionItem(draft, "interests", formData, data?.customSectionId);
});
closeDialog();
};
+3 -15
View File
@@ -17,6 +17,7 @@ import { Slider } from "@/components/ui/slider";
import { useDialogStore } from "@/dialogs/store";
import { useFormBlocker } from "@/hooks/use-form-blocker";
import { languageItemSchema } from "@/schema/resume/data";
import { createSectionItem, updateSectionItem } from "@/utils/resume/section-actions";
import { generateId } from "@/utils/string";
const formSchema = languageItemSchema;
@@ -40,12 +41,7 @@ export function CreateLanguageDialog({ data }: DialogProps<"resume.sections.lang
const onSubmit = (formData: FormValues) => {
updateResumeData((draft) => {
if (data?.customSectionId) {
const section = draft.customSections.find((s) => s.id === data.customSectionId);
if (section) section.items.push(formData);
} else {
draft.sections.languages.items.push(formData);
}
createSectionItem(draft, "languages", formData, data?.customSectionId);
});
closeDialog();
};
@@ -98,15 +94,7 @@ export function UpdateLanguageDialog({ data }: DialogProps<"resume.sections.lang
const onSubmit = (formData: FormValues) => {
updateResumeData((draft) => {
if (data?.customSectionId) {
const section = draft.customSections.find((s) => s.id === data.customSectionId);
if (!section) return;
const index = section.items.findIndex((item) => item.id === formData.id);
if (index !== -1) section.items[index] = formData;
} else {
const index = draft.sections.languages.items.findIndex((item) => item.id === formData.id);
if (index !== -1) draft.sections.languages.items[index] = formData;
}
updateSectionItem(draft, "languages", formData, data?.customSectionId);
});
closeDialog();
};
+3 -15
View File
@@ -18,6 +18,7 @@ import { Switch } from "@/components/ui/switch";
import { type DialogProps, useDialogStore } from "@/dialogs/store";
import { useFormBlocker } from "@/hooks/use-form-blocker";
import { profileItemSchema } from "@/schema/resume/data";
import { createSectionItem, updateSectionItem } from "@/utils/resume/section-actions";
import { generateId } from "@/utils/string";
import { cn } from "@/utils/style";
@@ -44,12 +45,7 @@ export function CreateProfileDialog({ data }: DialogProps<"resume.sections.profi
const onSubmit = (formData: FormValues) => {
updateResumeData((draft) => {
if (data?.customSectionId) {
const section = draft.customSections.find((s) => s.id === data.customSectionId);
if (section) section.items.push(formData);
} else {
draft.sections.profiles.items.push(formData);
}
createSectionItem(draft, "profiles", formData, data?.customSectionId);
});
closeDialog();
};
@@ -104,15 +100,7 @@ export function UpdateProfileDialog({ data }: DialogProps<"resume.sections.profi
const onSubmit = (formData: FormValues) => {
updateResumeData((draft) => {
if (data?.customSectionId) {
const section = draft.customSections.find((s) => s.id === data.customSectionId);
if (!section) return;
const index = section.items.findIndex((item) => item.id === formData.id);
if (index !== -1) section.items[index] = formData;
} else {
const index = draft.sections.profiles.items.findIndex((item) => item.id === formData.id);
if (index !== -1) draft.sections.profiles.items[index] = formData;
}
updateSectionItem(draft, "profiles", formData, data?.customSectionId);
});
closeDialog();
};
+3 -15
View File
@@ -18,6 +18,7 @@ import { Switch } from "@/components/ui/switch";
import { useDialogStore } from "@/dialogs/store";
import { useFormBlocker } from "@/hooks/use-form-blocker";
import { projectItemSchema } from "@/schema/resume/data";
import { createSectionItem, updateSectionItem } from "@/utils/resume/section-actions";
import { generateId } from "@/utils/string";
const formSchema = projectItemSchema;
@@ -43,12 +44,7 @@ export function CreateProjectDialog({ data }: DialogProps<"resume.sections.proje
const onSubmit = (formData: FormValues) => {
updateResumeData((draft) => {
if (data?.customSectionId) {
const section = draft.customSections.find((s) => s.id === data.customSectionId);
if (section) section.items.push(formData);
} else {
draft.sections.projects.items.push(formData);
}
createSectionItem(draft, "projects", formData, data?.customSectionId);
});
closeDialog();
};
@@ -103,15 +99,7 @@ export function UpdateProjectDialog({ data }: DialogProps<"resume.sections.proje
const onSubmit = (formData: FormValues) => {
updateResumeData((draft) => {
if (data?.customSectionId) {
const section = draft.customSections.find((s) => s.id === data.customSectionId);
if (!section) return;
const index = section.items.findIndex((item) => item.id === formData.id);
if (index !== -1) section.items[index] = formData;
} else {
const index = draft.sections.projects.items.findIndex((item) => item.id === formData.id);
if (index !== -1) draft.sections.projects.items[index] = formData;
}
updateSectionItem(draft, "projects", formData, data?.customSectionId);
});
closeDialog();
};
+3 -15
View File
@@ -18,6 +18,7 @@ import { Switch } from "@/components/ui/switch";
import { useDialogStore } from "@/dialogs/store";
import { useFormBlocker } from "@/hooks/use-form-blocker";
import { publicationItemSchema } from "@/schema/resume/data";
import { createSectionItem, updateSectionItem } from "@/utils/resume/section-actions";
import { generateId } from "@/utils/string";
const formSchema = publicationItemSchema;
@@ -44,12 +45,7 @@ export function CreatePublicationDialog({ data }: DialogProps<"resume.sections.p
const onSubmit = (formData: FormValues) => {
updateResumeData((draft) => {
if (data?.customSectionId) {
const section = draft.customSections.find((s) => s.id === data.customSectionId);
if (section) section.items.push(formData);
} else {
draft.sections.publications.items.push(formData);
}
createSectionItem(draft, "publications", formData, data?.customSectionId);
});
closeDialog();
};
@@ -105,15 +101,7 @@ export function UpdatePublicationDialog({ data }: DialogProps<"resume.sections.p
const onSubmit = (formData: FormValues) => {
updateResumeData((draft) => {
if (data?.customSectionId) {
const section = draft.customSections.find((s) => s.id === data.customSectionId);
if (!section) return;
const index = section.items.findIndex((item) => item.id === formData.id);
if (index !== -1) section.items[index] = formData;
} else {
const index = draft.sections.publications.items.findIndex((item) => item.id === formData.id);
if (index !== -1) draft.sections.publications.items[index] = formData;
}
updateSectionItem(draft, "publications", formData, data?.customSectionId);
});
closeDialog();
};
+3 -15
View File
@@ -18,6 +18,7 @@ import { Switch } from "@/components/ui/switch";
import { useDialogStore } from "@/dialogs/store";
import { useFormBlocker } from "@/hooks/use-form-blocker";
import { referenceItemSchema } from "@/schema/resume/data";
import { createSectionItem, updateSectionItem } from "@/utils/resume/section-actions";
import { generateId } from "@/utils/string";
const formSchema = referenceItemSchema;
@@ -44,12 +45,7 @@ export function CreateReferenceDialog({ data }: DialogProps<"resume.sections.ref
const onSubmit = (formData: FormValues) => {
updateResumeData((draft) => {
if (data?.customSectionId) {
const section = draft.customSections.find((s) => s.id === data.customSectionId);
if (section) section.items.push(formData);
} else {
draft.sections.references.items.push(formData);
}
createSectionItem(draft, "references", formData, data?.customSectionId);
});
closeDialog();
};
@@ -105,15 +101,7 @@ export function UpdateReferenceDialog({ data }: DialogProps<"resume.sections.ref
const onSubmit = (formData: FormValues) => {
updateResumeData((draft) => {
if (data?.customSectionId) {
const section = draft.customSections.find((s) => s.id === data.customSectionId);
if (!section) return;
const index = section.items.findIndex((item) => item.id === formData.id);
if (index !== -1) section.items[index] = formData;
} else {
const index = draft.sections.references.items.findIndex((item) => item.id === formData.id);
if (index !== -1) draft.sections.references.items[index] = formData;
}
updateSectionItem(draft, "references", formData, data?.customSectionId);
});
closeDialog();
};

Some files were not shown because too many files have changed in this diff Show More