Compare commits
254 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b3b3a0e5a8 | ||
|
|
a92eeaf149 | ||
|
|
86989362fe | ||
|
|
cb81749dbf | ||
|
|
0bac419c3a | ||
|
|
1fa4748168 | ||
|
|
c1318a2cc4 | ||
|
|
cc2e656e14 | ||
|
|
77f87daeba | ||
|
|
64479f0858 | ||
|
|
4c235c7d00 | ||
|
|
c0d2d5a9ec | ||
|
|
dae647a4be | ||
|
|
f27bb79a07 | ||
|
|
631d273b02 | ||
|
|
d4b21f8f4e | ||
|
|
a407606f1c | ||
|
|
4f21242e39 | ||
|
|
2a4f085e18 | ||
|
|
253514a6e9 | ||
|
|
e18c829ae7 | ||
|
|
9329eaf3a9 | ||
|
|
292597e7c6 | ||
|
|
e377fb5b06 | ||
|
|
84f86032c9 | ||
|
|
834db6b39d | ||
|
|
97453803d6 | ||
|
|
1c99bd1886 | ||
|
|
5359ae193b | ||
|
|
325d5e6df7 | ||
|
|
79d92ca8c9 | ||
|
|
2480049fd1 | ||
|
|
5c71e4ce58 | ||
|
|
77834aa3c0 | ||
|
|
76fb3500ec | ||
|
|
2d5dd81371 | ||
|
|
c6f7ce48d8 | ||
|
|
64aca507af | ||
|
|
d813971809 | ||
|
|
7729917611 | ||
|
|
96ba672b09 | ||
|
|
7d36090e46 | ||
|
|
f43369c960 | ||
|
|
64fa636413 | ||
|
|
c1f6431174 | ||
|
|
537ab0568b | ||
|
|
b095f26d61 | ||
|
|
2d776e973a | ||
|
|
ddb726ad1f | ||
|
|
67593ec284 | ||
|
|
6bc5982294 | ||
|
|
1dd01e0eca | ||
|
|
7ec8bfe7e6 | ||
|
|
bc62f22e6d | ||
|
|
9e9659c9fe | ||
|
|
ef7810f2d2 | ||
|
|
c8c9f46623 | ||
|
|
95b31fb14d | ||
|
|
cbba7f6b79 | ||
|
|
fc12f93316 | ||
|
|
27560a078c | ||
|
|
cf460b3ba7 | ||
|
|
bd54ee6ab8 | ||
|
|
4e0c7eb03c | ||
|
|
9e6f21fc18 | ||
|
|
a71ccbe16b | ||
|
|
dce6ba46f2 | ||
|
|
3d140091d4 | ||
|
|
3e9c9b465d | ||
|
|
578a5dbc84 | ||
|
|
87a623657f | ||
|
|
a1c614d1ff | ||
|
|
bb5acd8204 | ||
|
|
b2a3055840 | ||
|
|
1a06928f8b | ||
|
|
222b24069c | ||
|
|
92795317fe | ||
|
|
a77c63b73c | ||
|
|
415b2af31a | ||
|
|
605eb7f4e6 | ||
|
|
1163085c61 | ||
|
|
0ed140a9aa | ||
|
|
57e75d689a | ||
|
|
f3808dc0e1 | ||
|
|
dd04d6536c | ||
|
|
96ccf63367 | ||
|
|
735b288c40 | ||
|
|
3eedf2bc6b | ||
|
|
061ca90ef1 | ||
|
|
a4f141c7b9 | ||
|
|
f914a4d9bd | ||
|
|
1fabd374ab | ||
|
|
3bb1cc7114 | ||
|
|
6b066846c8 | ||
|
|
feae64883b | ||
|
|
78ddbaf4ed | ||
|
|
dedc5f4cdc | ||
|
|
a1f609c551 | ||
|
|
689e390190 | ||
|
|
249434de44 | ||
|
|
d09c32216f | ||
|
|
8b6d82c657 | ||
|
|
dc9ec6f9bd | ||
|
|
68d9d3d642 | ||
|
|
74efb48236 | ||
|
|
206eb69dec | ||
|
|
43387dc56d | ||
|
|
7c434602f5 | ||
|
|
ba876ac8bf | ||
|
|
afe3964198 | ||
|
|
7c5b5d534e | ||
|
|
4653074811 | ||
|
|
bcd19c5f67 | ||
|
|
cb5e23086a | ||
|
|
87f7f98a64 | ||
|
|
436f2913a5 | ||
|
|
0f1b4a3296 | ||
|
|
2c82f3f4c0 | ||
|
|
98b2692d07 | ||
|
|
e1725e92d4 | ||
|
|
2d8cb79053 | ||
|
|
b42c5101b4 | ||
|
|
c73423a5d1 | ||
|
|
1eb36ed8e9 | ||
|
|
de1034278e | ||
|
|
a88418fa36 | ||
|
|
83ecc89bc5 | ||
|
|
1c89549b01 | ||
|
|
62e401e215 | ||
|
|
b75527fe6c | ||
|
|
8d6874072e | ||
|
|
0b6f9b581b | ||
|
|
9848adf8c8 | ||
|
|
44647c4e38 | ||
|
|
36d33bba48 | ||
|
|
9d9b4a37fb | ||
|
|
e0949a9c33 | ||
|
|
a2fd65234b | ||
|
|
98693961d4 | ||
|
|
b4512a6cbc | ||
|
|
b98c097b34 | ||
|
|
fa4c11b2ee | ||
|
|
4f0f9e25c5 | ||
|
|
328dcac0e4 | ||
|
|
56a5b49fca | ||
|
|
0669ee9499 | ||
|
|
64cd0baa5e | ||
|
|
9860e9d25a | ||
|
|
f9c2539fbb | ||
|
|
ede1a11099 | ||
|
|
6e97c70570 | ||
|
|
e2b41c85f6 | ||
|
|
677376983b | ||
|
|
2918eda784 | ||
|
|
ba8d8fbdb1 | ||
|
|
f193c46d73 | ||
|
|
da1c8f1068 | ||
|
|
8b33ba7c5d | ||
|
|
323ffe72a0 | ||
|
|
5d2d696ddd | ||
|
|
081942a6cd | ||
|
|
462af85a38 | ||
|
|
2c31919533 | ||
|
|
72aa57f018 | ||
|
|
0e98a556da | ||
|
|
bdac10ac57 | ||
|
|
6dc7c3d370 | ||
|
|
97a7b12d87 | ||
|
|
c88790abac | ||
|
|
0de0d3ebc0 | ||
|
|
7eba12e718 | ||
|
|
41c58505fa | ||
|
|
a58888f0e6 | ||
|
|
fb4d4efe66 | ||
|
|
5c9afa0b6e | ||
|
|
e2816bc54d | ||
|
|
9b71ce910b | ||
|
|
946190c9e0 | ||
|
|
3e4a44bd00 | ||
|
|
1c1e8e218b | ||
|
|
236deb465a | ||
|
|
f0cdcd4f45 | ||
|
|
e26100c308 | ||
|
|
f1f6d45e41 | ||
|
|
32b86c0dde | ||
|
|
6d968d6a2d | ||
|
|
4642ad1918 | ||
|
|
0d7f178d68 | ||
|
|
8af2ed3702 | ||
|
|
25eb13d12a | ||
|
|
7e8802052a | ||
|
|
5199240148 | ||
|
|
8c9bf0db1d | ||
|
|
d34a7e7d34 | ||
|
|
4e5222758d | ||
|
|
6ace462797 | ||
|
|
7e4b4b8fd6 | ||
|
|
9bc82b9dc5 | ||
|
|
dbd1fa72c4 | ||
|
|
43ffb3da5a | ||
|
|
6100738db6 | ||
|
|
c8f97f6957 | ||
|
|
5cbc8a4c37 | ||
|
|
2b7dfe68c2 | ||
|
|
30ab8d755d | ||
|
|
77dd689cc6 | ||
|
|
8dc2340b46 | ||
|
|
950807693c | ||
|
|
d760ede92f | ||
|
|
784b667e95 | ||
|
|
677ba280a3 | ||
|
|
e154d3b80e | ||
|
|
7f4c47475b | ||
|
|
9921289c9d | ||
|
|
80d3b1b7e2 | ||
|
|
36f7dc79e0 | ||
|
|
96fc6eb448 | ||
|
|
9244070e30 | ||
|
|
c5130ef46a | ||
|
|
c474041c7c | ||
|
|
c649e051d8 | ||
|
|
207888affe | ||
|
|
5f0c5cdc5d | ||
|
|
5b7594ac64 | ||
|
|
90a38bf091 | ||
|
|
eecfc98ebc | ||
|
|
6428239be2 | ||
|
|
4c6e244069 | ||
|
|
af926b033e | ||
|
|
b7bdfa7885 | ||
|
|
309fd32d50 | ||
|
|
2442b0c441 | ||
|
|
5d8095bd9c | ||
|
|
1a8aeb84cc | ||
|
|
b2529a0091 | ||
|
|
841f83d6ae | ||
|
|
731c46b26a | ||
|
|
612924e7c3 | ||
|
|
78760ceebb | ||
|
|
e05aa2d169 | ||
|
|
1ddf2539e0 | ||
|
|
83a5760959 | ||
|
|
0215a78404 | ||
|
|
475806ac29 | ||
|
|
903d022877 | ||
|
|
5fb0b5b656 | ||
|
|
0b4b21bbb0 | ||
|
|
555c9d0774 | ||
|
|
48dbc7a152 | ||
|
|
784ffbcd00 | ||
|
|
412faf4ad5 | ||
|
|
a05f8dc4a4 | ||
|
|
dfa07aa5d1 | ||
|
|
34aa76504e |
20
.github/workflows/build.yml
vendored
20
.github/workflows/build.yml
vendored
@@ -9,13 +9,13 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Use Node.js 20
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20.x
|
||||
cache: 'npm'
|
||||
- name: Install dependencies
|
||||
run: npm i
|
||||
- run: npm run build
|
||||
- run: npm run lint:ci
|
||||
- uses: actions/checkout@v7
|
||||
- name: Use Node.js 20
|
||||
uses: actions/setup-node@v7
|
||||
with:
|
||||
node-version: 20.x
|
||||
cache: 'npm'
|
||||
- name: Install dependencies
|
||||
run: npm i
|
||||
- run: npm run build
|
||||
- run: npm run lint:ci
|
||||
|
||||
@@ -1,2 +1,13 @@
|
||||
LICENSE.md
|
||||
dist/
|
||||
build/
|
||||
vendor/
|
||||
android/
|
||||
ios/
|
||||
resources/
|
||||
.bundle/
|
||||
.agents/
|
||||
.impeccable/
|
||||
package-lock.json
|
||||
Gemfile.lock
|
||||
skills-lock.json
|
||||
|
||||
@@ -12,15 +12,16 @@ Builds and (optionally) uploads signed Android and iOS release artifacts from th
|
||||
|
||||
Common flags on `release.sh`:
|
||||
|
||||
| Flag | Effect |
|
||||
|---|---|
|
||||
| `--android` / `--ios` | Build only one platform |
|
||||
| `--bump minor\|major` | Bump type (default: `patch`) |
|
||||
| `--skip-bump` | Build with the current version, don't bump |
|
||||
| `--upload` | Upload after building |
|
||||
| `--track TRACK` | Play Store track for `--upload` (default: `internal`) |
|
||||
| Flag | Effect |
|
||||
| --------------------- | ----------------------------------------------------- |
|
||||
| `--android` / `--ios` | Build only one platform |
|
||||
| `--bump minor\|major` | Bump type (default: `patch`) |
|
||||
| `--skip-bump` | Build with the current version, don't bump |
|
||||
| `--upload` | Upload after building |
|
||||
| `--track TRACK` | Play Store track for `--upload` (default: `internal`) |
|
||||
|
||||
Outputs:
|
||||
|
||||
- Android: `android/app/build/outputs/bundle/release/app-release.aab`
|
||||
- iOS: `build/ios/Donetick.ipa`
|
||||
|
||||
@@ -36,15 +37,15 @@ Outputs:
|
||||
|
||||
All secrets live in Vaultwarden (`https://www.bitwarden.com`) as Secure Notes, named exactly as below:
|
||||
|
||||
| Vault item name | Written to | Encoding |
|
||||
|---|---|---|
|
||||
| Donetick Google Services Android | `android/app/google-services.json` | raw |
|
||||
| Donetick Android Keystore | `android/app/release/donetick.jks` | base64 |
|
||||
| Donetick Keystore Password | (used inline for `android/keystore.properties`) | raw |
|
||||
| Donetick Google Play Service Account | `android/play-service-account.json` | raw |
|
||||
| Donetick Google Services iOS | `ios/App/App/GoogleService-Info.plist` | raw |
|
||||
| Donetick App Store Connect Key | `ios/AuthKey_84F695CDQ3.p8` | base64 |
|
||||
| Donetick Env Production | `.env.production` | raw |
|
||||
| Vault item name | Written to | Encoding |
|
||||
| ------------------------------------ | ----------------------------------------------- | -------- |
|
||||
| Donetick Google Services Android | `android/app/google-services.json` | raw |
|
||||
| Donetick Android Keystore | `android/app/release/donetick.jks` | base64 |
|
||||
| Donetick Keystore Password | (used inline for `android/keystore.properties`) | raw |
|
||||
| Donetick Google Play Service Account | `android/play-service-account.json` | raw |
|
||||
| Donetick Google Services iOS | `ios/App/App/GoogleService-Info.plist` | raw |
|
||||
| Donetick App Store Connect Key | `ios/AuthKey_84F695CDQ3.p8` | base64 |
|
||||
| Donetick Env Production | `.env.production` | raw |
|
||||
|
||||
None of these files are committed to git — all covered by `.gitignore`.
|
||||
|
||||
@@ -57,6 +58,7 @@ The App target uses **manual signing for Release**, not Automatic. This was a de
|
||||
- `fastlane/Fastfile`'s `ios release` lane passes explicit `export_options: { signingStyle: "manual", provisioningProfiles: {...} }` to `build_app` — do **not** switch this back to `-allowProvisioningUpdates`/automatic without a good reason, it re-triggers the ambiguous cert selection.
|
||||
|
||||
**If you ever add/change an entitlement** (new Capability in Signing & Capabilities, e.g. a new permission), the existing provisioning profile becomes stale and exports will fail with an error like `"App.app" requires a provisioning profile with the X feature`. Fix:
|
||||
|
||||
1. developer.apple.com → Identifiers → `com.donetick.app` → confirm the new capability is checked
|
||||
2. developer.apple.com → Profiles → find `Donetick App Store(fastline)` → regenerate it → download
|
||||
3. Install it locally: get its UUID (`security cms -D -i <file>.mobileprovision | plutil -extract UUID xml1 -o - -`) and copy to `~/Library/MobileDevice/Provisioning Profiles/<uuid>.mobileprovision`
|
||||
|
||||
@@ -13,8 +13,8 @@ android {
|
||||
applicationId "com.donetick.app"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 57
|
||||
versionName "1.2.36"
|
||||
versionCode 70
|
||||
versionName "1.2.49"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
aaptOptions {
|
||||
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
|
||||
|
||||
@@ -21,6 +21,7 @@ dependencies {
|
||||
implementation project(':capacitor-network')
|
||||
implementation project(':capacitor-preferences')
|
||||
implementation project(':capacitor-push-notifications')
|
||||
implementation project(':capacitor-share')
|
||||
implementation project(':capacitor-status-bar')
|
||||
implementation project(':capgo-capacitor-document-scanner')
|
||||
implementation project(':capgo-capacitor-nfc')
|
||||
|
||||
@@ -21,17 +21,13 @@
|
||||
{
|
||||
"minApi": 28,
|
||||
"maxApi": 30,
|
||||
"baselineProfiles": [
|
||||
"baselineProfiles/1/app-release.dm"
|
||||
]
|
||||
"baselineProfiles": ["baselineProfiles/1/app-release.dm"]
|
||||
},
|
||||
{
|
||||
"minApi": 31,
|
||||
"maxApi": 2147483647,
|
||||
"baselineProfiles": [
|
||||
"baselineProfiles/0/app-release.dm"
|
||||
]
|
||||
"baselineProfiles": ["baselineProfiles/0/app-release.dm"]
|
||||
}
|
||||
],
|
||||
"minSdkVersionForDexing": 28
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,17 @@
|
||||
<data android:scheme="donetick" />
|
||||
</intent-filter>
|
||||
|
||||
<!-- Verified App Link for Circle invites hosted by Donetick Cloud. -->
|
||||
<intent-filter android:autoVerify="true">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data
|
||||
android:scheme="https"
|
||||
android:host="app.donetick.com"
|
||||
android:pathPrefix="/circle/join" />
|
||||
</intent-filter>
|
||||
|
||||
<!-- NFC NDEF dispatch: open app directly when a donetick:// tag is scanned -->
|
||||
<intent-filter>
|
||||
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":1,"sessions":{}}
|
||||
{ "version": 1, "sessions": {} }
|
||||
|
||||
@@ -38,6 +38,9 @@ project(':capacitor-preferences').projectDir = new File('../node_modules/@capaci
|
||||
include ':capacitor-push-notifications'
|
||||
project(':capacitor-push-notifications').projectDir = new File('../node_modules/@capacitor/push-notifications/android')
|
||||
|
||||
include ':capacitor-share'
|
||||
project(':capacitor-share').projectDir = new File('../node_modules/@capacitor/share/android')
|
||||
|
||||
include ':capacitor-status-bar'
|
||||
project(':capacitor-status-bar').projectDir = new File('../node_modules/@capacitor/status-bar/android')
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Crowdin configuration for Donetick
|
||||
# See: https://support.crowdin.com/configuration-file/
|
||||
|
||||
project_id: "donetick"
|
||||
project_id: 'donetick'
|
||||
api_token_env: CROWDIN_API_TOKEN
|
||||
preserve_hierarchy: true
|
||||
|
||||
@@ -13,3 +13,4 @@ files:
|
||||
- source: /public/locales/en/*.json
|
||||
translation: /public/locales/%two_letters_code%/%original_file_name%
|
||||
update_option: update_as_unapproved
|
||||
skip_untranslated_strings: true
|
||||
|
||||
5
e2e/.gitignore
vendored
Normal file
5
e2e/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
node_modules/
|
||||
.auth/
|
||||
playwright-report/
|
||||
test-results/
|
||||
.e2e-run/
|
||||
21
e2e/debug.mjs
Normal file
21
e2e/debug.mjs
Normal file
@@ -0,0 +1,21 @@
|
||||
import { chromium } from '@playwright/test'
|
||||
import { readFile } from 'fs/promises'
|
||||
|
||||
const state = JSON.parse(await readFile('.auth/state.json', 'utf8'))
|
||||
const browser = await chromium.launch()
|
||||
const context = await browser.newContext({ storageState: state })
|
||||
const page = await context.newPage()
|
||||
page.on('console', msg => console.log('[console]', msg.type(), msg.text()))
|
||||
page.on('pageerror', err =>
|
||||
console.log('[pageerror]', err.message, '\n', err.stack),
|
||||
)
|
||||
|
||||
await page.goto('http://localhost:5173/chores/create')
|
||||
await page.getByTestId('chore-name-input').fill('Debug Chore ' + Date.now())
|
||||
await page.getByLabel('Repeat this task').click()
|
||||
await page.getByLabel('Daily').click()
|
||||
await page.getByRole('button', { name: 'Create' }).click()
|
||||
await page.waitForURL('**/chores', { timeout: 15000 })
|
||||
await page.waitForTimeout(2000)
|
||||
|
||||
await browser.close()
|
||||
59
e2e/fixtures/auth.js
Normal file
59
e2e/fixtures/auth.js
Normal file
@@ -0,0 +1,59 @@
|
||||
import { expect, test as base } from '@playwright/test'
|
||||
import path from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
|
||||
/**
|
||||
* Fill and submit the signup form through the UI.
|
||||
* After successful signup the app auto-logs in and walks through the
|
||||
* onboarding flow (/circle-setup, then /ready) before landing on /chores.
|
||||
*/
|
||||
export async function signUpViaUI(
|
||||
page,
|
||||
{ displayName, email, password, username },
|
||||
) {
|
||||
await page.goto('/signup')
|
||||
await page.locator('#username').fill(username)
|
||||
await page.locator('#email').fill(email)
|
||||
await page.locator('#password').fill(password)
|
||||
await page.locator('#displayName').fill(displayName)
|
||||
await page.getByRole('button', { name: 'Create account' }).click()
|
||||
|
||||
await page.waitForURL('**/circle-setup', { timeout: 10_000 })
|
||||
await page.getByRole('button', { name: 'Continue' }).click()
|
||||
|
||||
await page.waitForURL('**/ready', { timeout: 10_000 })
|
||||
await page.getByRole('button', { name: 'Continue' }).click()
|
||||
|
||||
await page.waitForURL('**/chores', { timeout: 10_000 })
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill and submit the login form through the UI.
|
||||
* After successful login the app redirects to /chores.
|
||||
*/
|
||||
export async function loginViaUI(page, { password, username }) {
|
||||
await page.goto('/login')
|
||||
await page.locator('#username').fill(username)
|
||||
await page.locator('#password').fill(password)
|
||||
await page.getByRole('button', { name: 'Sign In' }).click()
|
||||
await page.waitForURL('**/chores', { timeout: 10_000 })
|
||||
}
|
||||
|
||||
/**
|
||||
* A Playwright test fixture that provides a page already authenticated as the
|
||||
* shared E2E user (via persisted storage state, no UI interaction required).
|
||||
*/
|
||||
export const test = base.extend({
|
||||
authenticatedPage: async ({ browser }, callback) => {
|
||||
const ctx = await browser.newContext({
|
||||
storageState: path.join(__dirname, '..', '.auth', 'state.json'),
|
||||
})
|
||||
const page = await ctx.newPage()
|
||||
await callback(page)
|
||||
await ctx.close()
|
||||
},
|
||||
})
|
||||
|
||||
export { expect }
|
||||
100
e2e/global-setup.js
Normal file
100
e2e/global-setup.js
Normal file
@@ -0,0 +1,100 @@
|
||||
import { mkdir, writeFile } from 'fs/promises'
|
||||
import path from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
|
||||
// FRONTEND_URL: what the browser navigates to (Playwright baseURL)
|
||||
// API_URL: where the Go API lives (may be the same in production builds)
|
||||
export const FRONTEND_URL =
|
||||
process.env.E2E_FRONTEND_URL ||
|
||||
process.env.E2E_BASE_URL ||
|
||||
'http://localhost:5173'
|
||||
export const API_URL =
|
||||
process.env.E2E_API_URL || process.env.E2E_BASE_URL || 'http://localhost:2021'
|
||||
|
||||
export const TEST_USER = {
|
||||
username: 'e2e.user',
|
||||
email: 'e2e@donetick.test',
|
||||
password: 'E2ePassword123!',
|
||||
displayName: 'E2E User',
|
||||
}
|
||||
|
||||
/**
|
||||
* Global setup: create the shared E2E test user (idempotent) and persist
|
||||
* the JWT token as a Playwright storage state so authenticated tests can
|
||||
* skip the login UI.
|
||||
*/
|
||||
export default async function globalSetup() {
|
||||
await waitForServer(API_URL)
|
||||
|
||||
// Create user – ignore 409/conflict so re-runs are safe
|
||||
const signupRes = await fetch(`${API_URL}/api/v1/auth/`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(TEST_USER),
|
||||
})
|
||||
if (!signupRes.ok) {
|
||||
const body = await signupRes.text()
|
||||
// Treat "already exists" errors as success so re-runs are idempotent
|
||||
if (!body.includes('already exists') && !body.includes('already taken')) {
|
||||
throw new Error(`Signup failed (${signupRes.status}): ${body}`)
|
||||
}
|
||||
}
|
||||
|
||||
// Login and grab the access token
|
||||
const loginRes = await fetch(`${API_URL}/api/v1/auth/login`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
username: TEST_USER.username,
|
||||
password: TEST_USER.password,
|
||||
}),
|
||||
})
|
||||
if (!loginRes.ok) {
|
||||
const body = await loginRes.text()
|
||||
throw new Error(`Login failed (${loginRes.status}): ${body}`)
|
||||
}
|
||||
|
||||
const { expire, token } = await loginRes.json()
|
||||
|
||||
// Write a Playwright storage-state file containing the token in localStorage
|
||||
const stateDir = path.join(__dirname, '.auth')
|
||||
await mkdir(stateDir, { recursive: true })
|
||||
await writeFile(
|
||||
path.join(stateDir, 'state.json'),
|
||||
JSON.stringify({
|
||||
cookies: [],
|
||||
origins: [
|
||||
{
|
||||
origin: FRONTEND_URL,
|
||||
localStorage: [
|
||||
{ name: 'token', value: token },
|
||||
{ name: 'token_expiry', value: expire },
|
||||
],
|
||||
},
|
||||
],
|
||||
}),
|
||||
'utf8',
|
||||
)
|
||||
|
||||
console.log('[global-setup] Test user ready, storage state saved.')
|
||||
}
|
||||
|
||||
async function waitForServer(url, retries = 20, delayMs = 1000) {
|
||||
for (let i = 0; i < retries; i++) {
|
||||
try {
|
||||
const res = await fetch(`${url}/api/v1/auth/login`, {
|
||||
method: 'POST',
|
||||
body: '{}',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
})
|
||||
if (res.status < 500) return
|
||||
} catch {
|
||||
// server not up yet
|
||||
}
|
||||
console.log(`[global-setup] Waiting for server… (${i + 1}/${retries})`)
|
||||
await new Promise(r => setTimeout(r, delayMs))
|
||||
}
|
||||
throw new Error(`Server at ${url} did not become ready in time`)
|
||||
}
|
||||
78
e2e/package-lock.json
generated
Normal file
78
e2e/package-lock.json
generated
Normal file
@@ -0,0 +1,78 @@
|
||||
{
|
||||
"name": "donetick-e2e",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "donetick-e2e",
|
||||
"version": "1.0.0",
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.44.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@playwright/test": {
|
||||
"version": "1.59.1",
|
||||
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.59.1.tgz",
|
||||
"integrity": "sha512-PG6q63nQg5c9rIi4/Z5lR5IVF7yU5MqmKaPOe0HSc0O2cX1fPi96sUQu5j7eo4gKCkB2AnNGoWt7y4/Xx3Kcqg==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright": "1.59.1"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/playwright": {
|
||||
"version": "1.59.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.59.1.tgz",
|
||||
"integrity": "sha512-C8oWjPR3F81yljW9o5OxcWzfh6avkVwDD2VYdwIGqTkl+OGFISgypqzfu7dOe4QNLL2aqcWBmI3PMtLIK233lw==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright-core": "1.59.1"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "2.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/playwright-core": {
|
||||
"version": "1.59.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.59.1.tgz",
|
||||
"integrity": "sha512-HBV/RJg81z5BiiZ9yPzIiClYV/QMsDCKUyogwH9p3MCP6IYjUFu/MActgYAvK0oWyV9NlwM3GLBjADyWgydVyg==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"playwright-core": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
15
e2e/package.json
Normal file
15
e2e/package.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "donetick-e2e",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"test": "playwright test",
|
||||
"test:headed": "playwright test --headed",
|
||||
"test:report": "playwright show-report",
|
||||
"test:full": "./run-e2e.sh"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.44.0"
|
||||
}
|
||||
}
|
||||
32
e2e/playwright.config.js
Normal file
32
e2e/playwright.config.js
Normal file
@@ -0,0 +1,32 @@
|
||||
import { defineConfig, devices } from '@playwright/test'
|
||||
|
||||
// When frontend and backend are the same origin (embedded binary) set E2E_BASE_URL.
|
||||
// For dev, set E2E_FRONTEND_URL (default 5173) and E2E_API_URL (default 2021) separately.
|
||||
const FRONTEND_URL =
|
||||
process.env.E2E_FRONTEND_URL ||
|
||||
process.env.E2E_BASE_URL ||
|
||||
'http://localhost:5173'
|
||||
|
||||
export default defineConfig({
|
||||
testDir: './tests',
|
||||
timeout: 30_000,
|
||||
retries: process.env.CI ? 2 : 0,
|
||||
workers: 1, // sequential – single SQLite DB
|
||||
reporter: process.env.CI ? 'github' : 'list',
|
||||
|
||||
use: {
|
||||
baseURL: FRONTEND_URL,
|
||||
headless: true,
|
||||
trace: 'on-first-retry',
|
||||
screenshot: 'only-on-failure',
|
||||
},
|
||||
|
||||
globalSetup: './global-setup.js',
|
||||
|
||||
projects: [
|
||||
{
|
||||
name: 'chromium',
|
||||
use: { ...devices['Desktop Chrome'] },
|
||||
},
|
||||
],
|
||||
})
|
||||
118
e2e/run-e2e.sh
Executable file
118
e2e/run-e2e.sh
Executable file
@@ -0,0 +1,118 @@
|
||||
#!/usr/bin/env bash
|
||||
# Starts an isolated backend + frontend for this repo, runs the Playwright
|
||||
# suite against them, then tears both servers down. Uses dedicated ports
|
||||
# (2022/5180) so it never touches dev servers you may have running elsewhere
|
||||
# (e.g. another worktree on the default 2021/5173).
|
||||
set -uo pipefail
|
||||
set -m # each backgrounded job gets its own process group, so we can kill it as a unit (portable alternative to setsid, which isn't available on macOS)
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
FRONTEND_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
BACKEND_DIR="$HOME/workspace/donetick-core"
|
||||
|
||||
BACKEND_PORT=2022
|
||||
FRONTEND_PORT=5180
|
||||
BACKEND_URL="http://localhost:$BACKEND_PORT"
|
||||
FRONTEND_URL="http://localhost:$FRONTEND_PORT"
|
||||
|
||||
LOG_DIR="$SCRIPT_DIR/.e2e-run"
|
||||
mkdir -p "$LOG_DIR"
|
||||
|
||||
BACKEND_PID=""
|
||||
FRONTEND_PID=""
|
||||
|
||||
cleanup() {
|
||||
echo "--- Stopping e2e servers ---"
|
||||
[[ -n "$FRONTEND_PID" ]] && kill -TERM -"$FRONTEND_PID" 2>/dev/null
|
||||
[[ -n "$BACKEND_PID" ]] && kill -TERM -"$BACKEND_PID" 2>/dev/null
|
||||
sleep 1
|
||||
[[ -n "$FRONTEND_PID" ]] && kill -KILL -"$FRONTEND_PID" 2>/dev/null
|
||||
[[ -n "$BACKEND_PID" ]] && kill -KILL -"$BACKEND_PID" 2>/dev/null
|
||||
wait 2>/dev/null
|
||||
}
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
kill_port() {
|
||||
local port=$1
|
||||
local pids
|
||||
pids=$(lsof -ti tcp:"$port" 2>/dev/null || true)
|
||||
if [[ -n "$pids" ]]; then
|
||||
echo "Port $port in use by leftover process(es) $pids — killing."
|
||||
kill -TERM $pids 2>/dev/null
|
||||
sleep 1
|
||||
kill -KILL $pids 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
wait_for_backend() {
|
||||
for ((i = 1; i <= 40; i++)); do
|
||||
if curl -s -o /dev/null -w '%{http_code}' -X POST "$BACKEND_URL/api/v1/auth/login" \
|
||||
-H 'Content-Type: application/json' -d '{}' 2>/dev/null | grep -qE '^[0-9]+$'; then
|
||||
return 0
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
wait_for_frontend() {
|
||||
for ((i = 1; i <= 40; i++)); do
|
||||
if curl -sf -o /dev/null "$FRONTEND_URL" 2>/dev/null; then
|
||||
return 0
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
kill_port "$BACKEND_PORT"
|
||||
kill_port "$FRONTEND_PORT"
|
||||
|
||||
echo "--- Starting backend on :$BACKEND_PORT (log: $LOG_DIR/backend.log) ---"
|
||||
(
|
||||
cd "$BACKEND_DIR"
|
||||
exec env \
|
||||
DT_NAME=e2e-frontend-repo \
|
||||
DT_IS_DONE_TICK_DOT_COM=false \
|
||||
DT_IS_USER_CREATION_DISABLED=false \
|
||||
DT_DATABASE_TYPE=sqlite \
|
||||
DT_DATABASE_MIGRATION=true \
|
||||
DT_JWT_SECRET=e2e_test_secret_change_this_32chars \
|
||||
DT_JWT_SESSION_TIME=168h \
|
||||
DT_JWT_MAX_REFRESH=168h \
|
||||
DT_SERVER_PORT="$BACKEND_PORT" \
|
||||
DT_SERVER_READ_TIMEOUT=10s \
|
||||
DT_SERVER_WRITE_TIMEOUT=10s \
|
||||
DT_SERVER_RATE_PERIOD=60s \
|
||||
DT_SERVER_RATE_LIMIT=300 \
|
||||
DT_SERVER_CORS_ALLOW_ORIGINS="$FRONTEND_URL" \
|
||||
DT_SERVER_SERVE_FRONTEND=false \
|
||||
go run .
|
||||
) > "$LOG_DIR/backend.log" 2>&1 &
|
||||
BACKEND_PID=$!
|
||||
|
||||
echo "--- Starting frontend on :$FRONTEND_PORT (log: $LOG_DIR/frontend.log) ---"
|
||||
(
|
||||
cd "$FRONTEND_DIR"
|
||||
exec env VITE_APP_API_URL="$BACKEND_URL" npx vite --port "$FRONTEND_PORT" --strictPort
|
||||
) > "$LOG_DIR/frontend.log" 2>&1 &
|
||||
FRONTEND_PID=$!
|
||||
|
||||
echo "Waiting for backend..."
|
||||
if ! wait_for_backend; then
|
||||
echo "Backend did not become ready. See $LOG_DIR/backend.log" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Waiting for frontend..."
|
||||
if ! wait_for_frontend; then
|
||||
echo "Frontend did not become ready. See $LOG_DIR/frontend.log" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "--- Running Playwright tests ---"
|
||||
cd "$SCRIPT_DIR"
|
||||
E2E_FRONTEND_URL="$FRONTEND_URL" E2E_API_URL="$BACKEND_URL" npx playwright test "$@"
|
||||
TEST_EXIT=$?
|
||||
|
||||
exit $TEST_EXIT
|
||||
174
e2e/tests/add-task-modal.spec.js
Normal file
174
e2e/tests/add-task-modal.spec.js
Normal file
@@ -0,0 +1,174 @@
|
||||
import { expect, test } from '../fixtures/auth.js'
|
||||
import { API_URL } from '../global-setup.js'
|
||||
|
||||
// Fetch the full chore list for the authenticated user via the API — used to
|
||||
// verify a task's persisted fields without relying on list-page badge markup.
|
||||
async function fetchChores(page) {
|
||||
const token = await page.evaluate(() => localStorage.getItem('token'))
|
||||
const apiRes = await fetch(`${API_URL}/api/v1/chores/`, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
})
|
||||
expect(apiRes.ok).toBe(true)
|
||||
const { res: chores } = await apiRes.json()
|
||||
return chores
|
||||
}
|
||||
|
||||
test.describe('AddTaskModal (quick-add)', () => {
|
||||
// All tests in this suite run as the pre-authenticated E2E user
|
||||
test.use({
|
||||
storageState: '.auth/state.json',
|
||||
})
|
||||
|
||||
test('creates a task from plain text title only and it appears in the list', async ({
|
||||
page,
|
||||
}) => {
|
||||
const taskName = `E2E Quick Task ${Date.now()}`
|
||||
|
||||
// ── Open the quick-add modal from the chores list ───────────────────────
|
||||
await page.goto('/chores')
|
||||
await page.getByTestId('open-add-task-modal').click()
|
||||
|
||||
const dialog = page.getByRole('dialog', { name: 'Create new task' })
|
||||
await expect(dialog).toBeVisible()
|
||||
|
||||
// ── Type a plain title (no parseable tokens) and submit with Enter ──────
|
||||
const input = dialog.locator('textarea')
|
||||
await input.fill(taskName)
|
||||
await input.press('Enter')
|
||||
|
||||
// ── Modal closes and the task shows up in the list ──────────────────────
|
||||
await expect(dialog).toBeHidden()
|
||||
await expect(page.getByText(taskName)).toBeVisible({ timeout: 10_000 })
|
||||
|
||||
// ── Verify it exists via the API too ─────────────────────────────────────
|
||||
const chores = await fetchChores(page)
|
||||
const created = chores.find(c => c.name === taskName)
|
||||
expect(created).toBeDefined()
|
||||
})
|
||||
|
||||
test('smart-parses a due date and priority from typed text', async ({
|
||||
page,
|
||||
}) => {
|
||||
// Kept lowercase: parsePriority's cleanup step lowercases the whole
|
||||
// sentence when a priority token matches, so an already-lowercase prefix
|
||||
// sidesteps that quirk and round-trips unchanged.
|
||||
const taskName = `e2e parse task ${Date.now()}`
|
||||
|
||||
await page.goto('/chores')
|
||||
await page.getByTestId('open-add-task-modal').click()
|
||||
|
||||
const dialog = page.getByRole('dialog', { name: 'Create new task' })
|
||||
await expect(dialog).toBeVisible()
|
||||
|
||||
const input = dialog.locator('textarea')
|
||||
await input.fill(`${taskName} !p1 tomorrow`)
|
||||
|
||||
// ── Confirm the smart parse is reflected in the pickers before saving ───
|
||||
await expect(
|
||||
dialog.getByRole('button', { name: 'P1', exact: true }),
|
||||
).toBeVisible()
|
||||
// The due-date trigger only ever reads "Due" in its empty state, so once
|
||||
// parsing lands a date the button relabels itself away from that text.
|
||||
await expect(
|
||||
dialog.getByRole('button', { name: 'Due', exact: true }),
|
||||
).toHaveCount(0)
|
||||
|
||||
await input.press('Enter')
|
||||
|
||||
await expect(dialog).toBeHidden()
|
||||
await expect(page.getByText(taskName)).toBeVisible({ timeout: 10_000 })
|
||||
|
||||
// ── Verify the parsed priority + due date persisted via the API ─────────
|
||||
const chores = await fetchChores(page)
|
||||
const created = chores.find(c => c.name === taskName)
|
||||
expect(created).toBeDefined()
|
||||
expect(created.priority).toBe(1)
|
||||
expect(created.nextDueDate).toBeTruthy()
|
||||
})
|
||||
|
||||
test('creates a task using the picker UI directly, skipping smart-parse tokens', async ({
|
||||
page,
|
||||
}) => {
|
||||
const taskName = `E2E Picker Task ${Date.now()}`
|
||||
|
||||
await page.goto('/chores')
|
||||
await page.getByTestId('open-add-task-modal').click()
|
||||
|
||||
const dialog = page.getByRole('dialog', { name: 'Create new task' })
|
||||
await expect(dialog).toBeVisible()
|
||||
|
||||
// Plain title only — none of "due date"/"priority"/"repeat" tokens.
|
||||
await dialog.locator('textarea').fill(taskName)
|
||||
|
||||
// ── Set the due date via the picker (Due → Tomorrow → Apply) ────────────
|
||||
await dialog.getByRole('button', { name: 'Due', exact: true }).click()
|
||||
const dueDateDialog = page.getByRole('dialog', { name: 'Due Date' })
|
||||
await dueDateDialog
|
||||
.getByRole('checkbox', { name: 'Tomorrow', exact: true })
|
||||
.click()
|
||||
await dueDateDialog
|
||||
.getByRole('button', { name: 'Apply', exact: true })
|
||||
.click()
|
||||
|
||||
// ── Set the priority via the picker (Priority → P2) ──────────────────────
|
||||
await dialog.getByRole('button', { name: 'Priority', exact: true }).click()
|
||||
await page.getByRole('button', { name: 'P2', exact: true }).click()
|
||||
await expect(
|
||||
dialog.getByRole('button', { name: 'P2', exact: true }),
|
||||
).toBeVisible()
|
||||
|
||||
// ── Set the repeat schedule via the picker (Repeat → Daily → Apply) ─────
|
||||
await dialog.getByRole('button', { name: 'Repeat', exact: true }).click()
|
||||
const repeatDialog = page.getByRole('dialog', { name: 'Repeat Schedule' })
|
||||
await repeatDialog
|
||||
.getByRole('checkbox', { name: 'Daily', exact: true })
|
||||
.click()
|
||||
await repeatDialog
|
||||
.getByRole('button', { name: 'Apply', exact: true })
|
||||
.click()
|
||||
|
||||
await dialog.getByRole('button', { name: 'Create', exact: true }).click()
|
||||
|
||||
await expect(dialog).toBeHidden()
|
||||
await expect(page.getByText(taskName)).toBeVisible({ timeout: 10_000 })
|
||||
|
||||
// ── Verify the picker-set values persisted via the API ───────────────────
|
||||
const chores = await fetchChores(page)
|
||||
const created = chores.find(c => c.name === taskName)
|
||||
expect(created).toBeDefined()
|
||||
expect(created.priority).toBe(2)
|
||||
expect(created.frequencyType).toBe('daily')
|
||||
expect(created.nextDueDate).toBeTruthy()
|
||||
})
|
||||
|
||||
test('Create button is disabled until the title is non-empty', async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.goto('/chores')
|
||||
await page.getByTestId('open-add-task-modal').click()
|
||||
|
||||
const dialog = page.getByRole('dialog', { name: 'Create new task' })
|
||||
await expect(dialog).toBeVisible()
|
||||
|
||||
const createButton = dialog.getByRole('button', {
|
||||
name: 'Create',
|
||||
exact: true,
|
||||
})
|
||||
const input = dialog.locator('textarea')
|
||||
|
||||
// ── Empty title ───────────────────────────────────────────────────────
|
||||
await expect(createButton).toBeDisabled()
|
||||
|
||||
// ── Whitespace-only title still counts as empty ─────────────────────────
|
||||
await input.fill(' ')
|
||||
await expect(createButton).toBeDisabled()
|
||||
|
||||
// ── Real text enables the button ─────────────────────────────────────────
|
||||
await input.fill('E2E Enable Check')
|
||||
await expect(createButton).toBeEnabled()
|
||||
|
||||
// No task should be created by this test — back out via Cancel.
|
||||
await dialog.getByRole('button', { name: 'Cancel', exact: true }).click()
|
||||
await expect(dialog).toBeHidden()
|
||||
})
|
||||
})
|
||||
68
e2e/tests/auth.spec.js
Normal file
68
e2e/tests/auth.spec.js
Normal file
@@ -0,0 +1,68 @@
|
||||
import { expect, test } from '@playwright/test'
|
||||
|
||||
import { loginViaUI, signUpViaUI } from '../fixtures/auth.js'
|
||||
|
||||
// Username must match /^[a-z.-]+$/ — no digits allowed.
|
||||
// Generate a random lowercase-only suffix for uniqueness across runs.
|
||||
function randomSuffix(len = 8) {
|
||||
const chars = 'abcdefghijklmnopqrstuvwxyz'
|
||||
return Array.from(
|
||||
{ length: len },
|
||||
() => chars[Math.floor(Math.random() * 26)],
|
||||
).join('')
|
||||
}
|
||||
|
||||
test.describe('Auth – Sign Up', () => {
|
||||
test('creates a new account and lands on /chores', async ({ page }) => {
|
||||
const suffix = randomSuffix()
|
||||
const user = {
|
||||
username: `test.signup.${suffix}`,
|
||||
email: `signup.${suffix}@donetick.test`,
|
||||
password: 'TestPassword123!',
|
||||
displayName: 'Test Signup User',
|
||||
}
|
||||
|
||||
await signUpViaUI(page, user)
|
||||
|
||||
await expect(page).toHaveURL(/\/chores/)
|
||||
})
|
||||
|
||||
test('shows an error when username is too short', async ({ page }) => {
|
||||
await page.goto('/signup')
|
||||
await page.locator('#username').fill('ab') // < 4 chars
|
||||
await page.locator('#email').fill('short@donetick.test')
|
||||
await page.locator('#password').fill('ValidPass123!')
|
||||
await page.locator('#displayName').fill('Short User')
|
||||
await page.getByRole('button', { name: 'Create account' }).click()
|
||||
|
||||
await expect(
|
||||
page.getByText('Username must be at least 4 characters'),
|
||||
).toBeVisible()
|
||||
})
|
||||
})
|
||||
|
||||
test.describe('Auth – Login', () => {
|
||||
// Re-use the shared E2E user that global-setup already created
|
||||
test('logs in with valid credentials and lands on /chores', async ({
|
||||
page,
|
||||
}) => {
|
||||
await loginViaUI(page, {
|
||||
username: 'e2e.user',
|
||||
password: 'E2ePassword123!',
|
||||
})
|
||||
|
||||
await expect(page).toHaveURL(/\/chores/)
|
||||
})
|
||||
|
||||
test('shows an error for wrong password', async ({ page }) => {
|
||||
await page.goto('/login')
|
||||
await page.locator('#username').fill('e2e.user')
|
||||
await page.locator('#password').fill('WrongPassword!')
|
||||
await page.getByRole('button', { name: 'Sign In' }).click()
|
||||
|
||||
// The notification snackbar / error message should appear
|
||||
await expect(
|
||||
page.getByText(/Login Failed|invalid|incorrect/i).first(),
|
||||
).toBeVisible({ timeout: 5_000 })
|
||||
})
|
||||
})
|
||||
150
e2e/tests/chore-edit.spec.js
Normal file
150
e2e/tests/chore-edit.spec.js
Normal file
@@ -0,0 +1,150 @@
|
||||
import { expect, test } from '../fixtures/auth.js'
|
||||
import { API_URL } from '../global-setup.js'
|
||||
|
||||
test.describe('ChoreEdit', () => {
|
||||
// All tests in this suite run as the pre-authenticated E2E user
|
||||
test.use({
|
||||
storageState: '.auth/state.json',
|
||||
})
|
||||
|
||||
test('blocks save and shows an error when the name is left blank', async ({
|
||||
page,
|
||||
}) => {
|
||||
// ── Navigate to the create chore page, leave the form at defaults ──────
|
||||
await page.goto('/chores/create')
|
||||
|
||||
// ── Attempt to save without a name ──────────────────────────────────────
|
||||
await page.getByRole('button', { name: 'Create' }).click()
|
||||
|
||||
// ── The validation error is shown and we never leave the create page ───
|
||||
await expect(page.getByText('Name is required').first()).toBeVisible({
|
||||
timeout: 5_000,
|
||||
})
|
||||
await expect(page).toHaveURL(/\/chores\/create/)
|
||||
})
|
||||
|
||||
test('days-of-the-week repeat: blocks save with no days selected, then succeeds once days are chosen', async ({
|
||||
page,
|
||||
}) => {
|
||||
const choreName = `E2E Weekly Chore ${Date.now()}`
|
||||
|
||||
// ── Navigate to the create chore page ────────────────────────────────
|
||||
await page.goto('/chores/create')
|
||||
|
||||
// ── Fill in the chore name ────────────────────────────────────────────
|
||||
await page.locator('input').first().fill(choreName)
|
||||
|
||||
// ── Enable recurrence and switch to a custom "days of the week" schedule
|
||||
await page.getByLabel('Repeat this task').click()
|
||||
await page.getByLabel('Custom').click()
|
||||
await page.getByLabel('Days of the Week').click()
|
||||
|
||||
// ── Attempt to save with zero days selected ─────────────────────────────
|
||||
await page.getByRole('button', { name: 'Create' }).click()
|
||||
await expect(
|
||||
page.getByText('Please select at least one day of the week').first(),
|
||||
).toBeVisible({ timeout: 5_000 })
|
||||
await expect(page).toHaveURL(/\/chores\/create/)
|
||||
|
||||
// ── Select Monday and Wednesday, then save successfully ────────────────
|
||||
await page.getByLabel('Monday').click()
|
||||
await page.getByLabel('Wednesday').click()
|
||||
await page.getByRole('button', { name: 'Create' }).click()
|
||||
|
||||
await page.waitForURL('**/chores', { timeout: 15_000 })
|
||||
await expect(page.getByText(choreName)).toBeVisible({ timeout: 10_000 })
|
||||
|
||||
// ── Verify the chore exists in the API with the selected days ─────────
|
||||
const token = await page.evaluate(() => localStorage.getItem('token'))
|
||||
const apiRes = await fetch(`${API_URL}/api/v1/chores/`, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
})
|
||||
expect(apiRes.ok).toBe(true)
|
||||
|
||||
const { res: chores } = await apiRes.json()
|
||||
const created = chores.find(c => c.name === choreName)
|
||||
expect(created).toBeDefined()
|
||||
expect(created.frequencyType).toBe('days_of_the_week')
|
||||
expect([...(created.frequencyMetadata?.days || [])].sort()).toEqual([
|
||||
'monday',
|
||||
'wednesday',
|
||||
])
|
||||
})
|
||||
|
||||
test('creates a chore, edits it after reload, and toggles Anyone assignment', async ({
|
||||
page,
|
||||
}) => {
|
||||
const originalName = `E2E Edit Chore ${Date.now()}`
|
||||
const updatedName = `${originalName} Updated`
|
||||
const updatedDescription = `Updated by e2e ${Date.now()}`
|
||||
// One week out, formatted as YYYY-MM-DD for the native date input
|
||||
const updatedDueDate = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000)
|
||||
.toISOString()
|
||||
.slice(0, 10)
|
||||
|
||||
// ── Create a simple one-off chore with a due date ───────────────────────
|
||||
await page.goto('/chores/create')
|
||||
await page.locator('input').first().fill(originalName)
|
||||
|
||||
// Toggle "Anyone" on then off again — confirm it snaps back to the
|
||||
// default self-assignment before we submit.
|
||||
await page.getByLabel('Anyone').click()
|
||||
await expect(page.getByLabel('Anyone')).toBeChecked()
|
||||
await page.getByLabel('Anyone').click()
|
||||
await expect(page.getByLabel('Anyone')).not.toBeChecked()
|
||||
|
||||
// Give it a due date so it's a simple one-off chore
|
||||
await page.getByLabel('Give this task a due date').click()
|
||||
|
||||
await page.getByRole('button', { name: 'Create' }).click()
|
||||
await page.waitForURL('**/chores', { timeout: 15_000 })
|
||||
await expect(page.getByText(originalName)).toBeVisible({ timeout: 10_000 })
|
||||
|
||||
// ── Look up the created chore via the API (id + self-assignment state) ─
|
||||
const token = await page.evaluate(() => localStorage.getItem('token'))
|
||||
const listRes = await fetch(`${API_URL}/api/v1/chores/`, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
})
|
||||
expect(listRes.ok).toBe(true)
|
||||
const { res: chores } = await listRes.json()
|
||||
const created = chores.find(c => c.name === originalName)
|
||||
expect(created).toBeDefined()
|
||||
// Default self-assignment: exactly one assignee, matching assignedTo.
|
||||
expect(created.assignees?.length).toBe(1)
|
||||
expect(created.assignedTo).toBe(created.assignees[0].userId)
|
||||
|
||||
// ── Edit: change name, description, due date, and switch to Anyone ─────
|
||||
await page.goto(`/chores/${created.id}/edit`)
|
||||
|
||||
await page.locator('input').first().fill(updatedName)
|
||||
await page.locator('.ql-editor').fill(updatedDescription)
|
||||
await page.locator('input[type="date"]').fill(updatedDueDate)
|
||||
await page.getByLabel('Anyone').click()
|
||||
|
||||
await page.getByRole('button', { name: 'Save' }).click()
|
||||
await page.waitForURL('**/chores', { timeout: 15_000 })
|
||||
|
||||
// ── Reload the edit page and confirm the new values persisted in the UI
|
||||
await page.goto(`/chores/${created.id}/edit`)
|
||||
await expect(page.locator('input').first()).toHaveValue(updatedName)
|
||||
await expect(page.locator('.ql-editor')).toContainText(updatedDescription)
|
||||
await expect(page.locator('input[type="date"]')).toHaveValue(updatedDueDate)
|
||||
await expect(page.getByLabel('Anyone')).toBeChecked()
|
||||
|
||||
// ── Confirm persisted via the API too ───────────────────────────────────
|
||||
const detailRes = await fetch(`${API_URL}/api/v1/chores/${created.id}`, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
})
|
||||
expect(detailRes.ok).toBe(true)
|
||||
const { res: updated } = await detailRes.json()
|
||||
expect(updated.name).toBe(updatedName)
|
||||
expect(updated.description).toContain(updatedDescription)
|
||||
// Due-date persistence is already confirmed via the reloaded date input
|
||||
// above; comparing the raw UTC `nextDueDate` string here would be
|
||||
// timezone-fragile since the app stores it as an end-of-local-day UTC
|
||||
// instant.
|
||||
// "Anyone" assignment: no specific assignees, no fixed assignedTo.
|
||||
expect(updated.assignees ?? []).toHaveLength(0)
|
||||
expect(updated.assignedTo).toBeFalsy()
|
||||
})
|
||||
})
|
||||
53
e2e/tests/chores.spec.js
Normal file
53
e2e/tests/chores.spec.js
Normal file
@@ -0,0 +1,53 @@
|
||||
import { expect, test } from '../fixtures/auth.js'
|
||||
import { API_URL } from '../global-setup.js'
|
||||
|
||||
test.describe('Chores – Create', () => {
|
||||
// All tests in this suite run as the pre-authenticated E2E user
|
||||
test.use({
|
||||
storageState: '.auth/state.json',
|
||||
})
|
||||
|
||||
test('creates a daily recurring chore and confirms it appears in the list', async ({
|
||||
page,
|
||||
}) => {
|
||||
const choreName = `E2E Daily Chore ${Date.now()}`
|
||||
|
||||
// ── Navigate to the create chore page ────────────────────────────────
|
||||
await page.goto('/chores/create')
|
||||
|
||||
// ── Fill in the chore name ────────────────────────────────────────────
|
||||
// Name input is the first <input> on the page (no id/placeholder)
|
||||
await page.locator('input').first().fill(choreName)
|
||||
|
||||
// ── Enable recurrence ─────────────────────────────────────────────────
|
||||
// Check the "Repeat this task" checkbox to reveal frequency options
|
||||
await page.getByLabel('Repeat this task').click()
|
||||
|
||||
// Select "Daily" from the frequency chips
|
||||
await page.getByLabel('Daily').click()
|
||||
|
||||
// The due date is auto-populated to today once a repeating type is selected.
|
||||
// No manual date entry required unless testing date-specific behaviour.
|
||||
|
||||
// ── Save ──────────────────────────────────────────────────────────────
|
||||
await page.getByRole('button', { name: 'Create' }).click()
|
||||
|
||||
// After save the app navigates back to the chore list
|
||||
await page.waitForURL('**/chores', { timeout: 15_000 })
|
||||
|
||||
// ── Verify the chore appears in the UI ───────────────────────────────
|
||||
await expect(page.getByText(choreName)).toBeVisible({ timeout: 10_000 })
|
||||
|
||||
// ── Verify the chore exists in the API ───────────────────────────────
|
||||
const token = await page.evaluate(() => localStorage.getItem('token'))
|
||||
const apiRes = await fetch(`${API_URL}/api/v1/chores/`, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
})
|
||||
expect(apiRes.ok).toBe(true)
|
||||
|
||||
const { res: chores } = await apiRes.json()
|
||||
const created = chores.find(c => c.name === choreName)
|
||||
expect(created).toBeDefined()
|
||||
expect(created.frequencyType).toBe('daily')
|
||||
})
|
||||
})
|
||||
164
e2e/tests/projects-filters.spec.js
Normal file
164
e2e/tests/projects-filters.spec.js
Normal file
@@ -0,0 +1,164 @@
|
||||
import { expect, test } from '../fixtures/auth.js'
|
||||
import { API_URL } from '../global-setup.js'
|
||||
|
||||
test.describe('Projects & Filters – Create and navigate', () => {
|
||||
// All tests in this suite run as the pre-authenticated E2E user
|
||||
test.use({
|
||||
storageState: '.auth/state.json',
|
||||
})
|
||||
|
||||
test('creates a project via the modal, tracks its task count, and filters chores by it', async ({
|
||||
page,
|
||||
}) => {
|
||||
const projectName = `E2E Project ${Date.now()}`
|
||||
const choreName = `E2E Project Chore ${Date.now()}`
|
||||
|
||||
// ── Create the project via the modal ─────────────────────────────────
|
||||
await page.goto('/projects')
|
||||
await page.getByTestId('open-add-project-modal').click()
|
||||
|
||||
const projectDialog = page.getByRole('dialog')
|
||||
await projectDialog.getByLabel('Project Name').fill(projectName)
|
||||
await projectDialog.getByRole('button', { name: 'Create' }).click()
|
||||
|
||||
// ── Verify the project appears in the list with a 0 task count ───────
|
||||
// Scope to the row: the name Typography's parent Box also holds the
|
||||
// "N tasks" chip as a sibling, so one level up covers both.
|
||||
const projectRow = page
|
||||
.getByText(projectName, { exact: true })
|
||||
.locator('xpath=..')
|
||||
await expect(projectRow.getByText('0 tasks')).toBeVisible({
|
||||
timeout: 10_000,
|
||||
})
|
||||
|
||||
// ── Look up the created project via the API to get its id ────────────
|
||||
const token = await page.evaluate(() => localStorage.getItem('token'))
|
||||
const projectsRes = await fetch(`${API_URL}/api/v1/projects`, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
})
|
||||
expect(projectsRes.ok).toBe(true)
|
||||
const projects = await projectsRes.json()
|
||||
const project = projects.find(p => p.name === projectName)
|
||||
expect(project).toBeDefined()
|
||||
|
||||
// ── Create a chore inside the project directly via the API ───────────
|
||||
// Cheaper than driving the full chore-create UI, and this project is
|
||||
// brand new so its task count is guaranteed to go from 0 to 1.
|
||||
const choreRes = await fetch(`${API_URL}/api/v1/chores/`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
name: choreName,
|
||||
frequencyType: 'once',
|
||||
assignStrategy: 'no_assignee',
|
||||
projectId: project.id,
|
||||
}),
|
||||
})
|
||||
expect(choreRes.ok).toBe(true)
|
||||
|
||||
// ── Reload so the project list reflects the new task count ───────────
|
||||
await page.reload()
|
||||
await expect(projectRow.getByText('1 tasks')).toBeVisible({
|
||||
timeout: 10_000,
|
||||
})
|
||||
|
||||
// ── Click the project card and confirm navigation + filtered results ─
|
||||
await page.getByText(projectName, { exact: true }).click()
|
||||
await page.waitForURL(new RegExp(`/chores\\?project=${project.id}(&|$)`), {
|
||||
timeout: 10_000,
|
||||
})
|
||||
await expect(page.getByText(choreName)).toBeVisible({ timeout: 10_000 })
|
||||
})
|
||||
|
||||
test('creates a filter via AdvancedFilterBuilder, tracks its task count, and filters chores by it', async ({
|
||||
page,
|
||||
}) => {
|
||||
const filterProjectName = `E2E Filter Project ${Date.now()}`
|
||||
const filterName = `E2E Filter ${Date.now()}`
|
||||
const choreName = `E2E Filter Chore ${Date.now()}`
|
||||
|
||||
// ── Seed a throwaway project via the API to use as the filter's ──────
|
||||
// condition target. A brand-new project has zero chores, so the
|
||||
// filter's task count is guaranteed to start at 0 regardless of
|
||||
// whatever else has accumulated in the shared test database.
|
||||
await page.goto('/filters')
|
||||
const token = await page.evaluate(() => localStorage.getItem('token'))
|
||||
const createProjectRes = await fetch(`${API_URL}/api/v1/projects`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
body: JSON.stringify({ name: filterProjectName }),
|
||||
})
|
||||
expect(createProjectRes.ok).toBe(true)
|
||||
const { res: filterProject } = await createProjectRes.json()
|
||||
|
||||
// Reload so the modal's project list (fetched on page load) includes it
|
||||
await page.reload()
|
||||
|
||||
// ── Create the filter via AdvancedFilterBuilder ───────────────────────
|
||||
await page.getByTestId('open-add-filter-modal').click()
|
||||
|
||||
const filterDialog = page.getByRole('dialog')
|
||||
await filterDialog
|
||||
.getByPlaceholder('e.g. Overdue tasks for Alice')
|
||||
.fill(filterName)
|
||||
// Condition: Projects is <the seeded project> — one condition is enough
|
||||
await filterDialog
|
||||
.getByRole('button', { name: filterProjectName, exact: true })
|
||||
.click()
|
||||
await filterDialog.getByRole('button', { name: 'Save Filter' }).click()
|
||||
|
||||
// ── Verify the filter appears in the list with a 0 task count ────────
|
||||
// The name Typography sits inside a name-row Box, itself inside the
|
||||
// content Box that also holds the "N tasks" chip — two levels up.
|
||||
const filterRow = page
|
||||
.getByText(filterName, { exact: true })
|
||||
.locator('xpath=../..')
|
||||
await expect(filterRow.getByText('0 tasks')).toBeVisible({
|
||||
timeout: 10_000,
|
||||
})
|
||||
|
||||
// ── Look up the created filter via the API to get its id ─────────────
|
||||
const filtersRes = await fetch(`${API_URL}/api/v1/filters`, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
})
|
||||
expect(filtersRes.ok).toBe(true)
|
||||
const filters = await filtersRes.json()
|
||||
const filter = filters.find(f => f.name === filterName)
|
||||
expect(filter).toBeDefined()
|
||||
|
||||
// ── Create a chore matching the filter's project condition ───────────
|
||||
const choreRes = await fetch(`${API_URL}/api/v1/chores/`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
name: choreName,
|
||||
frequencyType: 'once',
|
||||
assignStrategy: 'no_assignee',
|
||||
projectId: filterProject.id,
|
||||
}),
|
||||
})
|
||||
expect(choreRes.ok).toBe(true)
|
||||
|
||||
// ── Reload so the filter list reflects the new task count ────────────
|
||||
await page.reload()
|
||||
await expect(filterRow.getByText('1 tasks')).toBeVisible({
|
||||
timeout: 10_000,
|
||||
})
|
||||
|
||||
// ── Click the filter card and confirm navigation + filtered results ──
|
||||
await page.getByText(filterName, { exact: true }).click()
|
||||
await page.waitForURL(new RegExp(`/chores\\?filterId=${filter.id}(&|$)`), {
|
||||
timeout: 10_000,
|
||||
})
|
||||
await expect(page.getByText(choreName)).toBeVisible({ timeout: 10_000 })
|
||||
})
|
||||
})
|
||||
@@ -15,7 +15,17 @@ import globals from 'globals'
|
||||
|
||||
export default [
|
||||
{
|
||||
ignores: ['dist'],
|
||||
ignores: [
|
||||
'dist',
|
||||
'build',
|
||||
'vendor',
|
||||
'android',
|
||||
'ios',
|
||||
'resources',
|
||||
'public/assets',
|
||||
'.agents',
|
||||
'.impeccable',
|
||||
],
|
||||
},
|
||||
js.configs.recommended,
|
||||
react.configs.flat.recommended,
|
||||
@@ -51,11 +61,24 @@ export default [
|
||||
eslintConfigPrettier, // Disable any rules that conflict with prettier
|
||||
eslintPluginPrettierRecommended,
|
||||
{
|
||||
files: ['*.{js,ts}'],
|
||||
files: [
|
||||
'*.{js,mjs,cjs,ts}',
|
||||
'scripts/**/*.{js,mjs,cjs,ts}',
|
||||
'workers/**/*.{js,mjs,cjs,ts}',
|
||||
],
|
||||
languageOptions: {
|
||||
globals: globals.node,
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['e2e/**/*.{js,mjs}'],
|
||||
languageOptions: {
|
||||
globals: {
|
||||
...globals.node,
|
||||
...globals.browser,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['*.config.{mjs,ts}'],
|
||||
languageOptions: {
|
||||
@@ -63,9 +86,9 @@ export default [
|
||||
sourceType: 'module',
|
||||
},
|
||||
rules: {
|
||||
// Formatting rules (indent, space-infix-ops) are owned by prettier here —
|
||||
// re-enabling them fights prettier/prettier and makes --fix unable to converge.
|
||||
eqeqeq: 'error',
|
||||
indent: ['error', 2],
|
||||
'space-infix-ops': ['error', { int32Hint: false }],
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -31,8 +31,7 @@ Build a signed, App Store-ready .ipa
|
||||
|
||||
Upload the built .ipa to TestFlight
|
||||
|
||||
----
|
||||
|
||||
---
|
||||
|
||||
## Android
|
||||
|
||||
@@ -60,7 +59,7 @@ Build a signed release .apk (for sideloading/testing)
|
||||
|
||||
Upload the built .aab to the Play Store (internal testing track by default)
|
||||
|
||||
----
|
||||
---
|
||||
|
||||
This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run.
|
||||
|
||||
|
||||
22
index.html
22
index.html
@@ -16,6 +16,28 @@
|
||||
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5" />
|
||||
<meta name="msapplication-TileColor" content="#da532c" />
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
<!--
|
||||
Plausible. This index.html is shared by the app and the marketing bundles
|
||||
(see src/main.jsx), so the tag is gated rather than hardcoded: it loads
|
||||
only when the page host matches VITE_APP_PLAUSIBLE_DOMAIN, which is the
|
||||
site registered in Plausible. On app.donetick.com the host never matches,
|
||||
so nothing loads. Unset the variable to disable it entirely.
|
||||
-->
|
||||
<script>
|
||||
;(function () {
|
||||
var domain = 'donetick.com'
|
||||
// Vite leaves the literal placeholder when the variable is unset.
|
||||
var host = window.location.hostname
|
||||
if (host !== domain) return
|
||||
var s = document.createElement('script')
|
||||
s.defer = true
|
||||
// s.setAttribute('data-domain', domain)
|
||||
s.setAttribute('data-domain', 'donetick.com')
|
||||
s.src = 'https://collector.wannaknow.link/js/script.js'
|
||||
document.head.appendChild(s)
|
||||
})()
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
@@ -4,4 +4,4 @@
|
||||
"capacitor": {}
|
||||
},
|
||||
"type": "custom"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -462,12 +462,12 @@
|
||||
CODE_SIGN_ALLOW_ENTITLEMENTS_MODIFICATION = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = App/App.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 57;
|
||||
CURRENT_PROJECT_VERSION = 70;
|
||||
DEVELOPMENT_TEAM = 6UJJ78R3BS;
|
||||
INFOPLIST_FILE = App/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
MARKETING_VERSION = 1.2.36;
|
||||
MARKETING_VERSION = 1.2.49;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.donetick.app;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
@@ -485,12 +485,12 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
PROVISIONING_PROFILE_SPECIFIER = "Donetick App Store(fastline)";
|
||||
CURRENT_PROJECT_VERSION = 57;
|
||||
CURRENT_PROJECT_VERSION = 70;
|
||||
DEVELOPMENT_TEAM = 6UJJ78R3BS;
|
||||
INFOPLIST_FILE = App/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
MARKETING_VERSION = 1.2.36;
|
||||
MARKETING_VERSION = 1.2.49;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.donetick.app;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "";
|
||||
@@ -504,12 +504,12 @@
|
||||
buildSettings = {
|
||||
CODE_SIGN_ENTITLEMENTS = DonetickWidget/DonetickWidget.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 57;
|
||||
CURRENT_PROJECT_VERSION = 70;
|
||||
DEVELOPMENT_TEAM = 6UJJ78R3BS;
|
||||
INFOPLIST_FILE = DonetickWidget/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
||||
MARKETING_VERSION = 1.2.36;
|
||||
MARKETING_VERSION = 1.2.49;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.donetick.app.widget;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
@@ -527,12 +527,12 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
PROVISIONING_PROFILE_SPECIFIER = "Donetick Widget App Store(fastline)";
|
||||
CURRENT_PROJECT_VERSION = 57;
|
||||
CURRENT_PROJECT_VERSION = 70;
|
||||
DEVELOPMENT_TEAM = 6UJJ78R3BS;
|
||||
INFOPLIST_FILE = DonetickWidget/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
||||
MARKETING_VERSION = 1.2.36;
|
||||
MARKETING_VERSION = 1.2.49;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.donetick.app.widget;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
|
||||
@@ -4,6 +4,10 @@
|
||||
<dict>
|
||||
<key>aps-environment</key>
|
||||
<string>development</string>
|
||||
<key>com.apple.developer.associated-domains</key>
|
||||
<array>
|
||||
<string>applinks:app.donetick.com</string>
|
||||
</array>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>group.com.donetick.app</string>
|
||||
|
||||
@@ -11,4 +11,4 @@
|
||||
"author": "xcode",
|
||||
"version": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
"info": {
|
||||
"version": 1,
|
||||
"author": "xcode"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,4 +53,4 @@
|
||||
"version": 1,
|
||||
"author": "xcode"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ def capacitor_pods
|
||||
pod 'CapacitorNetwork', :path => '../../node_modules/@capacitor/network'
|
||||
pod 'CapacitorPreferences', :path => '../../node_modules/@capacitor/preferences'
|
||||
pod 'CapacitorPushNotifications', :path => '../../node_modules/@capacitor/push-notifications'
|
||||
pod 'CapacitorShare', :path => '../../node_modules/@capacitor/share'
|
||||
pod 'CapacitorStatusBar', :path => '../../node_modules/@capacitor/status-bar'
|
||||
pod 'CapgoCapacitorDocumentScanner', :path => '../../node_modules/@capgo/capacitor-document-scanner'
|
||||
pod 'CapgoCapacitorNfc', :path => '../../node_modules/@capgo/capacitor-nfc'
|
||||
|
||||
@@ -43,6 +43,8 @@ PODS:
|
||||
- Capacitor
|
||||
- CapacitorPushNotifications (8.1.2):
|
||||
- Capacitor
|
||||
- CapacitorShare (8.0.1):
|
||||
- Capacitor
|
||||
- CapacitorStatusBar (8.0.3):
|
||||
- Capacitor
|
||||
- CapgoCapacitorDocumentScanner (8.4.2):
|
||||
@@ -157,6 +159,7 @@ DEPENDENCIES:
|
||||
- CapacitorPluginSafeArea (from `../../node_modules/capacitor-plugin-safe-area`)
|
||||
- "CapacitorPreferences (from `../../node_modules/@capacitor/preferences`)"
|
||||
- "CapacitorPushNotifications (from `../../node_modules/@capacitor/push-notifications`)"
|
||||
- "CapacitorShare (from `../../node_modules/@capacitor/share`)"
|
||||
- "CapacitorStatusBar (from `../../node_modules/@capacitor/status-bar`)"
|
||||
- "CapgoCapacitorDocumentScanner (from `../../node_modules/@capgo/capacitor-document-scanner`)"
|
||||
- "CapgoCapacitorNfc (from `../../node_modules/@capgo/capacitor-nfc`)"
|
||||
@@ -222,6 +225,8 @@ EXTERNAL SOURCES:
|
||||
:path: "../../node_modules/@capacitor/preferences"
|
||||
CapacitorPushNotifications:
|
||||
:path: "../../node_modules/@capacitor/push-notifications"
|
||||
CapacitorShare:
|
||||
:path: "../../node_modules/@capacitor/share"
|
||||
CapacitorStatusBar:
|
||||
:path: "../../node_modules/@capacitor/status-bar"
|
||||
CapgoCapacitorDocumentScanner:
|
||||
@@ -256,6 +261,7 @@ SPEC CHECKSUMS:
|
||||
CapacitorPluginSafeArea: 874619c00586248f1694210e72038123d422c2d9
|
||||
CapacitorPreferences: cca2021f386efb75947c850334447d9ff22b14f1
|
||||
CapacitorPushNotifications: 32a7f840815f319fd9ba1c1c9b0b914be9d95237
|
||||
CapacitorShare: 0c58305114538568059bfc07111f22dcb9cb2a82
|
||||
CapacitorStatusBar: eca7bc2b58d9f886f1ef9edb66e57a9b29c121af
|
||||
CapgoCapacitorDocumentScanner: 262bb84b73707f9e2e59071ca58013e3f9acf942
|
||||
CapgoCapacitorNfc: 8ea158143c441e1cf6d231a971e375511558d027
|
||||
@@ -283,6 +289,6 @@ SPEC CHECKSUMS:
|
||||
SQLCipher: eb79c64049cb002b4e9fcb30edb7979bf4706dfc
|
||||
ZIPFoundation: dfd3d681c4053ff7e2f7350bc4e53b5dba3f5351
|
||||
|
||||
PODFILE CHECKSUM: 028fdeb50d56158db0a97459bd577ed700f03c0c
|
||||
PODFILE CHECKSUM: 0170e6b548e03117ef7d6814596b8b140a6acce4
|
||||
|
||||
COCOAPODS: 1.16.2
|
||||
|
||||
801
package-lock.json
generated
801
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
16
package.json
16
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "donetick",
|
||||
"private": true,
|
||||
"version": "1.2.36",
|
||||
"version": "1.2.49",
|
||||
"type": "module",
|
||||
"engines": {
|
||||
"node": ">=20.0.0",
|
||||
@@ -20,8 +20,9 @@
|
||||
"build-cf": "rm -rf package-lock.json && npm install && npm install --force @rollup/rollup-linux-x64-gnu@4.34.9 @swc/core-linux-x64-gnu && vite build",
|
||||
"build-selfhosted": "rm -rf package-lock.json && npm install && npm install --force @rollup/rollup-linux-x64-gnu@4.34.9 @swc/core-linux-x64-gnu && vite build --mode selfhosted",
|
||||
"build-win": "del package-lock.json && npm install && npm install --force @rollup/rollup-win32-x64-msvc @swc/core-win32-x64-msvc && vite build --mode selfhosted",
|
||||
"lint": "eslint && prettier -c .",
|
||||
"lint:ci": "true # TODO: eslint -f gha && prettier -c .",
|
||||
"lint": "eslint && prettier -c . && npm run lint:i18n",
|
||||
"lint:i18n": "node scripts/i18n-audit.mjs",
|
||||
"lint:ci": "eslint -f gha && prettier -c . && npm run lint:i18n",
|
||||
"lint:fix": "eslint --fix && prettier -w .",
|
||||
"preview": "vite preview",
|
||||
"setup-m1": "rm -rf node_modules package-lock.json && npm install && npm install --force @rollup/rollup-darwin-arm64 @swc/core-darwin-arm64",
|
||||
@@ -56,6 +57,7 @@
|
||||
"@capacitor/network": "^8.0.0",
|
||||
"@capacitor/preferences": "^8.0.0",
|
||||
"@capacitor/push-notifications": "^8.0.0",
|
||||
"@capacitor/share": "^8.0.1",
|
||||
"@capacitor/status-bar": "^8.0.0",
|
||||
"@capgo/capacitor-document-scanner": "^8.4.0",
|
||||
"@capgo/capacitor-nfc": "^8.0.0",
|
||||
@@ -63,15 +65,17 @@
|
||||
"@dnd-kit/core": "^6.3.1",
|
||||
"@dnd-kit/sortable": "^10.0.0",
|
||||
"@dnd-kit/utilities": "^3.2.2",
|
||||
"@emotion/cache": "^11.14.0",
|
||||
"@emotion/react": "^11.11.3",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
"@hello-pangea/dnd": "^18.0.1",
|
||||
"@jcesarmobile/capacitor-ocr": "^0.3.0",
|
||||
"@meauxt/react-swipeable-list": "^1.0.0",
|
||||
"@mui/icons-material": "^5.16.13",
|
||||
"@mui/joy": "^5.0.0-beta.20",
|
||||
"@mui/joy": "5.0.0-beta.52",
|
||||
"@mui/material": "^5.15.2",
|
||||
"@openreplay/tracker": "^14.0.4",
|
||||
"@posthog/rollup-plugin": "^1.4.9",
|
||||
"@revenuecat/purchases-capacitor": "^12.0.0",
|
||||
"@revenuecat/purchases-capacitor-ui": "^12.0.0",
|
||||
"@stylistic/eslint-plugin": "^5.10.0",
|
||||
@@ -94,6 +98,7 @@
|
||||
"js-cookie": "^3.0.5",
|
||||
"moment": "^2.30.1",
|
||||
"murmurhash": "^2.0.1",
|
||||
"posthog-js": "^1.415.5",
|
||||
"prop-types": "^15.8.1",
|
||||
"qrcode": "^1.5.4",
|
||||
"quill": "^2.0.3",
|
||||
@@ -108,6 +113,8 @@
|
||||
"reactjs-social-login": "^2.6.3",
|
||||
"recharts": "^2.15.0",
|
||||
"reusify": "^1.0.4",
|
||||
"stylis": "^4.4.0",
|
||||
"stylis-plugin-rtl": "^2.1.1",
|
||||
"tesseract.js": "^7.0.0",
|
||||
"vite-plugin-pwa": "^0.20.0"
|
||||
},
|
||||
@@ -133,6 +140,7 @@
|
||||
"eslint-plugin-sort-destructure-keys": "^3.0.0",
|
||||
"eslint-plugin-tailwindcss": "^3.18.3",
|
||||
"husky": "^8.0.3",
|
||||
"lint-staged": "^16.4.0",
|
||||
"patch-package": "^8.0.1",
|
||||
"postcss": "^8.4.32",
|
||||
"prettier": "^3.8.3",
|
||||
|
||||
11
public/.well-known/apple-app-site-association
Normal file
11
public/.well-known/apple-app-site-association
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"applinks": {
|
||||
"apps": [],
|
||||
"details": [
|
||||
{
|
||||
"appID": "6UJJ78R3BS.com.donetick.app",
|
||||
"paths": ["/circle/join*"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
11
public/.well-known/apple-app-site-association.json
Normal file
11
public/.well-known/apple-app-site-association.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"applinks": {
|
||||
"apps": [],
|
||||
"details": [
|
||||
{
|
||||
"appID": "6UJJ78R3BS.com.donetick.app",
|
||||
"paths": ["/circle/join*"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
13
public/.well-known/assetlinks.json
Normal file
13
public/.well-known/assetlinks.json
Normal file
@@ -0,0 +1,13 @@
|
||||
[
|
||||
{
|
||||
"relation": ["delegate_permission/common.handle_all_urls"],
|
||||
"target": {
|
||||
"namespace": "android_app",
|
||||
"package_name": "com.donetick.app",
|
||||
"sha256_cert_fingerprints": [
|
||||
"EF:45:27:40:A2:D2:11:E4:27:AB:9A:7A:C6:E1:3B:CA:D4:DE:6A:0A:C3:81:05:58:D8:89:F1:FA:4E:CB:44:F3",
|
||||
"67:0B:E5:30:FB:8A:7F:E6:9A:54:51:7F:06:AA:B0:1D:1A:26:61:5B:2A:60:53:4A:31:75:72:DA:F6:FA:EC:5A"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
8
public/_headers
Normal file
8
public/_headers
Normal file
@@ -0,0 +1,8 @@
|
||||
/.well-known/apple-app-site-association
|
||||
Content-Type: application/json
|
||||
|
||||
/.well-known/apple-app-site-association.json
|
||||
Content-Type: application/json
|
||||
|
||||
/.well-known/assetlinks.json
|
||||
Content-Type: application/json
|
||||
1
public/_redirects
Normal file
1
public/_redirects
Normal file
@@ -0,0 +1 @@
|
||||
/.well-known/apple-app-site-association /.well-known/apple-app-site-association.json 200
|
||||
@@ -20,6 +20,7 @@
|
||||
"logout": "تسجيل الخروج",
|
||||
"version": "النسخة",
|
||||
"navigation": {
|
||||
"search": "بحث",
|
||||
"allTasks": "جميع المهام",
|
||||
"archived": "المؤرشفة",
|
||||
"things": "الأشياء",
|
||||
@@ -29,5 +30,47 @@
|
||||
"activities": "الأنشطة",
|
||||
"points": "النقاط",
|
||||
"settings": "الإعدادات"
|
||||
},
|
||||
"search": {
|
||||
"title": "بحث",
|
||||
"placeholder": "ابحث في Donetick",
|
||||
"inputAriaLabel": "ابحث في المهام والسجل والمشاريع والتسميات والإعدادات",
|
||||
"deviceNote": "يتم البحث في المحتوى المتوفر على هذا الجهاز",
|
||||
"escape": "Esc",
|
||||
"recent": "الأخيرة",
|
||||
"empty": {
|
||||
"title": "لا توجد نتائج مطابقة",
|
||||
"subtitle": "لا يزال بإمكانك تصفية قائمة المهام باستخدام هذا البحث."
|
||||
},
|
||||
"groups": {
|
||||
"tasks": "المهام",
|
||||
"history": "الملاحظات",
|
||||
"projects": "المشاريع",
|
||||
"labels": "التسميات",
|
||||
"people": "الأشخاص",
|
||||
"settings": "الإعدادات",
|
||||
"actions": "إجراءات سريعة"
|
||||
},
|
||||
"actions": {
|
||||
"quickAction": "إجراء سريع",
|
||||
"navigation": "التنقل",
|
||||
"createTask": "إنشاء مهمة",
|
||||
"viewAllTasks": "عرض جميع المهام",
|
||||
"viewArchivedTasks": "عرض المهام المؤرشفة",
|
||||
"openSettings": "فتح الإعدادات",
|
||||
"filterTasks": "عرض المهام المطابقة لـ «{{query}}»",
|
||||
"filterTasksSubtitle": "تصفية قائمة المهام"
|
||||
},
|
||||
"footer": {
|
||||
"navigate": "تنقل",
|
||||
"open": "فتح",
|
||||
"results_zero": "لا توجد نتائج",
|
||||
"results_one": "نتيجة واحدة",
|
||||
"results_two": "نتيجتان",
|
||||
"results_few": "{{count}} نتائج",
|
||||
"results_many": "{{count}} نتيجة",
|
||||
"results_other": "{{count}} نتيجة",
|
||||
"typeToSearch": "اكتب للبحث"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,116 +1,29 @@
|
||||
{
|
||||
"title": "الإعدادات",
|
||||
"circleSettings": {
|
||||
"title": "إعدادات الدائرة",
|
||||
"description": "يتم ربط حسابك تلقائيًا بدائرة عند إنشاء واحدة أو الانضمام إليها. ادعُ الأصدقاء بسهولة من خلال مشاركة رمز الدائرة الفريد أو الرابط أدناه. ستتلقى إشعارًا أدناه عندما يطلب شخص ما الانضمام إلى دائرتك. إذا كنت ترغب في المغادرة، فما عليك سوى الضغط على زر 'مغادرة الدائرة'.",
|
||||
"circleCode": "رمز الدائرة",
|
||||
"copyCode": "نسخ الرمز",
|
||||
"copyLink": "نسخ الرابط",
|
||||
"codeCopied": "تم نسخ رمز الدائرة!",
|
||||
"linkCopied": "تم نسخ الرابط!",
|
||||
"joinCircle": "الانضمام إلى دائرة",
|
||||
"joinCirclePlaceholder": "أدخل رمز الدائرة",
|
||||
"join": "انضمام",
|
||||
"leave": "مغادرة الدائرة",
|
||||
"leaveConfirmTitle": "مغادرة الدائرة",
|
||||
"leaveConfirmMessage": "هل أنت متأكد من أنك تريد مغادرة هذه الدائرة؟",
|
||||
"circleMembers": "أعضاء الدائرة",
|
||||
"circleMemberRequests": "طلبات انضمام الأعضاء",
|
||||
"admin": "مشرف",
|
||||
"member": "عضو",
|
||||
"pending": "قيد الانتظار",
|
||||
"accept": "قبول",
|
||||
"reject": "رفض",
|
||||
"makeAdmin": "جعله مشرف",
|
||||
"makeMember": "جعله عضو",
|
||||
"remove": "إزالة",
|
||||
"webhookURL": "رابط Webhook",
|
||||
"webhookDescription": "أدخل رابط webhook لتلقي إشعارات أحداث الدائرة",
|
||||
"webhookPlaceholder": "https://your-webhook-url.com"
|
||||
},
|
||||
"accountSettings": {
|
||||
"title": "إعدادات الحساب",
|
||||
"subscription": "الاشتراك",
|
||||
"subscriptionStatus": "الخطة الحالية",
|
||||
"free": "مجاني",
|
||||
"plus": "بلس",
|
||||
"upgrade": "ترقية",
|
||||
"cancel": "إلغاء",
|
||||
"changePassword": "تغيير كلمة المرور",
|
||||
"password": "كلمة المرور",
|
||||
"dangerZone": "منطقة الخطر",
|
||||
"dangerZoneDescription": "بمجرد حذف حسابك، لا يمكن التراجع. يرجى التأكد.",
|
||||
"deleteAccount": "حذف الحساب"
|
||||
},
|
||||
"localization": {
|
||||
"title": "التوطين",
|
||||
"description": "تخصيص اللغة وتنسيق التاريخ والتفضيلات الإقليمية لحسابك.",
|
||||
"language": "اللغة",
|
||||
"languageDescription": "اختر لغتك المفضلة",
|
||||
"dateFormat": "تنسيق التاريخ",
|
||||
"dateFormatDescription": "اختر كيفية عرض التواريخ في التطبيق",
|
||||
"timeFormat": "تنسيق الوقت",
|
||||
"timeFormatDescription": "اختر تنسيق 12 أو 24 ساعة",
|
||||
"12hour": "12 ساعة (ص/م)",
|
||||
"24hour": "24 ساعة",
|
||||
"firstDayOfWeek": "أول يوم في الأسبوع",
|
||||
"firstDayOfWeekDescription": "اختر اليوم الذي يبدأ به أسبوعك",
|
||||
"sunday": "الأحد",
|
||||
"monday": "الاثنين",
|
||||
"saturday": "السبت",
|
||||
"formats": {
|
||||
"mdy": "MM/DD/YYYY (الولايات المتحدة)",
|
||||
"dmy": "DD/MM/YYYY (أوروبا)",
|
||||
"ymd": "YYYY-MM-DD (ISO)",
|
||||
"long": "تنسيق طويل (مثل 1 يناير 2024)",
|
||||
"short": "تنسيق قصير (مثل 1 يناير 2024)"
|
||||
}
|
||||
},
|
||||
"sidepanel": {
|
||||
"title": "تخصيص اللوحة الجانبية",
|
||||
"description": "قم بتخصيص تخطيط ورؤية البطاقات في اللوحة الجانبية. هذا القسم متاح فقط على أجهزة الشاشة الكبيرة مثل الأجهزة اللوحية وأجهزة سطح المكتب."
|
||||
},
|
||||
"theme": {
|
||||
"title": "تفضيلات المظهر",
|
||||
"description": "اختر كيف يبدو الموقع لك. حدد مظهرًا واحدًا أو قم بالمزامنة مع نظامك والتبديل تلقائيًا بين مظاهر النهار والليل.",
|
||||
"themeMode": "وضع المظهر",
|
||||
"light": "فاتح",
|
||||
"dark": "داكن",
|
||||
"system": "النظام"
|
||||
},
|
||||
"notifications": {
|
||||
"settingsSaved": "تم حفظ الإعدادات بنجاح",
|
||||
"settingsSaveFailed": "فشل حفظ الإعدادات",
|
||||
"invalidWebhook": "رابط webhook غير صالح"
|
||||
},
|
||||
"profile": {
|
||||
"title": "إعدادات الملف الشخصي",
|
||||
"description": "تحديث اسم العرض وصورة الملف الشخصي.",
|
||||
"photoUpdated": "تم تحديث الصورة",
|
||||
"photoUpdatedMessage": "تم تحديث صورة ملفك الشخصي بنجاح!",
|
||||
"uploadFailed": "فشل التحميل",
|
||||
"uploadFailedMessage": "فشل تحميل صورتك. يرجى المحاولة مرة أخرى.",
|
||||
"profileUpdated": "تم تحديث الملف الشخصي",
|
||||
"profileUpdatedMessage": "تم حفظ معلومات ملفك الشخصي بنجاح!",
|
||||
"updateFailed": "فشل التحديث",
|
||||
"updateFailedMessage": "تعذر تحديث ملفك الشخصي. يرجى التحقق من اتصالك والمحاولة مرة أخرى.",
|
||||
"changePhoto": "تغيير الصورة",
|
||||
"displayName": "اسم العرض",
|
||||
"displayNamePlaceholder": "أدخل اسم العرض الخاص بك",
|
||||
"timezone": "المنطقة الزمنية",
|
||||
"timezonePlaceholder": "اختر منطقتك الزمنية",
|
||||
"common": {
|
||||
"save": "حفظ",
|
||||
"cancel": "إلغاء"
|
||||
"cancel": "إلغاء",
|
||||
"confirm": "تأكيد",
|
||||
"remove": "إزالة",
|
||||
"delete": "حذف",
|
||||
"refresh": "تحديث",
|
||||
"loading": "جارٍ التحميل…",
|
||||
"on": "مفعّل",
|
||||
"off": "متوقف",
|
||||
"error": "خطأ",
|
||||
"success": "تم بنجاح",
|
||||
"plusFeature": "ميزة Plus",
|
||||
"earlyAccess": "وصول مبكر"
|
||||
},
|
||||
"overview": {
|
||||
"title": "الإعدادات",
|
||||
"subtitle": "قم بتخصيص تجربتك وإدارة تفضيلات حسابك",
|
||||
"subtitle": "خصّص تجربتك وأدر تفضيلات حسابك",
|
||||
"upgrade": {
|
||||
"title": "الترقية إلى بلس",
|
||||
"description": "افتح ميزات قوية لتعزيز إنتاجيتك",
|
||||
"button": "الترقية الآن",
|
||||
"title": "الترقية إلى Plus",
|
||||
"description": "افتح ميزات قوية تزيد من إنتاجيتك",
|
||||
"button": "ترقية الآن",
|
||||
"features": {
|
||||
"richText": "أوصاف نصية منسقة",
|
||||
"richText": "أوصاف بنص منسّق",
|
||||
"notifications": "إشعارات المهام",
|
||||
"apiIntegrations": "تكاملات API",
|
||||
"advancedAutomation": "أتمتة متقدمة"
|
||||
@@ -119,56 +32,463 @@
|
||||
"sections": {
|
||||
"profile": {
|
||||
"title": "إعدادات الملف الشخصي",
|
||||
"description": "تحديث معلومات ملفك الشخصي والصورة واسم العرض وتفضيلات المنطقة الزمنية."
|
||||
"description": "حدّث معلومات ملفك الشخصي وصورتك واسم العرض والمنطقة الزمنية."
|
||||
},
|
||||
"circle": {
|
||||
"title": "إعدادات الدائرة",
|
||||
"description": "إدارة دائرتك ودعوة الأعضاء والتعامل مع طلبات الانضمام."
|
||||
"description": "أدر دائرتك، وادعُ الأعضاء، وتعامل مع طلبات الانضمام."
|
||||
},
|
||||
"account": {
|
||||
"title": "إعدادات الحساب",
|
||||
"description": "إدارة اشتراكك وتغيير كلمة المرور وخيارات حذف الحساب."
|
||||
"description": "أدر اشتراكك، وغيّر كلمة المرور، واحذف حسابك."
|
||||
},
|
||||
"subaccounts": {
|
||||
"title": "الحسابات المُدارة",
|
||||
"description": "إنشاء وإدارة حسابات فرعية لتسجيل الدخول وإكمال المهام المعينة."
|
||||
"description": "أنشئ وأدر حسابات فرعية يمكنها تسجيل الدخول وإنجاز المهام المسندة إليها."
|
||||
},
|
||||
"notifications": {
|
||||
"title": "الإشعارات",
|
||||
"description": "تكوين الإشعارات الفورية وتنبيهات البريد الإلكتروني ووجهات الإشعارات للمهام."
|
||||
"description": "اضبط الإشعارات الفورية وتنبيهات البريد ووجهات إشعارات المهام."
|
||||
},
|
||||
"mfa": {
|
||||
"title": "المصادقة متعددة العوامل",
|
||||
"description": "إضافة طبقة إضافية من الأمان باستخدام MFA مع تطبيقات المصادقة."
|
||||
"description": "أضف طبقة حماية إضافية عبر المصادقة متعددة العوامل باستخدام تطبيقات المصادقة."
|
||||
},
|
||||
"apitokens": {
|
||||
"title": "رموز API",
|
||||
"description": "إنشاء وإدارة رموز الوصول لتكاملات الطرف الثالث والوصول إلى API."
|
||||
"description": "أنشئ وأدر رموز الوصول للتكاملات الخارجية والوصول إلى API."
|
||||
},
|
||||
"storage": {
|
||||
"title": "إعدادات التخزين",
|
||||
"description": "نسخ احتياطي واستعادة بياناتك وإدارة التخزين المحلي وتفضيلات المزامنة."
|
||||
"description": "انسخ بياناتك احتياطيًا واستعدها، وأدر التخزين المحلي وتفضيلات المزامنة."
|
||||
},
|
||||
"sidepanel": {
|
||||
"title": "تخصيص اللوحة الجانبية",
|
||||
"description": "قم بتخصيص تخطيط ورؤية البطاقات في واجهة اللوحة الجانبية."
|
||||
"description": "خصّص ترتيب البطاقات وظهورها في اللوحة الجانبية."
|
||||
},
|
||||
"theme": {
|
||||
"title": "تفضيلات المظهر",
|
||||
"description": "اختر مظهرك المفضل وقم بتكوين إعدادات الوضع الداكن/الفاتح."
|
||||
"description": "اختر المظهر المفضل لديك واضبط الوضع الفاتح/الداكن."
|
||||
},
|
||||
"localization": {
|
||||
"title": "التوطين",
|
||||
"description": "تخصيص اللغة وتنسيق التاريخ وتنسيق الوقت والتفضيلات الإقليمية."
|
||||
"title": "الإعدادات المحلية",
|
||||
"description": "خصّص اللغة وتنسيق التاريخ والوقت والتفضيلات الإقليمية."
|
||||
},
|
||||
"advanced": {
|
||||
"title": "الإعدادات المتقدمة",
|
||||
"description": "تكوين webhooks والتحديثات في الوقت الفعلي وميزات متقدمة أخرى لتعزيز الإنتاجية."
|
||||
"description": "اضبط الـ Webhooks والتحديثات الفورية وغيرها من الميزات المتقدمة."
|
||||
},
|
||||
"developer": {
|
||||
"title": "إعدادات المطور",
|
||||
"description": "عرض المعلومات الفنية حول رموز المصادقة واتصالات SSE وبيانات التصحيح."
|
||||
"title": "إعدادات المطوّر",
|
||||
"description": "اعرض معلومات تقنية عن رموز المصادقة واتصالات SSE وبيانات التصحيح."
|
||||
},
|
||||
"feedback": {
|
||||
"title": "إرسال ملاحظات",
|
||||
"description": "أخبرنا كيف يعمل Donetick معك أو اطلب ميزة جديدة."
|
||||
},
|
||||
"bugReport": {
|
||||
"title": "الإبلاغ عن خلل",
|
||||
"description": "هناك شيء لا يعمل كما ينبغي؟ أرسل لنا التفاصيل مع لقطة تقنية."
|
||||
}
|
||||
}
|
||||
},
|
||||
"profile": {
|
||||
"title": "إعدادات الملف الشخصي",
|
||||
"description": "حدّث اسم العرض وصورة ملفك الشخصي.",
|
||||
"photoUpdated": "تم تحديث الصورة",
|
||||
"photoUpdatedMessage": "تم تحديث صورة ملفك الشخصي بنجاح!",
|
||||
"uploadFailed": "فشل الرفع",
|
||||
"uploadFailedMessage": "تعذّر رفع صورتك. يرجى المحاولة مرة أخرى.",
|
||||
"profileUpdated": "تم تحديث الملف الشخصي",
|
||||
"profileUpdatedMessage": "تم حفظ معلومات ملفك الشخصي بنجاح!",
|
||||
"updateFailed": "فشل التحديث",
|
||||
"updateFailedMessage": "تعذّر تحديث ملفك الشخصي. تحقق من اتصالك وحاول مرة أخرى.",
|
||||
"changePhoto": "تغيير الصورة",
|
||||
"editPhoto": "تحرير صورة الملف الشخصي",
|
||||
"displayName": "اسم العرض",
|
||||
"displayNamePlaceholder": "أدخل اسم العرض",
|
||||
"timezone": "المنطقة الزمنية",
|
||||
"timezonePlaceholder": "اختر منطقتك الزمنية",
|
||||
"save": "حفظ",
|
||||
"cancel": "إلغاء"
|
||||
},
|
||||
"circleSettings": {
|
||||
"title": "إعدادات الدائرة",
|
||||
"description": "يرتبط حسابك تلقائيًا بدائرة عند إنشائها أو الانضمام إليها. ادعُ أصدقاءك بسهولة عبر مشاركة رمز الدائرة أو الرابط أدناه. وسيصلك إشعار هنا عندما يطلب أحدهم الانضمام إلى دائرتك.",
|
||||
"memberOf": "أنت جزء من {{name}}",
|
||||
"yourCircleCode": "رمز دائرتك هو:",
|
||||
"copyCode": "نسخ الرمز",
|
||||
"shareInvite": "مشاركة الدعوة",
|
||||
"codeCopied": "تم نسخ الرمز إلى الحافظة",
|
||||
"linkCopied": "تم نسخ رابط الدعوة إلى الحافظة",
|
||||
"myCircle": "دائرتي",
|
||||
"shareTitle": "انضم إلى {{name}} على Donetick",
|
||||
"shareText": "أودّ دعوتك للانضمام إلى {{name}} على Donetick.",
|
||||
"shareDialogTitle": "مشاركة دعوة الدائرة",
|
||||
"leave": "مغادرة الدائرة",
|
||||
"leaveConfirmTitle": "مغادرة الدائرة",
|
||||
"leaveConfirmMessage": "هل تريد بالتأكيد مغادرة دائرتك؟",
|
||||
"leaveConfirmButton": "مغادرة",
|
||||
"leftCircle": "تمت مغادرة الدائرة بنجاح",
|
||||
"leaveFailed": "تعذّرت مغادرة الدائرة",
|
||||
"circleMembers": "أعضاء الدائرة",
|
||||
"you": "(أنت)",
|
||||
"pendingApproval": "بانتظار الموافقة",
|
||||
"joinedOn": "انضم في {{date}}",
|
||||
"requestedToJoin": "طلب الانضمام {{date}}",
|
||||
"roles": {
|
||||
"member": "عضو",
|
||||
"memberDescription": "عضو عادي في الدائرة",
|
||||
"manager": "مدير",
|
||||
"managerDescription": "يمكنه انتحال هوية المستخدمين وتنفيذ إجراءات نيابةً عنهم",
|
||||
"admin": "مسؤول",
|
||||
"adminDescription": "صلاحية كاملة على الدائرة"
|
||||
},
|
||||
"roleUpdateFailed": "تعذّر تحديث الدور",
|
||||
"removeMemberTitle": "إزالة عضو",
|
||||
"removeMemberMessage": "هل تريد بالتأكيد إزالة {{name}} من دائرتك؟",
|
||||
"memberRemoved": "تمت إزالة العضو بنجاح",
|
||||
"circleMemberRequests": "طلبات الانضمام إلى الدائرة",
|
||||
"lastUpdated": "آخر تحديث: {{time}}",
|
||||
"refreshing": "جارٍ التحديث…",
|
||||
"refreshFailed": "تعذّر تحديث طلبات الانضمام",
|
||||
"wantsToJoin": "يريد {{name}} الانضمام إلى دائرتك.",
|
||||
"accept": "قبول",
|
||||
"acceptRequestTitle": "قبول طلب الانضمام",
|
||||
"acceptRequestMessage": "هل تريد بالتأكيد قبول {{name}} (اسم المستخدم: {{username}}) للانضمام إلى دائرتك؟",
|
||||
"requestAccepted": "تم قبول الطلب بنجاح",
|
||||
"or": "أو",
|
||||
"joinOtherDescription": "تريد الانضمام إلى دائرة شخص آخر؟ اطلب منه رمز الدائرة أو رابط الانضمام، ثم أدخل الرمز أدناه للانضمام.",
|
||||
"enterCircleCode": "أدخل رمز الدائرة:",
|
||||
"enterCodePlaceholder": "أدخل الرمز",
|
||||
"joinCircle": "الانضمام إلى الدائرة",
|
||||
"joinedPending": "تم الانضمام إلى الدائرة بنجاح، انتظر موافقة مالك الدائرة على طلبك.",
|
||||
"alreadyMember": "أنت عضو في هذه الدائرة بالفعل",
|
||||
"joinFailed": "تعذّر الانضمام إلى الدائرة"
|
||||
},
|
||||
"accountSettings": {
|
||||
"title": "إعدادات الحساب",
|
||||
"description": "غيّر إعدادات حسابك أو نوع خطتك أو كلمة المرور",
|
||||
"accountType": "نوع الحساب: {{type}}",
|
||||
"free": "مجاني",
|
||||
"plus": "Plus",
|
||||
"plusUntil": "Plus (حتى {{date}})",
|
||||
"activeDescription": "أنت مشترك حاليًا في خطة Plus. سيتجدد اشتراكك في {{date}}.",
|
||||
"cancelledDescription": "لقد ألغيت اشتراكك. سيتم خفض حسابك إلى الخطة المجانية في {{date}}.",
|
||||
"freeDescription": "أنت حاليًا على الخطة المجانية. رقِّ إلى Plus لفتح المزيد من الميزات.",
|
||||
"upgrade": "ترقية",
|
||||
"cancel": "إلغاء الاشتراك",
|
||||
"password": "كلمة المرور:",
|
||||
"changePassword": "تغيير كلمة المرور",
|
||||
"passwordChanged": "تم تغيير كلمة المرور بنجاح",
|
||||
"passwordChangeFailed": "فشل تغيير كلمة المرور",
|
||||
"dangerZone": "منطقة الخطر",
|
||||
"dangerZoneDescription": "بمجرد حذف حسابك لا يمكن التراجع. يرجى التأكد قبل المتابعة.",
|
||||
"deleteAccount": "حذف الحساب",
|
||||
"accountDeleted": "تم حذف الحساب بنجاح",
|
||||
"subscriptionCancelled": "تم إلغاء الاشتراك",
|
||||
"subscriptionCancelFailed": "تعذّر إلغاء الاشتراك",
|
||||
"purchase": {
|
||||
"success": "تمت عملية الشراء بنجاح! أعد تشغيل التطبيق للوصول إلى ميزات Plus.",
|
||||
"storeConnection": "هناك مشكلة في الاتصال بالمتجر. تحقق من شبكتك وحاول مرة أخرى.",
|
||||
"notAllowed": "عمليات الشراء غير مسموح بها على هذا الجهاز. يرجى مراجعة قيود جهازك.",
|
||||
"unavailable": "هذا الاشتراك غير متاح. يرجى المحاولة لاحقًا.",
|
||||
"alreadyProcessed": "تمت معالجة هذه العملية من قبل. إذا كنت ترى أن هذا خطأ، تواصل مع الدعم.",
|
||||
"receiptMissing": "إيصال الشراء مفقود. يرجى إعادة محاولة الشراء.",
|
||||
"networkError": "خطأ في الشبكة. تحقق من اتصالك وحاول مرة أخرى.",
|
||||
"invalidReceipt": "إيصال الشراء غير صالح. تواصل مع الدعم إذا استمرت المشكلة.",
|
||||
"pending": "الدفعة بانتظار الموافقة. ستحصل على الوصول فور اعتمادها.",
|
||||
"failed": "فشلت عملية الشراء: {{error}}. حاول مرة أخرى أو تواصل مع الدعم.",
|
||||
"unknownError": "خطأ غير معروف"
|
||||
}
|
||||
},
|
||||
"subaccounts": {
|
||||
"title": "الحسابات المُدارة",
|
||||
"description": "أدر الحسابات الفرعية. يمكن لمستخدمي الحسابات الفرعية تسجيل الدخول وإنجاز المهام المسندة إليهم.",
|
||||
"notParentTitle": "إدارة الحسابات الفرعية",
|
||||
"notParentMessage": "الحسابات الرئيسية فقط هي التي يمكنها إدارة الحسابات الفرعية.",
|
||||
"freePlanNotice": "الخطة المجانية تتيح حسابًا فرعيًا واحدًا. رقِّ إلى Plus للحصول على ما يصل إلى 5 حسابات فرعية.",
|
||||
"count": "الحسابات الفرعية ({{count}})",
|
||||
"add": "إضافة حساب فرعي",
|
||||
"loading": "جارٍ تحميل الحسابات الفرعية…",
|
||||
"emptyTitle": "لا توجد حسابات فرعية",
|
||||
"emptyDescription": "أنشئ حسابات فرعية ليتمكن أعضاء الفريق من تسجيل الدخول وإنجاز المهام المسندة إليهم.",
|
||||
"addFirst": "أضف أول حساب فرعي",
|
||||
"username": "اسم المستخدم: {{username}}",
|
||||
"created": "أُنشئ في: {{date}}",
|
||||
"changePassword": "تغيير كلمة المرور",
|
||||
"deleteAccount": "حذف الحساب",
|
||||
"createdSuccess": "تم إنشاء الحساب الفرعي «{{name}}» بنجاح!",
|
||||
"createFailed": "تعذّر إنشاء الحساب الفرعي: {{error}}",
|
||||
"createFailedGeneric": "تعذّر إنشاء الحساب الفرعي",
|
||||
"passwordUpdated": "تم تحديث كلمة مرور الحساب الفرعي بنجاح",
|
||||
"passwordUpdateFailed": "تعذّر تحديث كلمة المرور: {{error}}",
|
||||
"passwordUpdateFailedGeneric": "تعذّر تحديث كلمة المرور",
|
||||
"deleteConfirmTitle": "حذف الحساب الفرعي",
|
||||
"deleteConfirmMessage": "هل تريد بالتأكيد حذف الحساب الفرعي «{{name}}»؟ لا يمكن التراجع عن هذا الإجراء.",
|
||||
"deleted": "تم حذف الحساب الفرعي «{{name}}» بنجاح",
|
||||
"deleteFailed": "تعذّر حذف الحساب الفرعي: {{error}}",
|
||||
"deleteFailedGeneric": "تعذّر حذف الحساب الفرعي",
|
||||
"howItWorksTitle": "كيف تعمل الحسابات المُدارة",
|
||||
"howItWorks1": "تُنشئ الحسابات المُدارة من الحساب الرئيسي، وهي مخصّصة لمن تريد أن تكون لديك إمكانية حذف حسابه وإعادة تعيين كلمة مروره.",
|
||||
"howItWorks2": "يمكن للحسابات الفرعية تسجيل الدخول باسم مستخدم وكلمة مرور خاصين بها.",
|
||||
"howItWorks3": "يمكن للحسابات المُدارة إنجاز المهام لكن صلاحياتها الإدارية محدودة",
|
||||
"howItWorks4": "تُضاف الحسابات المُدارة تلقائيًا إلى دائرتك"
|
||||
},
|
||||
"notifications": {
|
||||
"title": "إعدادات الإشعارات",
|
||||
"deviceSection": "إشعارات الجهاز",
|
||||
"deviceSectionDescription": "أدر إشعارات جهازك",
|
||||
"deviceLabel": "إشعار الجهاز",
|
||||
"deviceHelper": "تلقَّ إشعارًا على جهازك عند استحقاق مهمة",
|
||||
"mobileOnly": "هذه الميزة متاحة على الأجهزة المحمولة فقط",
|
||||
"testNotification": "إشعار تجريبي",
|
||||
"testNotificationBody": "لديك مهمة تستحق قريبًا",
|
||||
"dueTitle": "إشعار الاستحقاق",
|
||||
"dueLabel": "إشعار عند استحقاق المهمة",
|
||||
"preDueTitle": "إشعار قبل الاستحقاق",
|
||||
"preDueLabel": "إشعار قبل ساعات من استحقاق المهمة",
|
||||
"overdueTitle": "إشعار التأخر",
|
||||
"overdueLabel": "إشعار عند تأخر المهمة عن موعدها",
|
||||
"pushLabel": "الإشعارات الفورية",
|
||||
"pushHelper": "تلقَّ التذكيرات والإعلانات وإسنادات المهام عبر الإشعارات الفورية",
|
||||
"registeredDevices": "الأجهزة المسجّلة ({{count}}/5)",
|
||||
"registeredDevicesDescription": "الأجهزة المسجّلة لتلقّي الإشعارات الفورية الخاصة بحسابك",
|
||||
"currentDevice": "الجهاز الحالي: {{platform}} {{model}}",
|
||||
"currentDeviceNotRegistered": "هذا الجهاز غير مسجّل لتلقّي الإشعارات الفورية",
|
||||
"limitReached": "بلغت الحد الأقصى",
|
||||
"registerDevice": "تسجيل الجهاز",
|
||||
"unknownDevice": "جهاز غير معروف",
|
||||
"deviceCreatedAt": "أُنشئ في: {{date}}",
|
||||
"noDevices": "لا توجد أجهزة مسجّلة لتلقّي الإشعارات الفورية",
|
||||
"customSection": "إشعار مخصّص",
|
||||
"customSectionDescription": "الإشعار عبر منصة أخرى مثل Telegram أو Pushover",
|
||||
"customLabel": "إشعار مخصّص",
|
||||
"customHelper": "تلقَّ الإشعارات على منصة أخرى",
|
||||
"targetNone": "بدون",
|
||||
"targetTelegram": "Telegram",
|
||||
"targetPushover": "Pushover",
|
||||
"targetWebhooks": "Webhooks",
|
||||
"telegramBotHelpBefore": "عليك إرسال رسالة إلى البوت أولًا حتى تعمل إشعارات Telegram",
|
||||
"telegramBotHelpAfter": "لبدء محادثة",
|
||||
"clickHere": "اضغط هنا",
|
||||
"chatId": "معرّف المحادثة",
|
||||
"chatIdPlaceholder": "معرّف المستخدم / معرّف المحادثة",
|
||||
"telegramChatIdHelpBefore": "إذا كنت لا تعرف معرّف محادثتك، ابدأ محادثة مع userinfobot وسيرسله إليك.",
|
||||
"telegramChatIdHelpAfter": "لبدء محادثة مع userinfobot",
|
||||
"userKey": "مفتاح المستخدم",
|
||||
"userKeyPlaceholder": "معرّف المستخدم",
|
||||
"chatIdRequired": "معرّف المحادثة مطلوب",
|
||||
"chatIdInvalid": "معرّف المحادثة غير صالح",
|
||||
"userKeyRequired": "مفتاح المستخدم مطلوب",
|
||||
"targetUpdated": "تم تحديث وجهة الإشعارات",
|
||||
"targetUpdateFailed": "حدث خطأ أثناء تحديث وجهة الإشعارات: {{error}}",
|
||||
"deviceRegistered": "تم تسجيل الجهاز بنجاح لتلقّي الإشعارات الفورية.",
|
||||
"deviceLimitTitle": "بلغت الحد الأقصى للأجهزة",
|
||||
"deviceLimitMessage": "لقد بلغت الحد الأقصى وهو 5 أجهزة مسجّلة. يرجى إزالة جهاز قبل تسجيل هذا الجهاز.",
|
||||
"registrationFailedTitle": "فشل التسجيل",
|
||||
"registrationFailedMessage": "تعذّر تسجيل الجهاز تلقائيًا. يرجى المحاولة مرة أخرى.",
|
||||
"permissionRequiredTitle": "الإذن مطلوب",
|
||||
"permissionRequiredMessage": "يلزم إذن الإشعارات الفورية لتسجيل هذا الجهاز.",
|
||||
"registrationInitiatedTitle": "بدأ التسجيل",
|
||||
"registrationInitiatedMessage": "بدأ تسجيل الإشعارات الفورية. سيُسجَّل الجهاز تلقائيًا.",
|
||||
"registerDeviceFailed": "تعذّر تسجيل الجهاز. يرجى المحاولة مرة أخرى.",
|
||||
"permissionDeniedTitle": "تم رفض إذن الإشعارات",
|
||||
"permissionDeniedMessage": "لقد رفضت أذونات الإشعارات. يمكنك تفعيلها لاحقًا من إعدادات جهازك.",
|
||||
"pushPermissionDeniedTitle": "تم رفض إذن الإشعارات الفورية",
|
||||
"pushPermissionDeniedMessage": "تم تعطيل الإشعارات الفورية. يمكنك تفعيلها من إعدادات جهازك عند الحاجة.",
|
||||
"unregisterFailed": "تعذّر إلغاء تسجيل الجهاز"
|
||||
},
|
||||
"mfa": {
|
||||
"title": "المصادقة متعددة العوامل",
|
||||
"description": "أضف طبقة حماية إضافية لحسابك عبر المصادقة متعددة العوامل (MFA). عند تفعيلها، ستحتاج إلى إدخال رمز تحقق من تطبيق المصادقة إلى جانب كلمة المرور عند تسجيل الدخول.",
|
||||
"twoFactor": "المصادقة الثنائية",
|
||||
"enabledSubtitle": "حسابك محمي بالمصادقة الثنائية",
|
||||
"disabledSubtitle": "أمّن حسابك باستخدام تطبيق مصادقة",
|
||||
"enable": "تفعيل",
|
||||
"disable": "تعطيل",
|
||||
"enabledSuccess": "تم تفعيل المصادقة متعددة العوامل بنجاح!",
|
||||
"disabledSuccess": "تم تعطيل المصادقة متعددة العوامل بنجاح!",
|
||||
"errors": {
|
||||
"qrGenerationFailed": "تعذّر إنشاء رمز QR",
|
||||
"invalidResponse": "استجابة غير صالحة من الخادم. رمز QR أو المفتاح السري مفقود.",
|
||||
"notFound": "لم يُعثر على نقطة إعداد المصادقة متعددة العوامل. قد لا تكون هذه الميزة متاحة بعد.",
|
||||
"unauthorized": "غير مصرّح. يرجى تسجيل الدخول مرة أخرى.",
|
||||
"serverError": "خطأ في الخادم. يرجى المحاولة لاحقًا.",
|
||||
"setupFailed": "تعذّر إعداد المصادقة متعددة العوامل ({{status}}). يرجى المحاولة مرة أخرى.",
|
||||
"networkError": "خطأ في الشبكة. تحقق من اتصالك وحاول مرة أخرى.",
|
||||
"invalidCode": "رمز التحقق غير صالح. يرجى المحاولة مرة أخرى.",
|
||||
"confirmFailed": "تعذّر تأكيد المصادقة متعددة العوامل. يرجى المحاولة مرة أخرى.",
|
||||
"disableFailed": "تعذّر تعطيل المصادقة متعددة العوامل. يرجى المحاولة مرة أخرى."
|
||||
},
|
||||
"setup": {
|
||||
"title": "إعداد المصادقة متعددة العوامل",
|
||||
"addedAccount": "لقد أضفت الحساب",
|
||||
"back": "رجوع",
|
||||
"verifyAndEnable": "التحقق والتفعيل",
|
||||
"savedBackupCodes": "لقد حفظت رموز النسخ الاحتياطي",
|
||||
"step1Label": "الخطوة 1:",
|
||||
"step1": "امسح رمز QR أدناه باستخدام تطبيق المصادقة (Google Authenticator أو Authy أو غيرهما)",
|
||||
"qrAlt": "رمز QR للمصادقة متعددة العوامل",
|
||||
"qrFailed": "تعذّر إنشاء رمز QR. حاول مرة أخرى أو استخدم مفتاح الإدخال اليدوي أدناه.",
|
||||
"manualKey": "مفتاح الإدخال اليدوي:",
|
||||
"step2Label": "الخطوة 2:",
|
||||
"step2": "أدخل رمز التحقق المكوّن من 6 أرقام من تطبيق المصادقة",
|
||||
"codePlaceholder": "أدخل الرمز المكوّن من 6 أرقام",
|
||||
"successTitle": "تم تفعيل المصادقة متعددة العوامل بنجاح!",
|
||||
"backupCodesTitle": "احفظ رموز النسخ الاحتياطي هذه في مكان آمن",
|
||||
"backupCodesDescription": "يمكنك استخدام هذه الرموز للوصول إلى حسابك في حال فقدت جهاز المصادقة. يمكن استخدام كل رمز مرة واحدة فقط."
|
||||
},
|
||||
"disableModal": {
|
||||
"title": "تعطيل المصادقة متعددة العوامل",
|
||||
"warning": "تعطيل المصادقة متعددة العوامل يجعل حسابك أقل أمانًا. هل تريد بالتأكيد المتابعة؟",
|
||||
"prompt": "أدخل رمز تحقق من تطبيق المصادقة للتأكيد:",
|
||||
"confirm": "تعطيل المصادقة متعددة العوامل"
|
||||
},
|
||||
"backupCodesModal": {
|
||||
"title": "رموز نسخ احتياطي جديدة",
|
||||
"warning": "لم تعد رموز النسخ الاحتياطي السابقة صالحة. احفظ هذه الرموز الجديدة في مكان آمن. يمكن استخدام كل رمز مرة واحدة فقط."
|
||||
}
|
||||
},
|
||||
"apiTokens": {
|
||||
"title": "رموز API",
|
||||
"accessToken": "رمز الوصول",
|
||||
"description": "أنشئ رمزًا لاستخدامه مع API لتحديث الأشياء التي تُطلق المهام",
|
||||
"plusNotice": "رموز API غير متاحة في الخطة الأساسية. رقِّ إلى Plus لإنشاء رموز API للتكامل مع الأنظمة الخارجية وأتمتة مهامك.",
|
||||
"showToken": "إظهار الرمز",
|
||||
"hideToken": "إخفاء الرمز",
|
||||
"removeTitle": "إزالة الرمز",
|
||||
"removeMessage": "هل تريد بالتأكيد إزالة {{name}}؟",
|
||||
"removedTitle": "تمت الإزالة",
|
||||
"removedMessage": "تمت إزالة رمز API",
|
||||
"tokenCopied": "تم نسخ الرمز إلى الحافظة",
|
||||
"generateNew": "إنشاء رمز جديد",
|
||||
"nameModalTitle": "امنح رمزك الجديد اسمًا يساعدك على تذكّره.",
|
||||
"generateToken": "إنشاء الرمز"
|
||||
},
|
||||
"storage": {
|
||||
"title": "إعدادات التخزين",
|
||||
"serverTitle": "استخدام تخزين الخادم",
|
||||
"serverDescription": "هذه هي المساحة التي يستخدمها حسابك على خوادمنا (مثل الملفات والصور والبيانات التي رفعتها).",
|
||||
"usagePlaceholder": "-- ميغابايت مستخدمة / -- ميغابايت إجمالًا (--)",
|
||||
"usage": "{{used}} ميغابايت مستخدمة / {{total}} ميغابايت إجمالًا ({{percent}}%)",
|
||||
"basicPlanNotice": "تخزين الخادم غير متاح في الخطة الأساسية. رقِّ إلى Plus لتتبّع استخدامك لتخزين الخادم.",
|
||||
"localTitleApp": "التخزين المحلي والذاكرة المؤقتة للتطبيق",
|
||||
"localTitleBrowser": "التخزين المحلي والذاكرة المؤقتة للمتصفح",
|
||||
"localDescription": "هذه بيانات محفوظة محليًا في متصفحك لتسريع الوصول. مسحها لن يؤثر على بياناتك على الخادم، لكنه قد يسجّل خروجك.",
|
||||
"clearLocal": "مسح كل التخزين المحلي والذاكرة المؤقتة",
|
||||
"clearLocalTitle": "مسح كل التخزين المحلي",
|
||||
"clearLocalMessage": "هل تريد بالتأكيد مسح التخزين المحلي والذاكرة المؤقتة؟ سيؤدي ذلك إلى إزالة جميع بياناتك من هذا المتصفح وسيتطلب تسجيل الدخول من جديد.",
|
||||
"clearAll": "مسح الكل",
|
||||
"appPreferences": "تفضيلات التطبيق",
|
||||
"deviceOnly": "على الجهاز فقط",
|
||||
"appPreferencesDescription": "هذه تفضيلات وإعدادات يحفظها التطبيق محليًا على جهازك. مسحها سيعيد ضبط إعدادات التطبيق وقد يسجّل خروجك، لكنه لن يؤثر على بياناتك على الخادم.",
|
||||
"clearPreferences": "مسح تفضيلات التطبيق",
|
||||
"clearPreferencesTitle": "مسح تفضيلات التطبيق",
|
||||
"clearPreferencesMessage": "هل تريد بالتأكيد مسح جميع تفضيلات التطبيق؟ سيؤدي ذلك إلى إعادة ضبط إعداداتك وقد يتطلب تسجيل الدخول من جديد."
|
||||
},
|
||||
"sidepanel": {
|
||||
"title": "تخصيص اللوحة الجانبية",
|
||||
"heading": "إعدادات اللوحة الجانبية",
|
||||
"description": "حدّد البطاقات التي تظهر في اللوحة الجانبية وترتيبها. اسحب وأفلت لإعادة الترتيب، أو بدّل ظهور كل بطاقة.",
|
||||
"resetToDefaults": "استعادة الإعدادات الافتراضية",
|
||||
"resetHelper": "سيؤدي ذلك إلى استعادة الظهور والترتيب الافتراضيين لجميع البطاقات.",
|
||||
"cards": {
|
||||
"welcome": {
|
||||
"name": "تبديل المستخدم",
|
||||
"description": "يتيح للمسؤولين والمديرين عرض المهام بصفة مستخدمين آخرين"
|
||||
},
|
||||
"smartInsights": {
|
||||
"name": "رؤى ذكية",
|
||||
"description": "إجراءات سريعة بناءً على مهامك"
|
||||
},
|
||||
"assignees": {
|
||||
"name": "المهام حسب المكلَّف",
|
||||
"description": "يجمع المهام حسب الشخص المكلَّف بها"
|
||||
},
|
||||
"calendar": {
|
||||
"name": "عرض التقويم",
|
||||
"description": "يعرض المهام بتنسيق تقويم"
|
||||
},
|
||||
"activities": {
|
||||
"name": "الأنشطة الأخيرة",
|
||||
"description": "يعرض المهام المنجزة والأنشطة الأخيرة"
|
||||
},
|
||||
"weeklyGoals": {
|
||||
"name": "الأهداف الأسبوعية",
|
||||
"description": "يعرض التقدّم الأسبوعي وإحصاءات إنجاز العائلة"
|
||||
}
|
||||
}
|
||||
},
|
||||
"theme": {
|
||||
"title": "تفضيلات المظهر",
|
||||
"description": "اختر الشكل الذي يظهر به الموقع لك. حدّد مظهرًا ثابتًا أو زامنه مع نظامك للتبديل تلقائيًا بين المظهر النهاري والليلي.",
|
||||
"themeMode": "وضع المظهر",
|
||||
"light": "فاتح",
|
||||
"dark": "داكن",
|
||||
"system": "النظام"
|
||||
},
|
||||
"localization": {
|
||||
"title": "الإعدادات المحلية",
|
||||
"description": "خصّص اللغة وتنسيق التاريخ والتفضيلات الإقليمية لحسابك.",
|
||||
"language": "اللغة",
|
||||
"languageDescription": "اختر لغتك المفضلة",
|
||||
"rtlNotice": "تُكتب هذه اللغة من اليمين إلى اليسار (RTL)",
|
||||
"dateFormat": "تنسيق التاريخ",
|
||||
"dateFormatDescription": "اختر طريقة عرض التواريخ في جميع أنحاء التطبيق",
|
||||
"timeFormat": "تنسيق الوقت",
|
||||
"timeFormatDescription": "اختر نظام 12 ساعة أو 24 ساعة",
|
||||
"preview": "معاينة: {{value}}",
|
||||
"12hour": "12 ساعة (ص/م)",
|
||||
"24hour": "24 ساعة",
|
||||
"firstDayOfWeek": "أول أيام الأسبوع",
|
||||
"firstDayOfWeekDescription": "اختر اليوم الذي يبدأ به أسبوعك",
|
||||
"sunday": "الأحد",
|
||||
"monday": "الاثنين",
|
||||
"saturday": "السبت",
|
||||
"formats": {
|
||||
"mdy": "MM/DD/YYYY (الولايات المتحدة)",
|
||||
"dmy": "DD/MM/YYYY (أوروبا)",
|
||||
"ymd": "YYYY-MM-DD (ISO)",
|
||||
"long": "تنسيق طويل (مثال: 1 يناير 2024)",
|
||||
"short": "تنسيق قصير (مثال: 1 ينا 2024)"
|
||||
}
|
||||
},
|
||||
"advanced": {
|
||||
"title": "الإعدادات المتقدمة",
|
||||
"description": "اضبط الميزات المتقدمة مثل الـ Webhooks والتحديثات الفورية لتعزيز إنتاجيتك.",
|
||||
"offlineTitle": "دعم العمل دون اتصال",
|
||||
"offlineDescription": "واصل استخدام Donetick دون اتصال على هذا الجهاز/المتصفح. تُحفظ تغييراتك محليًا وتُزامن عند عودتك للاتصال.",
|
||||
"offlineToggle": "تفعيل دعم العمل دون اتصال",
|
||||
"offlineHelper": "إيقاف هذا الخيار يزيل التغييرات غير المزامنة والبيانات المحفوظة دون اتصال من هذا الجهاز/المتصفح.",
|
||||
"offlineEnabled": "تم تفعيل وضع العمل دون اتصال على هذا الجهاز/المتصفح",
|
||||
"offlineDisabled": "تم إيقاف وضع العمل دون اتصال ومسح البيانات المحلية",
|
||||
"offlineDisabledPartial": "تم إيقاف وضع العمل دون اتصال، لكن قد تبقى بعض البيانات المحلية مخزّنة",
|
||||
"offlineDisableTitle": "إيقاف وضع العمل دون اتصال",
|
||||
"offlineDisableMessage": "إيقاف وضع العمل دون اتصال سيزيل التغييرات غير المزامنة والبيانات المحفوظة دون اتصال على هذا الجهاز/المتصفح. هل تريد المتابعة؟",
|
||||
"offlineDisableConfirm": "الإيقاف ومسح البيانات",
|
||||
"webhookTitle": "تكامل Webhook",
|
||||
"webhookDescription": "تتيح لك الـ Webhooks إرسال إشعارات فورية إلى خدمات أخرى عند وقوع أحداث في دائرتك. اضبط رابط Webhook لتلقّي التحديثات الفورية.",
|
||||
"webhookPlusNotice": "إشعارات Webhook غير متاحة في الخطة الأساسية. رقِّ إلى Plus لتلقّي التحديثات الفورية عبر الـ Webhooks.",
|
||||
"webhookToggle": "تفعيل Webhook",
|
||||
"webhookHelper": "فعّل إشعارات Webhook لتحديثات المهام والأشياء.",
|
||||
"webhookURL": "رابط Webhook",
|
||||
"webhookUpdated": "تم تحديث رابط Webhook بنجاح",
|
||||
"webhookUpdateFailed": "تعذّر تحديث رابط Webhook",
|
||||
"realtimeTitle": "التحديثات الفورية",
|
||||
"realtimeDescription": "اضبط كيفية تلقّي التحديثات المباشرة عند تغيّر المهام والأنشطة في دائرتك.",
|
||||
"realtime": {
|
||||
"toggleLabel": "تفعيل التحديثات الفورية",
|
||||
"title": "التحديثات الفورية",
|
||||
"subtitle": "تلقَّ إشعارات فورية عند تحديث المهام",
|
||||
"statusLabel": "الحالة:",
|
||||
"basicPlan": "التحديثات الفورية غير متاحة في الخطة الأساسية. رقِّ إلى Plus لتلقّي إشعارات فورية عند تحديث المهام.",
|
||||
"disabled": "التحديثات الفورية معطّلة. فعّلها لترى التغييرات المباشرة عندما تنجز أنت أو أعضاء دائرتك المهام أو تتخطّونها أو تعدّلونها.",
|
||||
"connected": "التحديثات الفورية تعمل. سترى التغييرات المباشرة عندما تنجز أنت أو أعضاء دائرتك المهام أو تتخطّونها أو تعدّلونها.",
|
||||
"connecting": "جارٍ الاتصال بالتحديثات الفورية…",
|
||||
"errored": "التحديثات الفورية مفعّلة لكنها لا تعمل: {{error}}",
|
||||
"notConnected": "التحديثات الفورية مفعّلة لكن لا يوجد اتصال حاليًا.",
|
||||
"basicPlanNotice": "التحديثات الفورية غير متاحة في الخطة الأساسية. رقِّ إلى Plus لتلقّي إشعارات فورية عندما تنجز أنت أو أعضاء دائرتك المهام أو تتخطّونها أو تعدّلونها."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
111
public/locales/ar/auth.json
Normal file
111
public/locales/ar/auth.json
Normal file
@@ -0,0 +1,111 @@
|
||||
{
|
||||
"validationError": "Validation Error",
|
||||
"primaryUsernameRequired": "Primary username is required for sub account login",
|
||||
"subNameRequired": "Sub account name is required for sub account login",
|
||||
"usernameRequired": "Username is required",
|
||||
"passwordRequired": "Password is required",
|
||||
"loginFailed": "Login Failed",
|
||||
"genericError": "An error occurred, please try again",
|
||||
"providerLoginFailed": "{{provider}} Login Failed",
|
||||
"providerLoginFailedMsg": "Couldn't log in with {{provider}}, please try again",
|
||||
"providerLoginError": "{{provider}} Login Error",
|
||||
"networkError": "Network error occurred, please try again",
|
||||
"mfaFailed": "Two-Factor Authentication Failed",
|
||||
"oauthError": "OAuth Error",
|
||||
"oauthBrowserFailed": "Failed to open authentication browser",
|
||||
"primaryAccount": "Primary Account",
|
||||
"subAccount": "Sub Account",
|
||||
"username": "Username",
|
||||
"primaryUsernamePlaceholder": "Enter primary account username",
|
||||
"subNamePlaceholder": "Enter sub account name",
|
||||
"forgotPassword": "Forgot password?",
|
||||
"or": "or",
|
||||
"email": "Email",
|
||||
"displayNamePlaceholder": "How others see your name",
|
||||
"signupFailed": "Signup Failed",
|
||||
"signupDisabled": "Signup disabled, please contact admin",
|
||||
"usernameMinLength": "Username must be at least 4 characters",
|
||||
"invalidEmail": "Invalid email address",
|
||||
"passwordLength": "Password must be between 8 and 64 characters",
|
||||
"displayNameRequired": "Display name is required",
|
||||
"displayNameChars": "Display name can only contain letters and numbers",
|
||||
"resetEmailSent": "Reset Email Sent",
|
||||
"resetEmailSentMsg": "Check your email for password reset instructions",
|
||||
"resetFailed": "Reset Failed",
|
||||
"resetFailedMsg": "Failed to send reset email, please try again later",
|
||||
"emailPlaceholder": "you@example.com",
|
||||
"passwordUpdated": "Password Updated",
|
||||
"passwordUpdatedMsg": "Your password has been updated successfully. Redirecting to login...",
|
||||
"passwordUpdateFailed": "Password Update Failed",
|
||||
"passwordUpdateFailedMsg": "Failed to update password, please try again later",
|
||||
"savePassword": "Save password",
|
||||
"server": {
|
||||
"url": "Server URL",
|
||||
"dnsFailed": "Hostname could not be resolved. Check the URL for typos or verify DNS.",
|
||||
"unreachable": "Unable to reach the server. Check the URL, port, and network connection.",
|
||||
"invalidUrl": "Invalid URL format. Include the protocol (http:// or https://) and port if needed."
|
||||
},
|
||||
"mfaModal": {
|
||||
"title": "Two-factor authentication",
|
||||
"codeRequired": "Please enter a verification code",
|
||||
"verifyFailed": "Failed to verify code. Please try again.",
|
||||
"backupHint": "Enter one of the backup codes you saved when setting up two-factor authentication.",
|
||||
"codeHint": "Enter the 6-digit code from your authenticator app.",
|
||||
"verify": "Verify & Sign In",
|
||||
"backupLabel": "Backup code",
|
||||
"codeLabel": "Verification code",
|
||||
"backupPlaceholder": "Enter backup code",
|
||||
"useAuthenticator": "Use authenticator app instead",
|
||||
"useBackup": "Use a backup code instead",
|
||||
"backupOnce": "Each backup code can only be used once.",
|
||||
"invalidCode": "Invalid verification code. Please try again."
|
||||
},
|
||||
"appleLoginFailed": "Apple Login Failed",
|
||||
"googleLoginFailed": "Google Login Failed",
|
||||
"createOne": "Create one",
|
||||
"primaryAccountUsernameLabel": "Primary account username",
|
||||
"subAccountNameLabel": "Sub account name",
|
||||
"serverSettings": "Server settings",
|
||||
"useDifferentAccount": "Use a different account",
|
||||
"yourUsername": "Your username",
|
||||
"backToSignIn": "Back to sign in",
|
||||
"confirmNewPassword": "Confirm new password",
|
||||
"newPassword": "New password",
|
||||
"reenterPassword": "Re-enter your password",
|
||||
"requestNewLink": "Request a new link",
|
||||
"setNewPassword": "Set a new password",
|
||||
"linkInvalid": "This link is not valid",
|
||||
"createAccountButton": "Create account",
|
||||
"createYourAccount": "Create your account",
|
||||
"displayNameLabel": "Display name",
|
||||
"usernameHint": "lowercase letters, numbers, dot and dash",
|
||||
"termsShort": "By creating an account you agree to our Terms of Service and Privacy",
|
||||
"checkYourEmail": "Check your email",
|
||||
"resetYourPassword": "Reset your password",
|
||||
"serverChangeWarning": "Changing the server clears locally cached data on this device.",
|
||||
"serverConnected": "Connected. Taking you to sign in...",
|
||||
"passwordLabel": "Password",
|
||||
"showPassword": "Show password",
|
||||
"hidePassword": "Hide password",
|
||||
"loginPasswordPlaceholder": "Enter your password",
|
||||
"signupPasswordPlaceholder": "At least 8 characters",
|
||||
"signupPasswordHelper": "Use 8 to 64 characters.",
|
||||
"orContinueWith": "or continue with",
|
||||
"signupSignInFailed": "Your account was created, but signing in failed. Please sign in.",
|
||||
"authenticating": {
|
||||
"signingIn": "Signing you in",
|
||||
"signingInSub": "This will only take a moment.",
|
||||
"unknownProvider": "Unknown sign-in provider",
|
||||
"contactSupport": "Please contact support.",
|
||||
"signInFailed": "Sign-in failed",
|
||||
"mfaCancelled": "Two-factor authentication was cancelled.",
|
||||
"requestNotVerified": "The sign-in request could not be verified.",
|
||||
"tryAgain": "Please try again.",
|
||||
"mfaSessionMissing": "The MFA session is missing. Please try again.",
|
||||
"twoFactor": "Two-factor authentication",
|
||||
"verifyToContinue": "Verify your login to continue.",
|
||||
"noToken": "No valid authentication token was returned.",
|
||||
"backToSignIn": "Back to sign in",
|
||||
"mfaFailed": "Two-factor authentication failed. Please try again."
|
||||
}
|
||||
}
|
||||
@@ -71,5 +71,11 @@
|
||||
"reset": "إعادة تعيين المؤقت",
|
||||
"delete": "حذف الجلسة"
|
||||
}
|
||||
},
|
||||
"toolbar": {
|
||||
"defaultProject": "Default Project"
|
||||
},
|
||||
"sort": {
|
||||
"assignedToMe": "Assigned to me"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
"logout": "تسجيل الخروج",
|
||||
"version": "النسخة",
|
||||
"navigation": {
|
||||
"search": "بحث",
|
||||
"allTasks": "جميع المهام",
|
||||
"archived": "المؤرشفة",
|
||||
"things": "الأشياء",
|
||||
@@ -28,6 +29,123 @@
|
||||
"filters": "الفلاتر",
|
||||
"activities": "الأنشطة",
|
||||
"points": "النقاط",
|
||||
"settings": "الإعدادات"
|
||||
"settings": "الإعدادات",
|
||||
"reportBug": "Report a Bug"
|
||||
},
|
||||
"search": {
|
||||
"title": "بحث",
|
||||
"placeholder": "ابحث في Donetick",
|
||||
"inputAriaLabel": "ابحث في المهام والسجل والمشاريع والتسميات والإعدادات",
|
||||
"deviceNote": "يتم البحث في المحتوى المتوفر على هذا الجهاز",
|
||||
"escape": "Esc",
|
||||
"recent": "الأخيرة",
|
||||
"empty": {
|
||||
"title": "لا توجد نتائج مطابقة",
|
||||
"subtitle": "لا يزال بإمكانك تصفية قائمة المهام باستخدام هذا البحث."
|
||||
},
|
||||
"groups": {
|
||||
"tasks": "المهام",
|
||||
"history": "الملاحظات",
|
||||
"projects": "المشاريع",
|
||||
"labels": "التسميات",
|
||||
"people": "الأشخاص",
|
||||
"settings": "الإعدادات",
|
||||
"actions": "إجراءات سريعة"
|
||||
},
|
||||
"actions": {
|
||||
"quickAction": "إجراء سريع",
|
||||
"navigation": "التنقل",
|
||||
"createTask": "إنشاء مهمة",
|
||||
"viewAllTasks": "عرض جميع المهام",
|
||||
"viewArchivedTasks": "عرض المهام المؤرشفة",
|
||||
"openSettings": "فتح الإعدادات",
|
||||
"filterTasks": "عرض المهام المطابقة لـ «{{query}}»",
|
||||
"filterTasksSubtitle": "تصفية قائمة المهام"
|
||||
},
|
||||
"footer": {
|
||||
"navigate": "تنقل",
|
||||
"open": "فتح",
|
||||
"results_one": "نتيجة واحدة",
|
||||
"results_other": "{{count}} نتيجة",
|
||||
"typeToSearch": "اكتب للبحث"
|
||||
}
|
||||
},
|
||||
"feedback": {
|
||||
"later": "Maybe later",
|
||||
"sentiment": {
|
||||
"title": "How's Donetick working for you?",
|
||||
"subtitle": "Your answer helps us decide what to build next.",
|
||||
"options": {
|
||||
"love": "Love it",
|
||||
"okay": "It's okay",
|
||||
"issues": "Having issues"
|
||||
}
|
||||
},
|
||||
"categories": {
|
||||
"bugs": "Bugs",
|
||||
"missingFeature": "Missing feature",
|
||||
"tooComplicated": "Too complicated",
|
||||
"slow": "Slow",
|
||||
"notifications": "Notifications",
|
||||
"ai": "AI",
|
||||
"other": "Other"
|
||||
},
|
||||
"details": {
|
||||
"title": "What could we improve?",
|
||||
"messageLabel": "Tell us more",
|
||||
"messagePlaceholder": "What happened, or what would make this better?",
|
||||
"contextNote": "We'll include your app version, device and platform so we can reproduce issues.",
|
||||
"submit": "Send feedback",
|
||||
"contextNoteSelfHosted": "You're on a self-hosted instance, so nothing is sent from your server — we'll open a pre-filled GitHub issue you can review and edit first.",
|
||||
"submitSelfHosted": "Continue to GitHub"
|
||||
},
|
||||
"review": {
|
||||
"title": "Glad you're enjoying it!",
|
||||
"subtitle": "A rating or a star helps other people find Donetick.",
|
||||
"github": "Star on GitHub",
|
||||
"appStore": "Rate on the App Store",
|
||||
"playStore": "Rate on Google Play"
|
||||
},
|
||||
"thanks": {
|
||||
"title": "Thanks for the feedback",
|
||||
"subtitle": "We read every response and it shapes what we work on next."
|
||||
},
|
||||
"github": {
|
||||
"title": "Report it on GitHub",
|
||||
"subtitle": "We've filled in an issue with your notes and version details. Nothing has been sent yet — review it and post when you're ready.",
|
||||
"open": "Open the issue"
|
||||
}
|
||||
},
|
||||
"done": "Done",
|
||||
"clearAll": "Clear all",
|
||||
"upload": {
|
||||
"quotaTitle": "Storage Quota Exceeded",
|
||||
"quotaMessage": "You have exceeded your quota for uploading files.",
|
||||
"tooLargeTitle": "File Too Large",
|
||||
"tooLargeMessage": "The file you are trying to upload is too large.",
|
||||
"deniedTitle": "Permission Denied",
|
||||
"deniedMessage": "You do not have permission to upload files."
|
||||
},
|
||||
"getStarted": "Get Started!",
|
||||
"imageLoadFailed": "Failed to load image.",
|
||||
"typeHere": "Type in here…",
|
||||
"summaryOfChores": "This is a summary of your chores",
|
||||
"loadingOffline": "You are offline",
|
||||
"loadingOfflineSub": "This not available while offline. Please check your internet connection and try again.",
|
||||
"loadingSlow": "This is taking longer than usual. There might be an issue.",
|
||||
"navigateBack": "Navigate Back",
|
||||
"bottomNav": "Bottom Navigation",
|
||||
"profile": "Profile",
|
||||
"autocompletePlaceholder": "Type here...",
|
||||
"errorScreen": {
|
||||
"title": "Something went wrong",
|
||||
"fallback": "An unexpected error occurred. Try reloading — it usually fixes it.",
|
||||
"tryAgain": "Try again",
|
||||
"home": "Home",
|
||||
"login": "Login",
|
||||
"hideDetails": "Hide error details",
|
||||
"showDetails": "Show error details",
|
||||
"copyToClipboard": "Copy to clipboard",
|
||||
"copied": "Error details copied to clipboard"
|
||||
}
|
||||
}
|
||||
|
||||
17
public/locales/ar/filters.json
Normal file
17
public/locales/ar/filters.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"builder": {
|
||||
"errorName": "Please enter a filter name",
|
||||
"errorConditions": "Please configure at least one filter condition",
|
||||
"editTitle": "Edit Filter",
|
||||
"newTitle": "New Filter",
|
||||
"addConditions": "Add conditions to preview",
|
||||
"save": "Save Filter",
|
||||
"name": "Filter Name",
|
||||
"namePlaceholder": "e.g. Overdue tasks for Alice",
|
||||
"color": "Color"
|
||||
},
|
||||
"nameExists": "A filter with this name already exists",
|
||||
"tasks_one": "{{count}} task",
|
||||
"tasks_other": "{{count}} tasks",
|
||||
"overdue": "{{count}} overdue"
|
||||
}
|
||||
89
public/locales/ar/history.json
Normal file
89
public/locales/ar/history.json
Normal file
@@ -0,0 +1,89 @@
|
||||
{
|
||||
"edit": {
|
||||
"title": "Edit History",
|
||||
"completedDate": "Completed Date",
|
||||
"note": "Note",
|
||||
"additionalNotes": "Additional Notes",
|
||||
"deleteTitle": "Delete History",
|
||||
"deleteMessage": "Are you sure you want to delete this history?"
|
||||
},
|
||||
"status": {
|
||||
"inProgress": "In Progress",
|
||||
"completed": "Completed",
|
||||
"skipped": "Skipped",
|
||||
"pendingApproval": "Pending Approval",
|
||||
"rejected": "Rejected",
|
||||
"missed": "Missed",
|
||||
"rescheduled": "Rescheduled",
|
||||
"scheduled": "Scheduled"
|
||||
},
|
||||
"badge": {
|
||||
"onTime": "On Time",
|
||||
"onTimeLabel": "On time"
|
||||
},
|
||||
"detail": {
|
||||
"title": "Activity Detail",
|
||||
"openTask": "Open Task",
|
||||
"editEntry": "Edit Entry",
|
||||
"performedBy": "Performed by",
|
||||
"assignedTo": "Assigned to",
|
||||
"lastUpdated": "Last updated",
|
||||
"duration": "Duration",
|
||||
"pointsEarned": "Points earned",
|
||||
"points_one": "{{count}} pt",
|
||||
"points_other": "{{count}} pts",
|
||||
"note": "Note"
|
||||
},
|
||||
"charts": {
|
||||
"noData": "No data available",
|
||||
"noLabels": "No Labels",
|
||||
"unassigned": "Unassigned",
|
||||
"unknownTask": "Unknown Task",
|
||||
"late": "Late",
|
||||
"status": {
|
||||
"title": "Status",
|
||||
"description": "Completed tasks status"
|
||||
},
|
||||
"due": {
|
||||
"title": "Due Date",
|
||||
"description": "Current tasks due date"
|
||||
},
|
||||
"priority": {
|
||||
"title": "Priority",
|
||||
"description": "Tasks by priority"
|
||||
},
|
||||
"labels": {
|
||||
"title": "Labels",
|
||||
"description": "Tasks by labels"
|
||||
},
|
||||
"labelsDuration": {
|
||||
"title": "Labels (time)",
|
||||
"description": "Time spent by labels (hours)"
|
||||
},
|
||||
"tasksTime": {
|
||||
"title": "Tasks (time)",
|
||||
"description": "Time spent by individual tasks (hours)"
|
||||
},
|
||||
"assigneeBreakdown": {
|
||||
"title": "by Assignee",
|
||||
"description": "Tasks grouped by assignee"
|
||||
}
|
||||
},
|
||||
"filter": {
|
||||
"status": "Status",
|
||||
"pending": "Pending",
|
||||
"labels": "Labels",
|
||||
"hasNotes": "Has Notes",
|
||||
"hasPoints": "Has Points",
|
||||
"timePeriod": "Time Period",
|
||||
"user": "User"
|
||||
},
|
||||
"period": {
|
||||
"days_one": "{{count}} Day",
|
||||
"days_other": "{{count}} Days",
|
||||
"allTime": "All Time"
|
||||
},
|
||||
"activities": {
|
||||
"title": "Activities"
|
||||
}
|
||||
}
|
||||
9
public/locales/ar/labels.json
Normal file
9
public/locales/ar/labels.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"shared": "Shared",
|
||||
"delete": {
|
||||
"title": "Delete Label",
|
||||
"message": "Are you sure you want to delete this label? This will remove the label from all tasks."
|
||||
},
|
||||
"loadError": "Failed to load labels. Please try again.",
|
||||
"blurb": "Manage your labels and organize your tasks effectively. Labels will be automatically shared with your circle if they are used on a shared task."
|
||||
}
|
||||
74
public/locales/ar/points.json
Normal file
74
public/locales/ar/points.json
Normal file
@@ -0,0 +1,74 @@
|
||||
{
|
||||
"redeem": "Redeem Points",
|
||||
"redeemModal": {
|
||||
"redeemButton": "Redeem",
|
||||
"pointsAvailable": "{{count}} points available",
|
||||
"pointsToRedeem": "Points to Redeem",
|
||||
"placeholder": "Enter points...",
|
||||
"cannotExceed": "Cannot exceed available points",
|
||||
"quickAdd": "Quick Add:",
|
||||
"aboutToRedeem": "You are about to redeem",
|
||||
"amount": "{{count}} points",
|
||||
"remaining": "Remaining: {{count}} points"
|
||||
},
|
||||
"leaderboard": {
|
||||
"titlePoints": "Points Leaderboard",
|
||||
"titleTasks": "Tasks Leaderboard",
|
||||
"subtitlePoints": "Rankings based on points earned during the selected time period",
|
||||
"subtitleTasks": "Rankings based on tasks completed during the selected time period",
|
||||
"modePoints": "Points",
|
||||
"modeTasks": "Tasks",
|
||||
"you": "You",
|
||||
"tasksAndAvg": "{{tasks}} tasks • {{avg}} avg per task",
|
||||
"available": "{{count}} available",
|
||||
"points_one": "{{count}} point",
|
||||
"points_other": "{{count}} points"
|
||||
},
|
||||
"tabs": {
|
||||
"short7d": "7D",
|
||||
"short6m": "6M",
|
||||
"shortAll": "All",
|
||||
"days7": "7 Days",
|
||||
"months6": "6 Months",
|
||||
"allTime": "All Time"
|
||||
},
|
||||
"filter": {
|
||||
"analysisTitle": "Filter & Analysis",
|
||||
"title": "Filter Points",
|
||||
"showFor": "Show points for:",
|
||||
"timePeriod": "Time period:"
|
||||
},
|
||||
"cards": {
|
||||
"available": {
|
||||
"title": "Available",
|
||||
"subtext": "Ready to redeem"
|
||||
},
|
||||
"redeemed": {
|
||||
"title": "Redeemed",
|
||||
"subtext": "Previously used"
|
||||
},
|
||||
"total": {
|
||||
"title": "Total",
|
||||
"subtext": "All time earned"
|
||||
},
|
||||
"period": {
|
||||
"title": "Period Points",
|
||||
"allTime": "All time",
|
||||
"last6Months": "Last 6 months",
|
||||
"lastDays_one": "Last {{count}} day",
|
||||
"lastDays_other": "Last {{count}} days"
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"showingFor": "Showing points for",
|
||||
"unknownUser": "Unknown User",
|
||||
"overThe": "over the",
|
||||
"allTime": "All Time",
|
||||
"last6Months": "Last 6 Months",
|
||||
"lastDays_one": "Last {{count}} Day",
|
||||
"lastDays_other": "Last {{count}} Days"
|
||||
},
|
||||
"trend": {
|
||||
"title": "Points Trend"
|
||||
}
|
||||
}
|
||||
24
public/locales/ar/projects.json
Normal file
24
public/locales/ar/projects.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"iconPicker": {
|
||||
"chooseIcon": "Choose Project Icon",
|
||||
"availableIcons": "Available Icons"
|
||||
},
|
||||
"defaultChip": "Default",
|
||||
"tasks_one": "{{count}} task",
|
||||
"tasks_other": "{{count}} tasks",
|
||||
"shared": "Shared",
|
||||
"delete": {
|
||||
"title": "Delete Project",
|
||||
"message": "Are you sure you want to delete \"{{name}}\"? This will remove the project but keep all tasks (they'll move to the Default Project)."
|
||||
},
|
||||
"loadError": "Failed to load projects. Please try again.",
|
||||
"blurb": "Organize your tasks into projects. Create custom workspaces to keep your tasks organized and easily accessible.",
|
||||
"defaultDescription": "All tasks without a specific project",
|
||||
"selector": {
|
||||
"title": "Projects",
|
||||
"createNew": "Create New Project",
|
||||
"createNewDescription": "Add a custom project workspace",
|
||||
"manage": "Manage Projects",
|
||||
"manageDescription": "View, edit, and organize all projects"
|
||||
}
|
||||
}
|
||||
@@ -1,116 +1,29 @@
|
||||
{
|
||||
"title": "الإعدادات",
|
||||
"circleSettings": {
|
||||
"title": "إعدادات الدائرة",
|
||||
"description": "يتم ربط حسابك تلقائيًا بدائرة عند إنشاء واحدة أو الانضمام إليها. ادعُ الأصدقاء بسهولة من خلال مشاركة رمز الدائرة الفريد أو الرابط أدناه. ستتلقى إشعارًا أدناه عندما يطلب شخص ما الانضمام إلى دائرتك. إذا كنت ترغب في المغادرة، فما عليك سوى الضغط على زر 'مغادرة الدائرة'.",
|
||||
"circleCode": "رمز الدائرة",
|
||||
"copyCode": "نسخ الرمز",
|
||||
"copyLink": "نسخ الرابط",
|
||||
"codeCopied": "تم نسخ رمز الدائرة!",
|
||||
"linkCopied": "تم نسخ الرابط!",
|
||||
"joinCircle": "الانضمام إلى دائرة",
|
||||
"joinCirclePlaceholder": "أدخل رمز الدائرة",
|
||||
"join": "انضمام",
|
||||
"leave": "مغادرة الدائرة",
|
||||
"leaveConfirmTitle": "مغادرة الدائرة",
|
||||
"leaveConfirmMessage": "هل أنت متأكد من أنك تريد مغادرة هذه الدائرة؟",
|
||||
"circleMembers": "أعضاء الدائرة",
|
||||
"circleMemberRequests": "طلبات انضمام الأعضاء",
|
||||
"admin": "مشرف",
|
||||
"member": "عضو",
|
||||
"pending": "قيد الانتظار",
|
||||
"accept": "قبول",
|
||||
"reject": "رفض",
|
||||
"makeAdmin": "جعله مشرف",
|
||||
"makeMember": "جعله عضو",
|
||||
"remove": "إزالة",
|
||||
"webhookURL": "رابط Webhook",
|
||||
"webhookDescription": "أدخل رابط webhook لتلقي إشعارات أحداث الدائرة",
|
||||
"webhookPlaceholder": "https://your-webhook-url.com"
|
||||
},
|
||||
"accountSettings": {
|
||||
"title": "إعدادات الحساب",
|
||||
"subscription": "الاشتراك",
|
||||
"subscriptionStatus": "الخطة الحالية",
|
||||
"free": "مجاني",
|
||||
"plus": "بلس",
|
||||
"upgrade": "ترقية",
|
||||
"cancel": "إلغاء",
|
||||
"changePassword": "تغيير كلمة المرور",
|
||||
"password": "كلمة المرور",
|
||||
"dangerZone": "منطقة الخطر",
|
||||
"dangerZoneDescription": "بمجرد حذف حسابك، لا يمكن التراجع. يرجى التأكد.",
|
||||
"deleteAccount": "حذف الحساب"
|
||||
},
|
||||
"localization": {
|
||||
"title": "التوطين",
|
||||
"description": "تخصيص اللغة وتنسيق التاريخ والتفضيلات الإقليمية لحسابك.",
|
||||
"language": "اللغة",
|
||||
"languageDescription": "اختر لغتك المفضلة",
|
||||
"dateFormat": "تنسيق التاريخ",
|
||||
"dateFormatDescription": "اختر كيفية عرض التواريخ في التطبيق",
|
||||
"timeFormat": "تنسيق الوقت",
|
||||
"timeFormatDescription": "اختر تنسيق 12 أو 24 ساعة",
|
||||
"12hour": "12 ساعة (ص/م)",
|
||||
"24hour": "24 ساعة",
|
||||
"firstDayOfWeek": "أول يوم في الأسبوع",
|
||||
"firstDayOfWeekDescription": "اختر اليوم الذي يبدأ به أسبوعك",
|
||||
"sunday": "الأحد",
|
||||
"monday": "الاثنين",
|
||||
"saturday": "السبت",
|
||||
"formats": {
|
||||
"mdy": "MM/DD/YYYY (الولايات المتحدة)",
|
||||
"dmy": "DD/MM/YYYY (أوروبا)",
|
||||
"ymd": "YYYY-MM-DD (ISO)",
|
||||
"long": "تنسيق طويل (مثل 1 يناير 2024)",
|
||||
"short": "تنسيق قصير (مثل 1 يناير 2024)"
|
||||
}
|
||||
},
|
||||
"sidepanel": {
|
||||
"title": "تخصيص اللوحة الجانبية",
|
||||
"description": "قم بتخصيص تخطيط ورؤية البطاقات في اللوحة الجانبية. هذا القسم متاح فقط على أجهزة الشاشة الكبيرة مثل الأجهزة اللوحية وأجهزة سطح المكتب."
|
||||
},
|
||||
"theme": {
|
||||
"title": "تفضيلات المظهر",
|
||||
"description": "اختر كيف يبدو الموقع لك. حدد مظهرًا واحدًا أو قم بالمزامنة مع نظامك والتبديل تلقائيًا بين مظاهر النهار والليل.",
|
||||
"themeMode": "وضع المظهر",
|
||||
"light": "فاتح",
|
||||
"dark": "داكن",
|
||||
"system": "النظام"
|
||||
},
|
||||
"notifications": {
|
||||
"settingsSaved": "تم حفظ الإعدادات بنجاح",
|
||||
"settingsSaveFailed": "فشل حفظ الإعدادات",
|
||||
"invalidWebhook": "رابط webhook غير صالح"
|
||||
},
|
||||
"profile": {
|
||||
"title": "إعدادات الملف الشخصي",
|
||||
"description": "تحديث اسم العرض وصورة الملف الشخصي.",
|
||||
"photoUpdated": "تم تحديث الصورة",
|
||||
"photoUpdatedMessage": "تم تحديث صورة ملفك الشخصي بنجاح!",
|
||||
"uploadFailed": "فشل التحميل",
|
||||
"uploadFailedMessage": "فشل تحميل صورتك. يرجى المحاولة مرة أخرى.",
|
||||
"profileUpdated": "تم تحديث الملف الشخصي",
|
||||
"profileUpdatedMessage": "تم حفظ معلومات ملفك الشخصي بنجاح!",
|
||||
"updateFailed": "فشل التحديث",
|
||||
"updateFailedMessage": "تعذر تحديث ملفك الشخصي. يرجى التحقق من اتصالك والمحاولة مرة أخرى.",
|
||||
"changePhoto": "تغيير الصورة",
|
||||
"displayName": "اسم العرض",
|
||||
"displayNamePlaceholder": "أدخل اسم العرض الخاص بك",
|
||||
"timezone": "المنطقة الزمنية",
|
||||
"timezonePlaceholder": "اختر منطقتك الزمنية",
|
||||
"common": {
|
||||
"save": "حفظ",
|
||||
"cancel": "إلغاء"
|
||||
"cancel": "إلغاء",
|
||||
"confirm": "تأكيد",
|
||||
"remove": "إزالة",
|
||||
"delete": "حذف",
|
||||
"refresh": "تحديث",
|
||||
"loading": "جارٍ التحميل…",
|
||||
"on": "مفعّل",
|
||||
"off": "متوقف",
|
||||
"error": "خطأ",
|
||||
"success": "تم بنجاح",
|
||||
"plusFeature": "ميزة Plus",
|
||||
"earlyAccess": "وصول مبكر"
|
||||
},
|
||||
"overview": {
|
||||
"title": "الإعدادات",
|
||||
"subtitle": "قم بتخصيص تجربتك وإدارة تفضيلات حسابك",
|
||||
"subtitle": "خصّص تجربتك وأدر تفضيلات حسابك",
|
||||
"upgrade": {
|
||||
"title": "الترقية إلى بلس",
|
||||
"description": "افتح ميزات قوية لتعزيز إنتاجيتك",
|
||||
"button": "الترقية الآن",
|
||||
"title": "الترقية إلى Plus",
|
||||
"description": "افتح ميزات قوية تزيد من إنتاجيتك",
|
||||
"button": "ترقية الآن",
|
||||
"features": {
|
||||
"richText": "أوصاف نصية منسقة",
|
||||
"richText": "أوصاف بنص منسّق",
|
||||
"notifications": "إشعارات المهام",
|
||||
"apiIntegrations": "تكاملات API",
|
||||
"advancedAutomation": "أتمتة متقدمة"
|
||||
@@ -119,56 +32,536 @@
|
||||
"sections": {
|
||||
"profile": {
|
||||
"title": "إعدادات الملف الشخصي",
|
||||
"description": "تحديث معلومات ملفك الشخصي والصورة واسم العرض وتفضيلات المنطقة الزمنية."
|
||||
"description": "حدّث معلومات ملفك الشخصي وصورتك واسم العرض والمنطقة الزمنية."
|
||||
},
|
||||
"circle": {
|
||||
"title": "إعدادات الدائرة",
|
||||
"description": "إدارة دائرتك ودعوة الأعضاء والتعامل مع طلبات الانضمام."
|
||||
"description": "أدر دائرتك، وادعُ الأعضاء، وتعامل مع طلبات الانضمام."
|
||||
},
|
||||
"account": {
|
||||
"title": "إعدادات الحساب",
|
||||
"description": "إدارة اشتراكك وتغيير كلمة المرور وخيارات حذف الحساب."
|
||||
"description": "أدر اشتراكك، وغيّر كلمة المرور، واحذف حسابك."
|
||||
},
|
||||
"subaccounts": {
|
||||
"title": "الحسابات المُدارة",
|
||||
"description": "إنشاء وإدارة حسابات فرعية لتسجيل الدخول وإكمال المهام المعينة."
|
||||
"description": "أنشئ وأدر حسابات فرعية يمكنها تسجيل الدخول وإنجاز المهام المسندة إليها."
|
||||
},
|
||||
"notifications": {
|
||||
"title": "الإشعارات",
|
||||
"description": "تكوين الإشعارات الفورية وتنبيهات البريد الإلكتروني ووجهات الإشعارات للمهام."
|
||||
"description": "اضبط الإشعارات الفورية وتنبيهات البريد ووجهات إشعارات المهام."
|
||||
},
|
||||
"mfa": {
|
||||
"title": "المصادقة متعددة العوامل",
|
||||
"description": "إضافة طبقة إضافية من الأمان باستخدام MFA مع تطبيقات المصادقة."
|
||||
"description": "أضف طبقة حماية إضافية عبر المصادقة متعددة العوامل باستخدام تطبيقات المصادقة."
|
||||
},
|
||||
"apitokens": {
|
||||
"title": "رموز API",
|
||||
"description": "إنشاء وإدارة رموز الوصول لتكاملات الطرف الثالث والوصول إلى API."
|
||||
"description": "أنشئ وأدر رموز الوصول للتكاملات الخارجية والوصول إلى API."
|
||||
},
|
||||
"storage": {
|
||||
"title": "إعدادات التخزين",
|
||||
"description": "نسخ احتياطي واستعادة بياناتك وإدارة التخزين المحلي وتفضيلات المزامنة."
|
||||
"description": "انسخ بياناتك احتياطيًا واستعدها، وأدر التخزين المحلي وتفضيلات المزامنة."
|
||||
},
|
||||
"sidepanel": {
|
||||
"title": "تخصيص اللوحة الجانبية",
|
||||
"description": "قم بتخصيص تخطيط ورؤية البطاقات في واجهة اللوحة الجانبية."
|
||||
"description": "خصّص ترتيب البطاقات وظهورها في اللوحة الجانبية."
|
||||
},
|
||||
"theme": {
|
||||
"title": "تفضيلات المظهر",
|
||||
"description": "اختر مظهرك المفضل وقم بتكوين إعدادات الوضع الداكن/الفاتح."
|
||||
"description": "اختر المظهر المفضل لديك واضبط الوضع الفاتح/الداكن."
|
||||
},
|
||||
"localization": {
|
||||
"title": "التوطين",
|
||||
"description": "تخصيص اللغة وتنسيق التاريخ وتنسيق الوقت والتفضيلات الإقليمية."
|
||||
"title": "الإعدادات المحلية",
|
||||
"description": "خصّص اللغة وتنسيق التاريخ والوقت والتفضيلات الإقليمية."
|
||||
},
|
||||
"advanced": {
|
||||
"title": "الإعدادات المتقدمة",
|
||||
"description": "تكوين webhooks والتحديثات في الوقت الفعلي وميزات متقدمة أخرى لتعزيز الإنتاجية."
|
||||
"description": "اضبط الـ Webhooks والتحديثات الفورية وغيرها من الميزات المتقدمة."
|
||||
},
|
||||
"developer": {
|
||||
"title": "إعدادات المطور",
|
||||
"description": "عرض المعلومات الفنية حول رموز المصادقة واتصالات SSE وبيانات التصحيح."
|
||||
"title": "إعدادات المطوّر",
|
||||
"description": "اعرض معلومات تقنية عن رموز المصادقة واتصالات SSE وبيانات التصحيح."
|
||||
},
|
||||
"feedback": {
|
||||
"title": "إرسال ملاحظات",
|
||||
"description": "أخبرنا كيف يعمل Donetick معك أو اطلب ميزة جديدة."
|
||||
},
|
||||
"bugReport": {
|
||||
"title": "الإبلاغ عن خلل",
|
||||
"description": "هناك شيء لا يعمل كما ينبغي؟ أرسل لنا التفاصيل مع لقطة تقنية."
|
||||
}
|
||||
}
|
||||
},
|
||||
"profile": {
|
||||
"title": "إعدادات الملف الشخصي",
|
||||
"description": "حدّث اسم العرض وصورة ملفك الشخصي.",
|
||||
"photoUpdated": "تم تحديث الصورة",
|
||||
"photoUpdatedMessage": "تم تحديث صورة ملفك الشخصي بنجاح!",
|
||||
"uploadFailed": "فشل الرفع",
|
||||
"uploadFailedMessage": "تعذّر رفع صورتك. يرجى المحاولة مرة أخرى.",
|
||||
"profileUpdated": "تم تحديث الملف الشخصي",
|
||||
"profileUpdatedMessage": "تم حفظ معلومات ملفك الشخصي بنجاح!",
|
||||
"updateFailed": "فشل التحديث",
|
||||
"updateFailedMessage": "تعذّر تحديث ملفك الشخصي. تحقق من اتصالك وحاول مرة أخرى.",
|
||||
"changePhoto": "تغيير الصورة",
|
||||
"editPhoto": "تحرير صورة الملف الشخصي",
|
||||
"displayName": "اسم العرض",
|
||||
"displayNamePlaceholder": "أدخل اسم العرض",
|
||||
"timezone": "المنطقة الزمنية",
|
||||
"timezonePlaceholder": "اختر منطقتك الزمنية",
|
||||
"save": "حفظ",
|
||||
"cancel": "إلغاء"
|
||||
},
|
||||
"circleSettings": {
|
||||
"title": "إعدادات الدائرة",
|
||||
"description": "يرتبط حسابك تلقائيًا بدائرة عند إنشائها أو الانضمام إليها. ادعُ أصدقاءك بسهولة عبر مشاركة رمز الدائرة أو الرابط أدناه. وسيصلك إشعار هنا عندما يطلب أحدهم الانضمام إلى دائرتك.",
|
||||
"memberOf": "أنت جزء من {{name}}",
|
||||
"yourCircleCode": "رمز دائرتك هو:",
|
||||
"copyCode": "نسخ الرمز",
|
||||
"shareInvite": "مشاركة الدعوة",
|
||||
"codeCopied": "تم نسخ الرمز إلى الحافظة",
|
||||
"linkCopied": "تم نسخ رابط الدعوة إلى الحافظة",
|
||||
"myCircle": "دائرتي",
|
||||
"shareTitle": "انضم إلى {{name}} على Donetick",
|
||||
"shareText": "أودّ دعوتك للانضمام إلى {{name}} على Donetick.",
|
||||
"shareDialogTitle": "مشاركة دعوة الدائرة",
|
||||
"leave": "مغادرة الدائرة",
|
||||
"leaveConfirmTitle": "مغادرة الدائرة",
|
||||
"leaveConfirmMessage": "هل تريد بالتأكيد مغادرة دائرتك؟",
|
||||
"leaveConfirmButton": "مغادرة",
|
||||
"leftCircle": "تمت مغادرة الدائرة بنجاح",
|
||||
"leaveFailed": "تعذّرت مغادرة الدائرة",
|
||||
"circleMembers": "أعضاء الدائرة",
|
||||
"you": "(أنت)",
|
||||
"pendingApproval": "بانتظار الموافقة",
|
||||
"joinedOn": "انضم في {{date}}",
|
||||
"requestedToJoin": "طلب الانضمام {{date}}",
|
||||
"roles": {
|
||||
"member": "عضو",
|
||||
"memberDescription": "عضو عادي في الدائرة",
|
||||
"manager": "مدير",
|
||||
"managerDescription": "يمكنه انتحال هوية المستخدمين وتنفيذ إجراءات نيابةً عنهم",
|
||||
"admin": "مسؤول",
|
||||
"adminDescription": "صلاحية كاملة على الدائرة"
|
||||
},
|
||||
"roleUpdateFailed": "تعذّر تحديث الدور",
|
||||
"removeMemberTitle": "إزالة عضو",
|
||||
"removeMemberMessage": "هل تريد بالتأكيد إزالة {{name}} من دائرتك؟",
|
||||
"memberRemoved": "تمت إزالة العضو بنجاح",
|
||||
"circleMemberRequests": "طلبات الانضمام إلى الدائرة",
|
||||
"lastUpdated": "آخر تحديث: {{time}}",
|
||||
"refreshing": "جارٍ التحديث…",
|
||||
"refreshFailed": "تعذّر تحديث طلبات الانضمام",
|
||||
"wantsToJoin": "يريد {{name}} الانضمام إلى دائرتك.",
|
||||
"accept": "قبول",
|
||||
"acceptRequestTitle": "قبول طلب الانضمام",
|
||||
"acceptRequestMessage": "هل تريد بالتأكيد قبول {{name}} (اسم المستخدم: {{username}}) للانضمام إلى دائرتك؟",
|
||||
"requestAccepted": "تم قبول الطلب بنجاح",
|
||||
"or": "أو",
|
||||
"joinOtherDescription": "تريد الانضمام إلى دائرة شخص آخر؟ اطلب منه رمز الدائرة أو رابط الانضمام، ثم أدخل الرمز أدناه للانضمام.",
|
||||
"enterCircleCode": "أدخل رمز الدائرة:",
|
||||
"enterCodePlaceholder": "أدخل الرمز",
|
||||
"joinCircle": "الانضمام إلى الدائرة",
|
||||
"joinedPending": "تم الانضمام إلى الدائرة بنجاح، انتظر موافقة مالك الدائرة على طلبك.",
|
||||
"alreadyMember": "أنت عضو في هذه الدائرة بالفعل",
|
||||
"joinFailed": "تعذّر الانضمام إلى الدائرة"
|
||||
},
|
||||
"accountSettings": {
|
||||
"title": "إعدادات الحساب",
|
||||
"description": "غيّر إعدادات حسابك أو نوع خطتك أو كلمة المرور",
|
||||
"accountType": "نوع الحساب: {{type}}",
|
||||
"free": "مجاني",
|
||||
"plus": "بلس",
|
||||
"plusUntil": "Plus (حتى {{date}})",
|
||||
"activeDescription": "أنت مشترك حاليًا في خطة Plus. سيتجدد اشتراكك في {{date}}.",
|
||||
"cancelledDescription": "لقد ألغيت اشتراكك. سيتم خفض حسابك إلى الخطة المجانية في {{date}}.",
|
||||
"freeDescription": "أنت حاليًا على الخطة المجانية. رقِّ إلى Plus لفتح المزيد من الميزات.",
|
||||
"upgrade": "ترقية",
|
||||
"cancel": "إلغاء الاشتراك",
|
||||
"password": "كلمة المرور:",
|
||||
"changePassword": "تغيير كلمة المرور",
|
||||
"passwordChanged": "تم تغيير كلمة المرور بنجاح",
|
||||
"passwordChangeFailed": "فشل تغيير كلمة المرور",
|
||||
"dangerZone": "منطقة الخطر",
|
||||
"dangerZoneDescription": "بمجرد حذف حسابك لا يمكن التراجع. يرجى التأكد قبل المتابعة.",
|
||||
"deleteAccount": "حذف الحساب",
|
||||
"accountDeleted": "تم حذف الحساب بنجاح",
|
||||
"subscriptionCancelled": "تم إلغاء الاشتراك",
|
||||
"subscriptionCancelFailed": "تعذّر إلغاء الاشتراك",
|
||||
"purchase": {
|
||||
"success": "تمت عملية الشراء بنجاح! أعد تشغيل التطبيق للوصول إلى ميزات Plus.",
|
||||
"storeConnection": "هناك مشكلة في الاتصال بالمتجر. تحقق من شبكتك وحاول مرة أخرى.",
|
||||
"notAllowed": "عمليات الشراء غير مسموح بها على هذا الجهاز. يرجى مراجعة قيود جهازك.",
|
||||
"unavailable": "هذا الاشتراك غير متاح. يرجى المحاولة لاحقًا.",
|
||||
"alreadyProcessed": "تمت معالجة هذه العملية من قبل. إذا كنت ترى أن هذا خطأ، تواصل مع الدعم.",
|
||||
"receiptMissing": "إيصال الشراء مفقود. يرجى إعادة محاولة الشراء.",
|
||||
"networkError": "خطأ في الشبكة. تحقق من اتصالك وحاول مرة أخرى.",
|
||||
"invalidReceipt": "إيصال الشراء غير صالح. تواصل مع الدعم إذا استمرت المشكلة.",
|
||||
"pending": "الدفعة بانتظار الموافقة. ستحصل على الوصول فور اعتمادها.",
|
||||
"failed": "فشلت عملية الشراء: {{error}}. حاول مرة أخرى أو تواصل مع الدعم.",
|
||||
"unknownError": "خطأ غير معروف"
|
||||
}
|
||||
},
|
||||
"subaccounts": {
|
||||
"title": "الحسابات المُدارة",
|
||||
"description": "أدر الحسابات الفرعية. يمكن لمستخدمي الحسابات الفرعية تسجيل الدخول وإنجاز المهام المسندة إليهم.",
|
||||
"notParentTitle": "إدارة الحسابات الفرعية",
|
||||
"notParentMessage": "الحسابات الرئيسية فقط هي التي يمكنها إدارة الحسابات الفرعية.",
|
||||
"freePlanNotice": "الخطة المجانية تتيح حسابًا فرعيًا واحدًا. رقِّ إلى Plus للحصول على ما يصل إلى 5 حسابات فرعية.",
|
||||
"count": "الحسابات الفرعية ({{count}})",
|
||||
"add": "إضافة حساب فرعي",
|
||||
"loading": "جارٍ تحميل الحسابات الفرعية…",
|
||||
"emptyTitle": "لا توجد حسابات فرعية",
|
||||
"emptyDescription": "أنشئ حسابات فرعية ليتمكن أعضاء الفريق من تسجيل الدخول وإنجاز المهام المسندة إليهم.",
|
||||
"addFirst": "أضف أول حساب فرعي",
|
||||
"username": "اسم المستخدم: {{username}}",
|
||||
"created": "أُنشئ في: {{date}}",
|
||||
"changePassword": "تغيير كلمة المرور",
|
||||
"deleteAccount": "حذف الحساب",
|
||||
"createdSuccess": "تم إنشاء الحساب الفرعي «{{name}}» بنجاح!",
|
||||
"createFailed": "تعذّر إنشاء الحساب الفرعي: {{error}}",
|
||||
"createFailedGeneric": "تعذّر إنشاء الحساب الفرعي",
|
||||
"passwordUpdated": "تم تحديث كلمة مرور الحساب الفرعي بنجاح",
|
||||
"passwordUpdateFailed": "تعذّر تحديث كلمة المرور: {{error}}",
|
||||
"passwordUpdateFailedGeneric": "تعذّر تحديث كلمة المرور",
|
||||
"deleteConfirmTitle": "حذف الحساب الفرعي",
|
||||
"deleteConfirmMessage": "هل تريد بالتأكيد حذف الحساب الفرعي «{{name}}»؟ لا يمكن التراجع عن هذا الإجراء.",
|
||||
"deleted": "تم حذف الحساب الفرعي «{{name}}» بنجاح",
|
||||
"deleteFailed": "تعذّر حذف الحساب الفرعي: {{error}}",
|
||||
"deleteFailedGeneric": "تعذّر حذف الحساب الفرعي",
|
||||
"howItWorksTitle": "كيف تعمل الحسابات المُدارة",
|
||||
"howItWorks1": "تُنشئ الحسابات المُدارة من الحساب الرئيسي، وهي مخصّصة لمن تريد أن تكون لديك إمكانية حذف حسابه وإعادة تعيين كلمة مروره.",
|
||||
"howItWorks2": "يمكن للحسابات الفرعية تسجيل الدخول باسم مستخدم وكلمة مرور خاصين بها.",
|
||||
"howItWorks3": "يمكن للحسابات المُدارة إنجاز المهام لكن صلاحياتها الإدارية محدودة",
|
||||
"howItWorks4": "تُضاف الحسابات المُدارة تلقائيًا إلى دائرتك"
|
||||
},
|
||||
"notifications": {
|
||||
"title": "إعدادات الإشعارات",
|
||||
"deviceSection": "إشعارات الجهاز",
|
||||
"deviceSectionDescription": "أدر إشعارات جهازك",
|
||||
"deviceLabel": "إشعار الجهاز",
|
||||
"deviceHelper": "تلقَّ إشعارًا على جهازك عند استحقاق مهمة",
|
||||
"mobileOnly": "هذه الميزة متاحة على الأجهزة المحمولة فقط",
|
||||
"testNotification": "إشعار تجريبي",
|
||||
"testNotificationBody": "لديك مهمة تستحق قريبًا",
|
||||
"dueTitle": "إشعار الاستحقاق",
|
||||
"dueLabel": "إشعار عند استحقاق المهمة",
|
||||
"preDueTitle": "إشعار قبل الاستحقاق",
|
||||
"preDueLabel": "إشعار قبل ساعات من استحقاق المهمة",
|
||||
"overdueTitle": "إشعار التأخر",
|
||||
"overdueLabel": "إشعار عند تأخر المهمة عن موعدها",
|
||||
"pushLabel": "الإشعارات الفورية",
|
||||
"pushHelper": "تلقَّ التذكيرات والإعلانات وإسنادات المهام عبر الإشعارات الفورية",
|
||||
"registeredDevices": "الأجهزة المسجّلة ({{count}}/5)",
|
||||
"registeredDevicesDescription": "الأجهزة المسجّلة لتلقّي الإشعارات الفورية الخاصة بحسابك",
|
||||
"currentDevice": "الجهاز الحالي: {{platform}} {{model}}",
|
||||
"currentDeviceNotRegistered": "هذا الجهاز غير مسجّل لتلقّي الإشعارات الفورية",
|
||||
"limitReached": "بلغت الحد الأقصى",
|
||||
"registerDevice": "تسجيل الجهاز",
|
||||
"unknownDevice": "جهاز غير معروف",
|
||||
"deviceCreatedAt": "أُنشئ في: {{date}}",
|
||||
"noDevices": "لا توجد أجهزة مسجّلة لتلقّي الإشعارات الفورية",
|
||||
"customSection": "إشعار مخصّص",
|
||||
"customSectionDescription": "الإشعار عبر منصة أخرى مثل Telegram أو Pushover",
|
||||
"customLabel": "إشعار مخصّص",
|
||||
"customHelper": "تلقَّ الإشعارات على منصة أخرى",
|
||||
"targetNone": "بدون",
|
||||
"targetTelegram": "Telegram",
|
||||
"targetPushover": "Pushover",
|
||||
"targetWebhooks": "Webhooks",
|
||||
"telegramBotHelpBefore": "عليك إرسال رسالة إلى البوت أولًا حتى تعمل إشعارات Telegram",
|
||||
"telegramBotHelpAfter": "لبدء محادثة",
|
||||
"clickHere": "اضغط هنا",
|
||||
"chatId": "معرّف المحادثة",
|
||||
"chatIdPlaceholder": "معرّف المستخدم / معرّف المحادثة",
|
||||
"telegramChatIdHelpBefore": "إذا كنت لا تعرف معرّف محادثتك، ابدأ محادثة مع userinfobot وسيرسله إليك.",
|
||||
"telegramChatIdHelpAfter": "لبدء محادثة مع userinfobot",
|
||||
"userKey": "مفتاح المستخدم",
|
||||
"userKeyPlaceholder": "معرّف المستخدم",
|
||||
"chatIdRequired": "معرّف المحادثة مطلوب",
|
||||
"chatIdInvalid": "معرّف المحادثة غير صالح",
|
||||
"userKeyRequired": "مفتاح المستخدم مطلوب",
|
||||
"targetUpdated": "تم تحديث وجهة الإشعارات",
|
||||
"targetUpdateFailed": "حدث خطأ أثناء تحديث وجهة الإشعارات: {{error}}",
|
||||
"deviceRegistered": "تم تسجيل الجهاز بنجاح لتلقّي الإشعارات الفورية.",
|
||||
"deviceLimitTitle": "بلغت الحد الأقصى للأجهزة",
|
||||
"deviceLimitMessage": "لقد بلغت الحد الأقصى وهو 5 أجهزة مسجّلة. يرجى إزالة جهاز قبل تسجيل هذا الجهاز.",
|
||||
"registrationFailedTitle": "فشل التسجيل",
|
||||
"registrationFailedMessage": "تعذّر تسجيل الجهاز تلقائيًا. يرجى المحاولة مرة أخرى.",
|
||||
"permissionRequiredTitle": "الإذن مطلوب",
|
||||
"permissionRequiredMessage": "يلزم إذن الإشعارات الفورية لتسجيل هذا الجهاز.",
|
||||
"registrationInitiatedTitle": "بدأ التسجيل",
|
||||
"registrationInitiatedMessage": "بدأ تسجيل الإشعارات الفورية. سيُسجَّل الجهاز تلقائيًا.",
|
||||
"registerDeviceFailed": "تعذّر تسجيل الجهاز. يرجى المحاولة مرة أخرى.",
|
||||
"permissionDeniedTitle": "تم رفض إذن الإشعارات",
|
||||
"permissionDeniedMessage": "لقد رفضت أذونات الإشعارات. يمكنك تفعيلها لاحقًا من إعدادات جهازك.",
|
||||
"pushPermissionDeniedTitle": "تم رفض إذن الإشعارات الفورية",
|
||||
"pushPermissionDeniedMessage": "تم تعطيل الإشعارات الفورية. يمكنك تفعيلها من إعدادات جهازك عند الحاجة.",
|
||||
"unregisterFailed": "تعذّر إلغاء تسجيل الجهاز"
|
||||
},
|
||||
"mfa": {
|
||||
"title": "المصادقة متعددة العوامل",
|
||||
"description": "أضف طبقة حماية إضافية لحسابك عبر المصادقة متعددة العوامل (MFA). عند تفعيلها، ستحتاج إلى إدخال رمز تحقق من تطبيق المصادقة إلى جانب كلمة المرور عند تسجيل الدخول.",
|
||||
"twoFactor": "المصادقة الثنائية",
|
||||
"enabledSubtitle": "حسابك محمي بالمصادقة الثنائية",
|
||||
"disabledSubtitle": "أمّن حسابك باستخدام تطبيق مصادقة",
|
||||
"enable": "تفعيل",
|
||||
"disable": "تعطيل",
|
||||
"enabledSuccess": "تم تفعيل المصادقة متعددة العوامل بنجاح!",
|
||||
"disabledSuccess": "تم تعطيل المصادقة متعددة العوامل بنجاح!",
|
||||
"errors": {
|
||||
"qrGenerationFailed": "تعذّر إنشاء رمز QR",
|
||||
"invalidResponse": "استجابة غير صالحة من الخادم. رمز QR أو المفتاح السري مفقود.",
|
||||
"notFound": "لم يُعثر على نقطة إعداد المصادقة متعددة العوامل. قد لا تكون هذه الميزة متاحة بعد.",
|
||||
"unauthorized": "غير مصرّح. يرجى تسجيل الدخول مرة أخرى.",
|
||||
"serverError": "خطأ في الخادم. يرجى المحاولة لاحقًا.",
|
||||
"setupFailed": "تعذّر إعداد المصادقة متعددة العوامل ({{status}}). يرجى المحاولة مرة أخرى.",
|
||||
"networkError": "خطأ في الشبكة. تحقق من اتصالك وحاول مرة أخرى.",
|
||||
"invalidCode": "رمز التحقق غير صالح. يرجى المحاولة مرة أخرى.",
|
||||
"confirmFailed": "تعذّر تأكيد المصادقة متعددة العوامل. يرجى المحاولة مرة أخرى.",
|
||||
"disableFailed": "تعذّر تعطيل المصادقة متعددة العوامل. يرجى المحاولة مرة أخرى."
|
||||
},
|
||||
"setup": {
|
||||
"title": "إعداد المصادقة متعددة العوامل",
|
||||
"addedAccount": "لقد أضفت الحساب",
|
||||
"back": "رجوع",
|
||||
"verifyAndEnable": "التحقق والتفعيل",
|
||||
"savedBackupCodes": "لقد حفظت رموز النسخ الاحتياطي",
|
||||
"step1Label": "الخطوة 1:",
|
||||
"step1": "امسح رمز QR أدناه باستخدام تطبيق المصادقة (Google Authenticator أو Authy أو غيرهما)",
|
||||
"qrAlt": "رمز QR للمصادقة متعددة العوامل",
|
||||
"qrFailed": "تعذّر إنشاء رمز QR. حاول مرة أخرى أو استخدم مفتاح الإدخال اليدوي أدناه.",
|
||||
"manualKey": "مفتاح الإدخال اليدوي:",
|
||||
"step2Label": "الخطوة 2:",
|
||||
"step2": "أدخل رمز التحقق المكوّن من 6 أرقام من تطبيق المصادقة",
|
||||
"codePlaceholder": "أدخل الرمز المكوّن من 6 أرقام",
|
||||
"successTitle": "تم تفعيل المصادقة متعددة العوامل بنجاح!",
|
||||
"backupCodesTitle": "احفظ رموز النسخ الاحتياطي هذه في مكان آمن",
|
||||
"backupCodesDescription": "يمكنك استخدام هذه الرموز للوصول إلى حسابك في حال فقدت جهاز المصادقة. يمكن استخدام كل رمز مرة واحدة فقط."
|
||||
},
|
||||
"disableModal": {
|
||||
"title": "تعطيل المصادقة متعددة العوامل",
|
||||
"warning": "تعطيل المصادقة متعددة العوامل يجعل حسابك أقل أمانًا. هل تريد بالتأكيد المتابعة؟",
|
||||
"prompt": "أدخل رمز تحقق من تطبيق المصادقة للتأكيد:",
|
||||
"confirm": "تعطيل المصادقة متعددة العوامل"
|
||||
},
|
||||
"backupCodesModal": {
|
||||
"title": "رموز نسخ احتياطي جديدة",
|
||||
"warning": "لم تعد رموز النسخ الاحتياطي السابقة صالحة. احفظ هذه الرموز الجديدة في مكان آمن. يمكن استخدام كل رمز مرة واحدة فقط."
|
||||
}
|
||||
},
|
||||
"apiTokens": {
|
||||
"title": "رموز API",
|
||||
"accessToken": "رمز الوصول",
|
||||
"description": "أنشئ رمزًا لاستخدامه مع API لتحديث الأشياء التي تُطلق المهام",
|
||||
"plusNotice": "رموز API غير متاحة في الخطة الأساسية. رقِّ إلى Plus لإنشاء رموز API للتكامل مع الأنظمة الخارجية وأتمتة مهامك.",
|
||||
"showToken": "إظهار الرمز",
|
||||
"hideToken": "إخفاء الرمز",
|
||||
"removeTitle": "إزالة الرمز",
|
||||
"removeMessage": "هل تريد بالتأكيد إزالة {{name}}؟",
|
||||
"removedTitle": "تمت الإزالة",
|
||||
"removedMessage": "تمت إزالة رمز API",
|
||||
"tokenCopied": "تم نسخ الرمز إلى الحافظة",
|
||||
"generateNew": "إنشاء رمز جديد",
|
||||
"nameModalTitle": "امنح رمزك الجديد اسمًا يساعدك على تذكّره.",
|
||||
"generateToken": "إنشاء الرمز"
|
||||
},
|
||||
"storage": {
|
||||
"title": "إعدادات التخزين",
|
||||
"serverTitle": "استخدام تخزين الخادم",
|
||||
"serverDescription": "هذه هي المساحة التي يستخدمها حسابك على خوادمنا (مثل الملفات والصور والبيانات التي رفعتها).",
|
||||
"usagePlaceholder": "-- ميغابايت مستخدمة / -- ميغابايت إجمالًا (--)",
|
||||
"usage": "{{used}} ميغابايت مستخدمة / {{total}} ميغابايت إجمالًا ({{percent}}%)",
|
||||
"basicPlanNotice": "تخزين الخادم غير متاح في الخطة الأساسية. رقِّ إلى Plus لتتبّع استخدامك لتخزين الخادم.",
|
||||
"localTitleApp": "التخزين المحلي والذاكرة المؤقتة للتطبيق",
|
||||
"localTitleBrowser": "التخزين المحلي والذاكرة المؤقتة للمتصفح",
|
||||
"localDescription": "هذه بيانات محفوظة محليًا في متصفحك لتسريع الوصول. مسحها لن يؤثر على بياناتك على الخادم، لكنه قد يسجّل خروجك.",
|
||||
"clearLocal": "مسح كل التخزين المحلي والذاكرة المؤقتة",
|
||||
"clearLocalTitle": "مسح كل التخزين المحلي",
|
||||
"clearLocalMessage": "هل تريد بالتأكيد مسح التخزين المحلي والذاكرة المؤقتة؟ سيؤدي ذلك إلى إزالة جميع بياناتك من هذا المتصفح وسيتطلب تسجيل الدخول من جديد.",
|
||||
"clearAll": "مسح الكل",
|
||||
"appPreferences": "تفضيلات التطبيق",
|
||||
"deviceOnly": "على الجهاز فقط",
|
||||
"appPreferencesDescription": "هذه تفضيلات وإعدادات يحفظها التطبيق محليًا على جهازك. مسحها سيعيد ضبط إعدادات التطبيق وقد يسجّل خروجك، لكنه لن يؤثر على بياناتك على الخادم.",
|
||||
"clearPreferences": "مسح تفضيلات التطبيق",
|
||||
"clearPreferencesTitle": "مسح تفضيلات التطبيق",
|
||||
"clearPreferencesMessage": "هل تريد بالتأكيد مسح جميع تفضيلات التطبيق؟ سيؤدي ذلك إلى إعادة ضبط إعداداتك وقد يتطلب تسجيل الدخول من جديد."
|
||||
},
|
||||
"sidepanel": {
|
||||
"title": "تخصيص اللوحة الجانبية",
|
||||
"heading": "إعدادات اللوحة الجانبية",
|
||||
"description": "حدّد البطاقات التي تظهر في اللوحة الجانبية وترتيبها. اسحب وأفلت لإعادة الترتيب، أو بدّل ظهور كل بطاقة.",
|
||||
"resetToDefaults": "استعادة الإعدادات الافتراضية",
|
||||
"resetHelper": "سيؤدي ذلك إلى استعادة الظهور والترتيب الافتراضيين لجميع البطاقات.",
|
||||
"cards": {
|
||||
"welcome": {
|
||||
"name": "تبديل المستخدم",
|
||||
"description": "يتيح للمسؤولين والمديرين عرض المهام بصفة مستخدمين آخرين"
|
||||
},
|
||||
"smartInsights": {
|
||||
"name": "رؤى ذكية",
|
||||
"description": "إجراءات سريعة بناءً على مهامك"
|
||||
},
|
||||
"assignees": {
|
||||
"name": "المهام حسب المكلَّف",
|
||||
"description": "يجمع المهام حسب الشخص المكلَّف بها"
|
||||
},
|
||||
"calendar": {
|
||||
"name": "عرض التقويم",
|
||||
"description": "يعرض المهام بتنسيق تقويم"
|
||||
},
|
||||
"activities": {
|
||||
"name": "الأنشطة الأخيرة",
|
||||
"description": "يعرض المهام المنجزة والأنشطة الأخيرة"
|
||||
},
|
||||
"weeklyGoals": {
|
||||
"name": "الأهداف الأسبوعية",
|
||||
"description": "يعرض التقدّم الأسبوعي وإحصاءات إنجاز العائلة"
|
||||
}
|
||||
}
|
||||
},
|
||||
"theme": {
|
||||
"title": "تفضيلات المظهر",
|
||||
"description": "اختر الشكل الذي يظهر به الموقع لك. حدّد مظهرًا ثابتًا أو زامنه مع نظامك للتبديل تلقائيًا بين المظهر النهاري والليلي.",
|
||||
"themeMode": "وضع المظهر",
|
||||
"light": "فاتح",
|
||||
"dark": "داكن",
|
||||
"system": "النظام"
|
||||
},
|
||||
"localization": {
|
||||
"title": "الإعدادات المحلية",
|
||||
"description": "خصّص اللغة وتنسيق التاريخ والتفضيلات الإقليمية لحسابك.",
|
||||
"language": "اللغة",
|
||||
"languageDescription": "اختر لغتك المفضلة",
|
||||
"rtlNotice": "تُكتب هذه اللغة من اليمين إلى اليسار (RTL)",
|
||||
"dateFormat": "تنسيق التاريخ",
|
||||
"dateFormatDescription": "اختر طريقة عرض التواريخ في جميع أنحاء التطبيق",
|
||||
"timeFormat": "تنسيق الوقت",
|
||||
"timeFormatDescription": "اختر نظام 12 ساعة أو 24 ساعة",
|
||||
"preview": "معاينة: {{value}}",
|
||||
"12hour": "12 ساعة (ص/م)",
|
||||
"24hour": "24 ساعة",
|
||||
"firstDayOfWeek": "أول أيام الأسبوع",
|
||||
"firstDayOfWeekDescription": "اختر اليوم الذي يبدأ به أسبوعك",
|
||||
"sunday": "الأحد",
|
||||
"monday": "الاثنين",
|
||||
"saturday": "السبت",
|
||||
"formats": {
|
||||
"mdy": "MM/DD/YYYY (الولايات المتحدة)",
|
||||
"dmy": "DD/MM/YYYY (أوروبا)",
|
||||
"ymd": "YYYY-MM-DD (ISO)",
|
||||
"long": "تنسيق طويل (مثال: 1 يناير 2024)",
|
||||
"short": "تنسيق قصير (مثال: 1 ينا 2024)"
|
||||
}
|
||||
},
|
||||
"advanced": {
|
||||
"title": "الإعدادات المتقدمة",
|
||||
"description": "اضبط الميزات المتقدمة مثل الـ Webhooks والتحديثات الفورية لتعزيز إنتاجيتك.",
|
||||
"offlineTitle": "دعم العمل دون اتصال",
|
||||
"offlineDescription": "واصل استخدام Donetick دون اتصال على هذا الجهاز/المتصفح. تُحفظ تغييراتك محليًا وتُزامن عند عودتك للاتصال.",
|
||||
"offlineToggle": "تفعيل دعم العمل دون اتصال",
|
||||
"offlineHelper": "إيقاف هذا الخيار يزيل التغييرات غير المزامنة والبيانات المحفوظة دون اتصال من هذا الجهاز/المتصفح.",
|
||||
"offlineEnabled": "تم تفعيل وضع العمل دون اتصال على هذا الجهاز/المتصفح",
|
||||
"offlineDisabled": "تم إيقاف وضع العمل دون اتصال ومسح البيانات المحلية",
|
||||
"offlineDisabledPartial": "تم إيقاف وضع العمل دون اتصال، لكن قد تبقى بعض البيانات المحلية مخزّنة",
|
||||
"offlineDisableTitle": "إيقاف وضع العمل دون اتصال",
|
||||
"offlineDisableMessage": "إيقاف وضع العمل دون اتصال سيزيل التغييرات غير المزامنة والبيانات المحفوظة دون اتصال على هذا الجهاز/المتصفح. هل تريد المتابعة؟",
|
||||
"offlineDisableConfirm": "الإيقاف ومسح البيانات",
|
||||
"webhookTitle": "تكامل Webhook",
|
||||
"webhookDescription": "تتيح لك الـ Webhooks إرسال إشعارات فورية إلى خدمات أخرى عند وقوع أحداث في دائرتك. اضبط رابط Webhook لتلقّي التحديثات الفورية.",
|
||||
"webhookPlusNotice": "إشعارات Webhook غير متاحة في الخطة الأساسية. رقِّ إلى Plus لتلقّي التحديثات الفورية عبر الـ Webhooks.",
|
||||
"webhookToggle": "تفعيل Webhook",
|
||||
"webhookHelper": "فعّل إشعارات Webhook لتحديثات المهام والأشياء.",
|
||||
"webhookURL": "رابط Webhook",
|
||||
"webhookUpdated": "تم تحديث رابط Webhook بنجاح",
|
||||
"webhookUpdateFailed": "تعذّر تحديث رابط Webhook",
|
||||
"realtimeTitle": "التحديثات الفورية",
|
||||
"realtimeDescription": "اضبط كيفية تلقّي التحديثات المباشرة عند تغيّر المهام والأنشطة في دائرتك.",
|
||||
"realtime": {
|
||||
"toggleLabel": "تفعيل التحديثات الفورية",
|
||||
"title": "التحديثات الفورية",
|
||||
"subtitle": "تلقَّ إشعارات فورية عند تحديث المهام",
|
||||
"statusLabel": "الحالة:",
|
||||
"basicPlan": "التحديثات الفورية غير متاحة في الخطة الأساسية. رقِّ إلى Plus لتلقّي إشعارات فورية عند تحديث المهام.",
|
||||
"disabled": "التحديثات الفورية معطّلة. فعّلها لترى التغييرات المباشرة عندما تنجز أنت أو أعضاء دائرتك المهام أو تتخطّونها أو تعدّلونها.",
|
||||
"connected": "التحديثات الفورية تعمل. سترى التغييرات المباشرة عندما تنجز أنت أو أعضاء دائرتك المهام أو تتخطّونها أو تعدّلونها.",
|
||||
"connecting": "جارٍ الاتصال بالتحديثات الفورية…",
|
||||
"errored": "التحديثات الفورية مفعّلة لكنها لا تعمل: {{error}}",
|
||||
"notConnected": "التحديثات الفورية مفعّلة لكن لا يوجد اتصال حاليًا.",
|
||||
"basicPlanNotice": "التحديثات الفورية غير متاحة في الخطة الأساسية. رقِّ إلى Plus لتلقّي إشعارات فورية عندما تنجز أنت أو أعضاء دائرتك المهام أو تتخطّونها أو تعدّلونها."
|
||||
}
|
||||
},
|
||||
"subscription": {
|
||||
"sessionFailed": "Failed to create subscription session",
|
||||
"errorTitle": "Subscription Error",
|
||||
"errorMessage": "Failed to start subscription process. Please try again.",
|
||||
"subscribe": "Subscribe",
|
||||
"cancelAnytime": "Cancel anytime. No hidden fees. Secure payment powered by Stripe."
|
||||
},
|
||||
"childUsers": {
|
||||
"errNameRequired": "Sub account name is required",
|
||||
"errNameMin": "Sub account name must be at least 2 characters",
|
||||
"errNameMax": "Sub account name must be less than 20 characters",
|
||||
"errNameChars": "Sub account name can only contain lowercase letters, dot and dash",
|
||||
"errPasswordRequired": "Password is required",
|
||||
"errPasswordLength": "Password must be between 8 and 64 characters",
|
||||
"errPasswordMatch": "Passwords do not match",
|
||||
"errDisplayNameMax": "Display name must be less than 50 characters",
|
||||
"createTitle": "Create Sub Account",
|
||||
"createButton": "Create Account",
|
||||
"nameLabel": "Sub Account Name *",
|
||||
"namePlaceholder": "Enter sub account name (e.g., sarah)",
|
||||
"displayNameLabel": "Display Name",
|
||||
"displayNamePlaceholder": "Display name (optional, defaults to sub account name)",
|
||||
"passwordLabel": "Password *",
|
||||
"passwordPlaceholder": "Enter password (8-64 characters)",
|
||||
"confirmPasswordLabel": "Confirm Password *",
|
||||
"confirmPasswordPlaceholder": "Confirm password"
|
||||
},
|
||||
"passwordChange": {
|
||||
"minLength": "Password must be at least 8 characters",
|
||||
"maxLength": "Password must be less than 64 characters"
|
||||
},
|
||||
"payment": {
|
||||
"cancelledTitle": "Payment has been cancelled",
|
||||
"cancelledRedirect": "You will be redirected to the main page shortly.",
|
||||
"successTitle": "Payment Successful!",
|
||||
"successRedirect": "You will be redirected to the settings page shortly."
|
||||
},
|
||||
"developer": {
|
||||
"tokenRefreshed": "Token refreshed successfully",
|
||||
"endpointCalled": "Refresh token endpoint called successfully",
|
||||
"clearDbCleared": "Local offline database cleared. Starting full sync...",
|
||||
"clearDbDone": "Full sync completed from the beginning",
|
||||
"intro": "View technical information about your authentication tokens and session",
|
||||
"refreshCookieNote": "Refresh tokens are managed via HTTP-only cookies on web platform",
|
||||
"noReconnectInfo": "No reconnection information available",
|
||||
"noTimeoutInfo": "No timeout information available",
|
||||
"noDebugInfo": "No debug information available"
|
||||
},
|
||||
"backup": {
|
||||
"keyRequired": "Encryption key is required",
|
||||
"created": "Backup created and downloaded successfully",
|
||||
"createFailed": "Failed to create backup",
|
||||
"selectFile": "Please select a backup file",
|
||||
"restored": "Backup restored successfully. Please refresh the page.",
|
||||
"restoreFailed": "Failed to restore backup",
|
||||
"readFailed": "Failed to read backup file",
|
||||
"createIntro": "Create an encrypted backup of your data. This backup will include all your chores, history, settings, and optionally your uploaded files.",
|
||||
"keyPlaceholder": "Enter a strong encryption key",
|
||||
"includeAssets": "Include uploaded files and assets",
|
||||
"warningLabel": "Warning:",
|
||||
"restoreWarning": "Restoring a backup will replace all your current data. This action cannot be undone.",
|
||||
"restoreKeyPlaceholder": "Enter the encryption key used for this backup"
|
||||
},
|
||||
"deletion": {
|
||||
"passwordRequired": "Please enter your password to continue",
|
||||
"passwordAndDelete": "Please enter your password and type DELETE to confirm",
|
||||
"failed": "Failed to delete account",
|
||||
"passwordPlaceholder": "Enter your password",
|
||||
"transferIntro": "You own circles that require ownership transfer before deletion. Please select new owners:",
|
||||
"selectOwner": "Select new owner",
|
||||
"confirmPrompt": "Please enter your password and type DELETE to confirm",
|
||||
"typeDelete": "DELETE"
|
||||
}
|
||||
}
|
||||
|
||||
18
public/locales/ar/things.json
Normal file
18
public/locales/ar/things.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"errName": "Name is required",
|
||||
"errStateNumber": "State must be a number",
|
||||
"errStateBool": "State must be true or false",
|
||||
"errStateRequired": "State is required",
|
||||
"name": "Name",
|
||||
"namePlaceholder": "Thing name",
|
||||
"value": "Value",
|
||||
"valuePlaceholder": "Thing value",
|
||||
"updateState": "Update state",
|
||||
"update": "Update",
|
||||
"history": {
|
||||
"overview": "Things Overview",
|
||||
"visualization": "Data Visualization",
|
||||
"changeHistory": "Change History",
|
||||
"updated": "Updated"
|
||||
}
|
||||
}
|
||||
29
public/locales/ar/timer.json
Normal file
29
public/locales/ar/timer.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"toast": {
|
||||
"sessionUpdatedTitle": "Session updated",
|
||||
"sessionUpdatedMessage": "Timer session has been updated successfully.",
|
||||
"sessionUpdateFailTitle": "Failed to update session",
|
||||
"tryAgain": "Please try again.",
|
||||
"sessionUpdateErrorTitle": "Error updating session",
|
||||
"sessionDeletedTitle": "Session deleted",
|
||||
"sessionDeletedMessage": "Timer session has been deleted successfully.",
|
||||
"sessionDeleteErrorTitle": "Error deleting session",
|
||||
"deleteConfirmTitle": "Delete Timer Session",
|
||||
"deleteConfirmMessage": "Are you sure you want to delete this timer session?"
|
||||
},
|
||||
"loading": "Loading timer data...",
|
||||
"noData": "No timer data found for this chore.",
|
||||
"activeWork": "Active Work",
|
||||
"breakTime": "Break Time",
|
||||
"workSessions": "Work Sessions",
|
||||
"totalTime": "Total Time",
|
||||
"distribution": "Work vs Break Distribution",
|
||||
"noActiveTime": "No active time yet",
|
||||
"sessionBreakdown": "Session Breakdown",
|
||||
"sessions": "Sessions",
|
||||
"addSession": "Add Session",
|
||||
"startTime": "Start Time",
|
||||
"endTime": "End Time",
|
||||
"leaveEmpty": "Leave empty if session is ongoing",
|
||||
"noSessionForChore": "No timer session found for this chore."
|
||||
}
|
||||
111
public/locales/de/auth.json
Normal file
111
public/locales/de/auth.json
Normal file
@@ -0,0 +1,111 @@
|
||||
{
|
||||
"validationError": "Validation Error",
|
||||
"primaryUsernameRequired": "Primary username is required for sub account login",
|
||||
"subNameRequired": "Sub account name is required for sub account login",
|
||||
"usernameRequired": "Username is required",
|
||||
"passwordRequired": "Password is required",
|
||||
"loginFailed": "Login Failed",
|
||||
"genericError": "An error occurred, please try again",
|
||||
"providerLoginFailed": "{{provider}} Login Failed",
|
||||
"providerLoginFailedMsg": "Couldn't log in with {{provider}}, please try again",
|
||||
"providerLoginError": "{{provider}} Login Error",
|
||||
"networkError": "Network error occurred, please try again",
|
||||
"mfaFailed": "Two-Factor Authentication Failed",
|
||||
"oauthError": "OAuth Error",
|
||||
"oauthBrowserFailed": "Failed to open authentication browser",
|
||||
"primaryAccount": "Primary Account",
|
||||
"subAccount": "Sub Account",
|
||||
"username": "Username",
|
||||
"primaryUsernamePlaceholder": "Enter primary account username",
|
||||
"subNamePlaceholder": "Enter sub account name",
|
||||
"forgotPassword": "Forgot password?",
|
||||
"or": "or",
|
||||
"email": "Email",
|
||||
"displayNamePlaceholder": "How others see your name",
|
||||
"signupFailed": "Signup Failed",
|
||||
"signupDisabled": "Signup disabled, please contact admin",
|
||||
"usernameMinLength": "Username must be at least 4 characters",
|
||||
"invalidEmail": "Invalid email address",
|
||||
"passwordLength": "Password must be between 8 and 64 characters",
|
||||
"displayNameRequired": "Display name is required",
|
||||
"displayNameChars": "Display name can only contain letters and numbers",
|
||||
"resetEmailSent": "Reset Email Sent",
|
||||
"resetEmailSentMsg": "Check your email for password reset instructions",
|
||||
"resetFailed": "Reset Failed",
|
||||
"resetFailedMsg": "Failed to send reset email, please try again later",
|
||||
"emailPlaceholder": "you@example.com",
|
||||
"passwordUpdated": "Password Updated",
|
||||
"passwordUpdatedMsg": "Your password has been updated successfully. Redirecting to login...",
|
||||
"passwordUpdateFailed": "Password Update Failed",
|
||||
"passwordUpdateFailedMsg": "Failed to update password, please try again later",
|
||||
"savePassword": "Save password",
|
||||
"server": {
|
||||
"url": "Server URL",
|
||||
"dnsFailed": "Hostname could not be resolved. Check the URL for typos or verify DNS.",
|
||||
"unreachable": "Unable to reach the server. Check the URL, port, and network connection.",
|
||||
"invalidUrl": "Invalid URL format. Include the protocol (http:// or https://) and port if needed."
|
||||
},
|
||||
"mfaModal": {
|
||||
"title": "Two-factor authentication",
|
||||
"codeRequired": "Please enter a verification code",
|
||||
"verifyFailed": "Failed to verify code. Please try again.",
|
||||
"backupHint": "Enter one of the backup codes you saved when setting up two-factor authentication.",
|
||||
"codeHint": "Enter the 6-digit code from your authenticator app.",
|
||||
"verify": "Verify & Sign In",
|
||||
"backupLabel": "Backup code",
|
||||
"codeLabel": "Verification code",
|
||||
"backupPlaceholder": "Enter backup code",
|
||||
"useAuthenticator": "Use authenticator app instead",
|
||||
"useBackup": "Use a backup code instead",
|
||||
"backupOnce": "Each backup code can only be used once.",
|
||||
"invalidCode": "Invalid verification code. Please try again."
|
||||
},
|
||||
"appleLoginFailed": "Apple Login Failed",
|
||||
"googleLoginFailed": "Google Login Failed",
|
||||
"createOne": "Create one",
|
||||
"primaryAccountUsernameLabel": "Primary account username",
|
||||
"subAccountNameLabel": "Sub account name",
|
||||
"serverSettings": "Server settings",
|
||||
"useDifferentAccount": "Use a different account",
|
||||
"yourUsername": "Your username",
|
||||
"backToSignIn": "Back to sign in",
|
||||
"confirmNewPassword": "Confirm new password",
|
||||
"newPassword": "New password",
|
||||
"reenterPassword": "Re-enter your password",
|
||||
"requestNewLink": "Request a new link",
|
||||
"setNewPassword": "Set a new password",
|
||||
"linkInvalid": "This link is not valid",
|
||||
"createAccountButton": "Create account",
|
||||
"createYourAccount": "Create your account",
|
||||
"displayNameLabel": "Display name",
|
||||
"usernameHint": "lowercase letters, numbers, dot and dash",
|
||||
"termsShort": "By creating an account you agree to our Terms of Service and Privacy",
|
||||
"checkYourEmail": "Check your email",
|
||||
"resetYourPassword": "Reset your password",
|
||||
"serverChangeWarning": "Changing the server clears locally cached data on this device.",
|
||||
"serverConnected": "Connected. Taking you to sign in...",
|
||||
"passwordLabel": "Password",
|
||||
"showPassword": "Show password",
|
||||
"hidePassword": "Hide password",
|
||||
"loginPasswordPlaceholder": "Enter your password",
|
||||
"signupPasswordPlaceholder": "At least 8 characters",
|
||||
"signupPasswordHelper": "Use 8 to 64 characters.",
|
||||
"orContinueWith": "or continue with",
|
||||
"signupSignInFailed": "Your account was created, but signing in failed. Please sign in.",
|
||||
"authenticating": {
|
||||
"signingIn": "Signing you in",
|
||||
"signingInSub": "This will only take a moment.",
|
||||
"unknownProvider": "Unknown sign-in provider",
|
||||
"contactSupport": "Please contact support.",
|
||||
"signInFailed": "Sign-in failed",
|
||||
"mfaCancelled": "Two-factor authentication was cancelled.",
|
||||
"requestNotVerified": "The sign-in request could not be verified.",
|
||||
"tryAgain": "Please try again.",
|
||||
"mfaSessionMissing": "The MFA session is missing. Please try again.",
|
||||
"twoFactor": "Two-factor authentication",
|
||||
"verifyToContinue": "Verify your login to continue.",
|
||||
"noToken": "No valid authentication token was returned.",
|
||||
"backToSignIn": "Back to sign in",
|
||||
"mfaFailed": "Two-factor authentication failed. Please try again."
|
||||
}
|
||||
}
|
||||
@@ -71,5 +71,11 @@
|
||||
"reset": "Timer zurücksetzen",
|
||||
"delete": "Sitzung löschen"
|
||||
}
|
||||
},
|
||||
"toolbar": {
|
||||
"defaultProject": "Default Project"
|
||||
},
|
||||
"sort": {
|
||||
"assignedToMe": "Assigned to me"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
"logout": "Abmelden",
|
||||
"version": "Version",
|
||||
"navigation": {
|
||||
"search": "Suche",
|
||||
"allTasks": "Alle Aufgaben",
|
||||
"archived": "Archiviert",
|
||||
"things": "Dinge",
|
||||
@@ -28,6 +29,123 @@
|
||||
"filters": "Filter",
|
||||
"activities": "Aktivitäten",
|
||||
"points": "Punkte",
|
||||
"settings": "Einstellungen"
|
||||
"settings": "Einstellungen",
|
||||
"reportBug": "Report a Bug"
|
||||
},
|
||||
"search": {
|
||||
"title": "Suche",
|
||||
"placeholder": "Donetick durchsuchen",
|
||||
"inputAriaLabel": "Aufgaben, Verlauf, Projekte, Beschriftungen und Einstellungen durchsuchen",
|
||||
"deviceNote": "Es wird in Inhalten gesucht, die auf diesem Gerät verfügbar sind",
|
||||
"escape": "Esc",
|
||||
"recent": "Zuletzt verwendet",
|
||||
"empty": {
|
||||
"title": "Keine direkten Treffer",
|
||||
"subtitle": "Du kannst die Aufgabenliste trotzdem mit dieser Suche filtern."
|
||||
},
|
||||
"groups": {
|
||||
"tasks": "Aufgaben",
|
||||
"history": "Notizen",
|
||||
"projects": "Projekte",
|
||||
"labels": "Beschriftungen",
|
||||
"people": "Personen",
|
||||
"settings": "Einstellungen",
|
||||
"actions": "Schnellaktionen"
|
||||
},
|
||||
"actions": {
|
||||
"quickAction": "Schnellaktion",
|
||||
"navigation": "Navigation",
|
||||
"createTask": "Aufgabe erstellen",
|
||||
"viewAllTasks": "Alle Aufgaben anzeigen",
|
||||
"viewArchivedTasks": "Archivierte Aufgaben anzeigen",
|
||||
"openSettings": "Einstellungen öffnen",
|
||||
"filterTasks": "Aufgaben anzeigen, die zu „{{query}}“ passen",
|
||||
"filterTasksSubtitle": "Aufgabenliste filtern"
|
||||
},
|
||||
"footer": {
|
||||
"navigate": "Navigieren",
|
||||
"open": "Öffnen",
|
||||
"results_one": "{{count}} Ergebnis",
|
||||
"results_other": "{{count}} Ergebnisse",
|
||||
"typeToSearch": "Zum Suchen tippen"
|
||||
}
|
||||
},
|
||||
"feedback": {
|
||||
"later": "Vielleicht später",
|
||||
"sentiment": {
|
||||
"title": "Was hältst du von Donetick?",
|
||||
"subtitle": "Ihre Antwort hilft uns zu entscheiden, was wir als Nächstes entwickeln sollen.",
|
||||
"options": {
|
||||
"love": "Ich liebe es",
|
||||
"okay": "Es ist in Ordnung",
|
||||
"issues": "Ich habe Probleme"
|
||||
}
|
||||
},
|
||||
"categories": {
|
||||
"bugs": "Fehler",
|
||||
"missingFeature": "Fehlende Funktion",
|
||||
"tooComplicated": "Zu kompliziert",
|
||||
"slow": "Langsam",
|
||||
"notifications": "Benachrichtigungen",
|
||||
"ai": "KI",
|
||||
"other": "Sonstiges"
|
||||
},
|
||||
"details": {
|
||||
"title": "Was könnten wir verbessern?",
|
||||
"messageLabel": "Weiteres Feedback",
|
||||
"messagePlaceholder": "Was ist passiert oder was können wir verbessern?",
|
||||
"contextNote": "Wir werden folgende Diagnosedaten einschließen, um Probleme reproduzieren zu können: App-Version, Gerätebeschreibung und Betriebssystem.",
|
||||
"submit": "Feedback senden",
|
||||
"contextNoteSelfHosted": "Du befindest dich auf einem selbst-gehosteten Instanz, daher wird keine Meldung von deinem Server erstellt. Wir eröffnen ein Github-Problem welches vorausgefüllt ist. Du selbst kannst es prüfen und bearbeiten bevor es erstellt wird.",
|
||||
"submitSelfHosted": "Weiter zu GitHub"
|
||||
},
|
||||
"review": {
|
||||
"title": "Schön, dass es Ihnen gefällt!",
|
||||
"subtitle": "Eine Bewertung oder ein Stern hilft anderen Menschen Donetich zu finden.",
|
||||
"github": "Als GitHub Favorit setzen",
|
||||
"appStore": "Im App Store bewerten",
|
||||
"playStore": "Auf Google Play bewerten"
|
||||
},
|
||||
"thanks": {
|
||||
"title": "Vielen Dank für Ihr Feedback!",
|
||||
"subtitle": "Wir lesen jede Antwort und diese entscheiden was wir als Nächstes tun."
|
||||
},
|
||||
"github": {
|
||||
"title": "Melde es auf GitHub,",
|
||||
"subtitle": "Wir haben ein Problem mit Ihren Notizen und Versionsdetails vorausgefüllt. Es wurde noch nichts verschickt – überprüfe es und poste, sobald du bereit bist.",
|
||||
"open": "Eröffne das Problem"
|
||||
}
|
||||
},
|
||||
"done": "Done",
|
||||
"clearAll": "Clear all",
|
||||
"upload": {
|
||||
"quotaTitle": "Storage Quota Exceeded",
|
||||
"quotaMessage": "You have exceeded your quota for uploading files.",
|
||||
"tooLargeTitle": "File Too Large",
|
||||
"tooLargeMessage": "The file you are trying to upload is too large.",
|
||||
"deniedTitle": "Permission Denied",
|
||||
"deniedMessage": "You do not have permission to upload files."
|
||||
},
|
||||
"getStarted": "Get Started!",
|
||||
"imageLoadFailed": "Failed to load image.",
|
||||
"typeHere": "Type in here…",
|
||||
"summaryOfChores": "This is a summary of your chores",
|
||||
"loadingOffline": "You are offline",
|
||||
"loadingOfflineSub": "This not available while offline. Please check your internet connection and try again.",
|
||||
"loadingSlow": "This is taking longer than usual. There might be an issue.",
|
||||
"navigateBack": "Navigate Back",
|
||||
"bottomNav": "Bottom Navigation",
|
||||
"profile": "Profile",
|
||||
"autocompletePlaceholder": "Type here...",
|
||||
"errorScreen": {
|
||||
"title": "Something went wrong",
|
||||
"fallback": "An unexpected error occurred. Try reloading — it usually fixes it.",
|
||||
"tryAgain": "Try again",
|
||||
"home": "Home",
|
||||
"login": "Login",
|
||||
"hideDetails": "Hide error details",
|
||||
"showDetails": "Show error details",
|
||||
"copyToClipboard": "Copy to clipboard",
|
||||
"copied": "Error details copied to clipboard"
|
||||
}
|
||||
}
|
||||
|
||||
17
public/locales/de/filters.json
Normal file
17
public/locales/de/filters.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"builder": {
|
||||
"errorName": "Please enter a filter name",
|
||||
"errorConditions": "Please configure at least one filter condition",
|
||||
"editTitle": "Edit Filter",
|
||||
"newTitle": "New Filter",
|
||||
"addConditions": "Add conditions to preview",
|
||||
"save": "Save Filter",
|
||||
"name": "Filter Name",
|
||||
"namePlaceholder": "e.g. Overdue tasks for Alice",
|
||||
"color": "Color"
|
||||
},
|
||||
"nameExists": "A filter with this name already exists",
|
||||
"tasks_one": "{{count}} task",
|
||||
"tasks_other": "{{count}} tasks",
|
||||
"overdue": "{{count}} overdue"
|
||||
}
|
||||
89
public/locales/de/history.json
Normal file
89
public/locales/de/history.json
Normal file
@@ -0,0 +1,89 @@
|
||||
{
|
||||
"edit": {
|
||||
"title": "Edit History",
|
||||
"completedDate": "Completed Date",
|
||||
"note": "Note",
|
||||
"additionalNotes": "Additional Notes",
|
||||
"deleteTitle": "Delete History",
|
||||
"deleteMessage": "Are you sure you want to delete this history?"
|
||||
},
|
||||
"status": {
|
||||
"inProgress": "In Progress",
|
||||
"completed": "Completed",
|
||||
"skipped": "Skipped",
|
||||
"pendingApproval": "Pending Approval",
|
||||
"rejected": "Rejected",
|
||||
"missed": "Missed",
|
||||
"rescheduled": "Rescheduled",
|
||||
"scheduled": "Scheduled"
|
||||
},
|
||||
"badge": {
|
||||
"onTime": "On Time",
|
||||
"onTimeLabel": "On time"
|
||||
},
|
||||
"detail": {
|
||||
"title": "Activity Detail",
|
||||
"openTask": "Open Task",
|
||||
"editEntry": "Edit Entry",
|
||||
"performedBy": "Performed by",
|
||||
"assignedTo": "Assigned to",
|
||||
"lastUpdated": "Last updated",
|
||||
"duration": "Duration",
|
||||
"pointsEarned": "Points earned",
|
||||
"points_one": "{{count}} pt",
|
||||
"points_other": "{{count}} pts",
|
||||
"note": "Note"
|
||||
},
|
||||
"charts": {
|
||||
"noData": "No data available",
|
||||
"noLabels": "No Labels",
|
||||
"unassigned": "Unassigned",
|
||||
"unknownTask": "Unknown Task",
|
||||
"late": "Late",
|
||||
"status": {
|
||||
"title": "Status",
|
||||
"description": "Completed tasks status"
|
||||
},
|
||||
"due": {
|
||||
"title": "Due Date",
|
||||
"description": "Current tasks due date"
|
||||
},
|
||||
"priority": {
|
||||
"title": "Priority",
|
||||
"description": "Tasks by priority"
|
||||
},
|
||||
"labels": {
|
||||
"title": "Labels",
|
||||
"description": "Tasks by labels"
|
||||
},
|
||||
"labelsDuration": {
|
||||
"title": "Labels (time)",
|
||||
"description": "Time spent by labels (hours)"
|
||||
},
|
||||
"tasksTime": {
|
||||
"title": "Tasks (time)",
|
||||
"description": "Time spent by individual tasks (hours)"
|
||||
},
|
||||
"assigneeBreakdown": {
|
||||
"title": "by Assignee",
|
||||
"description": "Tasks grouped by assignee"
|
||||
}
|
||||
},
|
||||
"filter": {
|
||||
"status": "Status",
|
||||
"pending": "Pending",
|
||||
"labels": "Labels",
|
||||
"hasNotes": "Has Notes",
|
||||
"hasPoints": "Has Points",
|
||||
"timePeriod": "Time Period",
|
||||
"user": "User"
|
||||
},
|
||||
"period": {
|
||||
"days_one": "{{count}} Day",
|
||||
"days_other": "{{count}} Days",
|
||||
"allTime": "All Time"
|
||||
},
|
||||
"activities": {
|
||||
"title": "Activities"
|
||||
}
|
||||
}
|
||||
9
public/locales/de/labels.json
Normal file
9
public/locales/de/labels.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"shared": "Shared",
|
||||
"delete": {
|
||||
"title": "Delete Label",
|
||||
"message": "Are you sure you want to delete this label? This will remove the label from all tasks."
|
||||
},
|
||||
"loadError": "Failed to load labels. Please try again.",
|
||||
"blurb": "Manage your labels and organize your tasks effectively. Labels will be automatically shared with your circle if they are used on a shared task."
|
||||
}
|
||||
74
public/locales/de/points.json
Normal file
74
public/locales/de/points.json
Normal file
@@ -0,0 +1,74 @@
|
||||
{
|
||||
"redeem": "Redeem Points",
|
||||
"redeemModal": {
|
||||
"redeemButton": "Redeem",
|
||||
"pointsAvailable": "{{count}} points available",
|
||||
"pointsToRedeem": "Points to Redeem",
|
||||
"placeholder": "Enter points...",
|
||||
"cannotExceed": "Cannot exceed available points",
|
||||
"quickAdd": "Quick Add:",
|
||||
"aboutToRedeem": "You are about to redeem",
|
||||
"amount": "{{count}} points",
|
||||
"remaining": "Remaining: {{count}} points"
|
||||
},
|
||||
"leaderboard": {
|
||||
"titlePoints": "Points Leaderboard",
|
||||
"titleTasks": "Tasks Leaderboard",
|
||||
"subtitlePoints": "Rankings based on points earned during the selected time period",
|
||||
"subtitleTasks": "Rankings based on tasks completed during the selected time period",
|
||||
"modePoints": "Points",
|
||||
"modeTasks": "Tasks",
|
||||
"you": "You",
|
||||
"tasksAndAvg": "{{tasks}} tasks • {{avg}} avg per task",
|
||||
"available": "{{count}} available",
|
||||
"points_one": "{{count}} point",
|
||||
"points_other": "{{count}} points"
|
||||
},
|
||||
"tabs": {
|
||||
"short7d": "7D",
|
||||
"short6m": "6M",
|
||||
"shortAll": "All",
|
||||
"days7": "7 Days",
|
||||
"months6": "6 Months",
|
||||
"allTime": "All Time"
|
||||
},
|
||||
"filter": {
|
||||
"analysisTitle": "Filter & Analysis",
|
||||
"title": "Filter Points",
|
||||
"showFor": "Show points for:",
|
||||
"timePeriod": "Time period:"
|
||||
},
|
||||
"cards": {
|
||||
"available": {
|
||||
"title": "Available",
|
||||
"subtext": "Ready to redeem"
|
||||
},
|
||||
"redeemed": {
|
||||
"title": "Redeemed",
|
||||
"subtext": "Previously used"
|
||||
},
|
||||
"total": {
|
||||
"title": "Total",
|
||||
"subtext": "All time earned"
|
||||
},
|
||||
"period": {
|
||||
"title": "Period Points",
|
||||
"allTime": "All time",
|
||||
"last6Months": "Last 6 months",
|
||||
"lastDays_one": "Last {{count}} day",
|
||||
"lastDays_other": "Last {{count}} days"
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"showingFor": "Showing points for",
|
||||
"unknownUser": "Unknown User",
|
||||
"overThe": "over the",
|
||||
"allTime": "All Time",
|
||||
"last6Months": "Last 6 Months",
|
||||
"lastDays_one": "Last {{count}} Day",
|
||||
"lastDays_other": "Last {{count}} Days"
|
||||
},
|
||||
"trend": {
|
||||
"title": "Points Trend"
|
||||
}
|
||||
}
|
||||
24
public/locales/de/projects.json
Normal file
24
public/locales/de/projects.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"iconPicker": {
|
||||
"chooseIcon": "Choose Project Icon",
|
||||
"availableIcons": "Available Icons"
|
||||
},
|
||||
"defaultChip": "Default",
|
||||
"tasks_one": "{{count}} task",
|
||||
"tasks_other": "{{count}} tasks",
|
||||
"shared": "Shared",
|
||||
"delete": {
|
||||
"title": "Delete Project",
|
||||
"message": "Are you sure you want to delete \"{{name}}\"? This will remove the project but keep all tasks (they'll move to the Default Project)."
|
||||
},
|
||||
"loadError": "Failed to load projects. Please try again.",
|
||||
"blurb": "Organize your tasks into projects. Create custom workspaces to keep your tasks organized and easily accessible.",
|
||||
"defaultDescription": "All tasks without a specific project",
|
||||
"selector": {
|
||||
"title": "Projects",
|
||||
"createNew": "Create New Project",
|
||||
"createNewDescription": "Add a custom project workspace",
|
||||
"manage": "Manage Projects",
|
||||
"manageDescription": "View, edit, and organize all projects"
|
||||
}
|
||||
}
|
||||
@@ -1,100 +1,110 @@
|
||||
{
|
||||
"title": "Einstellungen",
|
||||
"circleSettings": {
|
||||
"title": "Kreis-Einstellungen",
|
||||
"description": "Dein Account wird automatisch mit einem Kreis verbunden, wenn du einen erstellst oder beitrittst. Lade einfach Freunde ein, indem du den einzigartigen Kreis-Code oder Link unten teilst. Du erhältst eine Benachrichtigung, wenn jemand deinem Kreis beitreten möchte. Wenn du gehen möchtest, klicke einfach auf 'Kreis verlassen'.",
|
||||
"circleCode": "Kreis-Code",
|
||||
"copyCode": "Code kopieren",
|
||||
"copyLink": "Link kopieren",
|
||||
"codeCopied": "Kreis-Code kopiert!",
|
||||
"linkCopied": "Kreis-Link kopiert!",
|
||||
"joinCircle": "Einem Kreis beitreten",
|
||||
"joinCirclePlaceholder": "Kreis-Code eingeben",
|
||||
"join": "Beitreten",
|
||||
"leave": "Kreis verlassen",
|
||||
"leaveConfirmTitle": "Kreis verlassen",
|
||||
"leaveConfirmMessage": "Bist du sicher, dass du diesen Kreis verlassen möchtest?",
|
||||
"circleMembers": "Kreis-Mitglieder",
|
||||
"circleMemberRequests": "Kreis-Beitrittsanfragen",
|
||||
"admin": "Administrator",
|
||||
"member": "Mitglied",
|
||||
"pending": "Ausstehend",
|
||||
"accept": "Akzeptieren",
|
||||
"reject": "Ablehnen",
|
||||
"makeAdmin": "Zum Administrator machen",
|
||||
"makeMember": "Zum Mitglied machen",
|
||||
"common": {
|
||||
"save": "Speichern",
|
||||
"cancel": "Abbrechen",
|
||||
"confirm": "Bestätigen",
|
||||
"remove": "Entfernen",
|
||||
"webhookURL": "Webhook-URL",
|
||||
"webhookDescription": "Gib eine Webhook-URL ein, um Benachrichtigungen für Kreis-Ereignisse zu erhalten",
|
||||
"webhookPlaceholder": "https://deine-webhook-url.com"
|
||||
"delete": "Löschen",
|
||||
"refresh": "Aktualisieren",
|
||||
"loading": "Wird geladen …",
|
||||
"on": "An",
|
||||
"off": "Aus",
|
||||
"error": "Fehler",
|
||||
"success": "Erfolg",
|
||||
"plusFeature": "Plus-Funktion",
|
||||
"earlyAccess": "Early Access"
|
||||
},
|
||||
"accountSettings": {
|
||||
"title": "Account-Einstellungen",
|
||||
"subscription": "Abonnement",
|
||||
"subscriptionStatus": "Aktueller Plan",
|
||||
"free": "Kostenlos",
|
||||
"plus": "Plus",
|
||||
"upgrade": "Upgraden",
|
||||
"cancel": "Kündigen",
|
||||
"changePassword": "Passwort ändern",
|
||||
"password": "Passwort",
|
||||
"dangerZone": "Gefahrenbereich",
|
||||
"dangerZoneDescription": "Sobald du dein Konto löschst, gibt es kein Zurück mehr. Bitte sei dir sicher.",
|
||||
"deleteAccount": "Account löschen"
|
||||
},
|
||||
"localization": {
|
||||
"title": "Sprach- und Formateinstellungen",
|
||||
"description": "Passe Sprache, Datumsformat und regionale Einstellungen für dein Konto an.",
|
||||
"language": "Sprache",
|
||||
"languageDescription": "Wähle deine bevorzugte Sprache",
|
||||
"dateFormat": "Datumsformat",
|
||||
"dateFormatDescription": "Wähle, wie Daten in der gesamten Anwendung angezeigt werden sollen",
|
||||
"timeFormat": "Zeitformat",
|
||||
"timeFormatDescription": "Wähle 12-Stunden- oder 24-Stunden-Zeitformat",
|
||||
"12hour": "12-Stunden (AM/PM)",
|
||||
"24hour": "24-Stunden",
|
||||
"firstDayOfWeek": "Erster Tag der Woche",
|
||||
"firstDayOfWeekDescription": "Wähle, welcher Tag deine Woche beginnt",
|
||||
"sunday": "Sonntag",
|
||||
"monday": "Montag",
|
||||
"saturday": "Samstag",
|
||||
"formats": {
|
||||
"mdy": "MM/TT/JJJJ (USA)",
|
||||
"dmy": "TT/MM/JJJJ (Europa)",
|
||||
"ymd": "JJJJ-MM-TT (ISO)",
|
||||
"long": "Langes Format (z.B. 1. Januar 2024)",
|
||||
"short": "Kurzes Format (z.B. 1. Jan 2024)"
|
||||
"overview": {
|
||||
"title": "Einstellungen",
|
||||
"subtitle": "Passe deine Erfahrung an und verwalte deine Kontoeinstellungen",
|
||||
"upgrade": {
|
||||
"title": "Auf Plus upgraden",
|
||||
"description": "Schalte leistungsstarke Funktionen frei und steigere deine Produktivität",
|
||||
"button": "Jetzt upgraden",
|
||||
"features": {
|
||||
"richText": "Rich-Text-Beschreibungen",
|
||||
"notifications": "Aufgabenbenachrichtigungen",
|
||||
"apiIntegrations": "API-Integrationen",
|
||||
"advancedAutomation": "Erweiterte Automatisierung"
|
||||
}
|
||||
},
|
||||
"sections": {
|
||||
"profile": {
|
||||
"title": "Profileinstellungen",
|
||||
"description": "Aktualisiere deine Profildaten, dein Foto, deinen Anzeigenamen und deine Zeitzone."
|
||||
},
|
||||
"circle": {
|
||||
"title": "Circle-Einstellungen",
|
||||
"description": "Verwalte deinen Circle, lade Mitglieder ein und bearbeite Beitrittsanfragen."
|
||||
},
|
||||
"account": {
|
||||
"title": "Kontoeinstellungen",
|
||||
"description": "Verwalte dein Abonnement, ändere dein Passwort und lösche dein Konto."
|
||||
},
|
||||
"subaccounts": {
|
||||
"title": "Verwaltete Konten",
|
||||
"description": "Erstelle und verwalte Unterkonten, um sich anzumelden und zugewiesene Aufgaben zu erledigen."
|
||||
},
|
||||
"notifications": {
|
||||
"title": "Benachrichtigungen",
|
||||
"description": "Konfiguriere Push-Benachrichtigungen, E-Mail-Hinweise und Benachrichtigungsziele für Aufgaben."
|
||||
},
|
||||
"mfa": {
|
||||
"title": "Multi-Faktor-Authentifizierung",
|
||||
"description": "Erhöhe deine Sicherheit mit MFA über Authenticator-Apps."
|
||||
},
|
||||
"apitokens": {
|
||||
"title": "API-Token",
|
||||
"description": "Erstelle und verwalte Zugriffstoken für Drittanbieter-Integrationen und API-Zugriff."
|
||||
},
|
||||
"storage": {
|
||||
"title": "Speichereinstellungen",
|
||||
"description": "Sichere und stelle deine Daten wieder her, verwalte lokalen Speicher und Sync-Einstellungen."
|
||||
},
|
||||
"sidepanel": {
|
||||
"title": "Seitenleisten-Anpassung",
|
||||
"description": "Passe Layout und Sichtbarkeit der Karten in der Seitenleiste an."
|
||||
},
|
||||
"theme": {
|
||||
"title": "Design-Einstellungen",
|
||||
"description": "Wähle dein bevorzugtes Design und konfiguriere den Hell-/Dunkelmodus."
|
||||
},
|
||||
"localization": {
|
||||
"title": "Lokalisierung",
|
||||
"description": "Passe Sprache, Datumsformat, Zeitformat und regionale Einstellungen an."
|
||||
},
|
||||
"advanced": {
|
||||
"title": "Erweiterte Einstellungen",
|
||||
"description": "Konfiguriere Webhooks, Echtzeit-Updates und weitere erweiterte Funktionen."
|
||||
},
|
||||
"developer": {
|
||||
"title": "Entwicklereinstellungen",
|
||||
"description": "Sieh dir technische Informationen zu Authentifizierungstoken, SSE-Verbindungen und Debug-Daten an."
|
||||
},
|
||||
"feedback": {
|
||||
"title": "Feedback senden",
|
||||
"description": "Sag uns, wie Donetick für dich funktioniert, oder wünsche dir eine Funktion."
|
||||
},
|
||||
"bugReport": {
|
||||
"title": "Fehler melden",
|
||||
"description": "Etwas funktioniert nicht richtig? Schick uns die Details zusammen mit einer technischen Momentaufnahme."
|
||||
}
|
||||
}
|
||||
},
|
||||
"sidepanel": {
|
||||
"title": "Seitenleisten-Anpassung",
|
||||
"description": "Passe das Layout und die Sichtbarkeit von Karten in der Seitenleiste an. Dieser Bereich ist nur auf großen Bildschirmgeräten wie Tablets und Desktops verfügbar."
|
||||
},
|
||||
"theme": {
|
||||
"title": "Theme-Einstellungen",
|
||||
"description": "Wähle, wie die Seite für dich aussieht. Wähle ein einzelnes Theme oder synchronisiere mit deinem System und wechsle automatisch zwischen Tag- und Nacht-Themes.",
|
||||
"themeMode": "Theme-Modus",
|
||||
"light": "Hell",
|
||||
"dark": "Dunkel",
|
||||
"system": "System"
|
||||
},
|
||||
"notifications": {
|
||||
"settingsSaved": "Einstellungen erfolgreich gespeichert",
|
||||
"settingsSaveFailed": "Speichern der Einstellungen fehlgeschlagen",
|
||||
"invalidWebhook": "Ungültige Webhook-URL"
|
||||
},
|
||||
"profile": {
|
||||
"title": "Profil-Einstellungen",
|
||||
"description": "Aktualisiere deinen Anzeigenamen und dein Profilbild.",
|
||||
"title": "Profileinstellungen",
|
||||
"description": "Aktualisiere deinen Anzeigenamen und dein Profilfoto.",
|
||||
"photoUpdated": "Foto aktualisiert",
|
||||
"photoUpdatedMessage": "Dein Profilbild wurde erfolgreich aktualisiert!",
|
||||
"photoUpdatedMessage": "Dein Profilfoto wurde erfolgreich aktualisiert!",
|
||||
"uploadFailed": "Upload fehlgeschlagen",
|
||||
"uploadFailedMessage": "Das Hochladen deines Fotos ist fehlgeschlagen. Bitte versuche es erneut.",
|
||||
"uploadFailedMessage": "Dein Foto konnte nicht hochgeladen werden. Bitte versuche es erneut.",
|
||||
"profileUpdated": "Profil aktualisiert",
|
||||
"profileUpdatedMessage": "Deine Profilinformationen wurden erfolgreich gespeichert!",
|
||||
"updateFailed": "Update fehlgeschlagen",
|
||||
"updateFailedMessage": "Dein Profil konnte nicht aktualisiert werden. Bitte überprüfe deine Verbindung und versuche es erneut.",
|
||||
"profileUpdatedMessage": "Deine Profildaten wurden erfolgreich gespeichert!",
|
||||
"updateFailed": "Aktualisierung fehlgeschlagen",
|
||||
"updateFailedMessage": "Dein Profil konnte nicht aktualisiert werden. Bitte prüfe deine Verbindung und versuche es erneut.",
|
||||
"changePhoto": "Foto ändern",
|
||||
"editPhoto": "Profilfoto bearbeiten",
|
||||
"displayName": "Anzeigename",
|
||||
"displayNamePlaceholder": "Gib deinen Anzeigenamen ein",
|
||||
"timezone": "Zeitzone",
|
||||
@@ -102,73 +112,456 @@
|
||||
"save": "Speichern",
|
||||
"cancel": "Abbrechen"
|
||||
},
|
||||
"overview": {
|
||||
"title": "Einstellungen",
|
||||
"subtitle": "Passe deine Erfahrung an und verwalte deine Account-Einstellungen",
|
||||
"upgrade": {
|
||||
"title": "Auf Plus upgraden",
|
||||
"description": "Schalte mächtige Funktionen frei, um deine Produktivität zu steigern",
|
||||
"button": "Jetzt upgraden",
|
||||
"features": {
|
||||
"richText": "Rich-Text-Beschreibungen",
|
||||
"notifications": "Aufgaben-Benachrichtigungen",
|
||||
"apiIntegrations": "API-Integrationen",
|
||||
"advancedAutomation": "Erweiterte Automatisierung"
|
||||
}
|
||||
"circleSettings": {
|
||||
"title": "Circle-Einstellungen",
|
||||
"description": "Dein Konto wird automatisch mit einem Circle verbunden, wenn du einen erstellst oder beitrittst. Lade Freunde ein, indem du den unten stehenden Circle-Code oder Link teilst. Du erhältst unten eine Benachrichtigung, wenn jemand deinem Circle beitreten möchte.",
|
||||
"memberOf": "Du bist Teil von {{name}}",
|
||||
"yourCircleCode": "Dein Circle-Code lautet:",
|
||||
"copyCode": "Code kopieren",
|
||||
"shareInvite": "Einladung teilen",
|
||||
"codeCopied": "Code in die Zwischenablage kopiert",
|
||||
"linkCopied": "Einladungslink in die Zwischenablage kopiert",
|
||||
"myCircle": "meinem Circle",
|
||||
"shareTitle": "Tritt {{name}} auf Donetick bei",
|
||||
"shareText": "Ich möchte dich einladen, {{name}} auf Donetick beizutreten.",
|
||||
"shareDialogTitle": "Circle-Einladung teilen",
|
||||
"leave": "Circle verlassen",
|
||||
"leaveConfirmTitle": "Circle verlassen",
|
||||
"leaveConfirmMessage": "Möchtest du deinen Circle wirklich verlassen?",
|
||||
"leaveConfirmButton": "Verlassen",
|
||||
"leftCircle": "Circle erfolgreich verlassen",
|
||||
"leaveFailed": "Circle konnte nicht verlassen werden",
|
||||
"circleMembers": "Circle-Mitglieder",
|
||||
"you": "(Du)",
|
||||
"pendingApproval": "Warten auf Freigabe",
|
||||
"joinedOn": "Beigetreten am {{date}}",
|
||||
"requestedToJoin": "Beitrittsanfrage {{date}}",
|
||||
"roles": {
|
||||
"member": "Mitglied",
|
||||
"memberDescription": "Ein normales Mitglied des Circles",
|
||||
"manager": "Manager",
|
||||
"managerDescription": "Kann sich als Nutzer ausgeben und in deren Namen handeln",
|
||||
"admin": "Admin",
|
||||
"adminDescription": "Voller Zugriff auf den Circle"
|
||||
},
|
||||
"sections": {
|
||||
"profile": {
|
||||
"title": "Profil-Einstellungen",
|
||||
"description": "Aktualisiere deine Profilinformationen, Foto, Anzeigenamen und Zeitzonen-Einstellungen."
|
||||
"roleUpdateFailed": "Rolle konnte nicht aktualisiert werden",
|
||||
"removeMemberTitle": "Mitglied entfernen",
|
||||
"removeMemberMessage": "Möchtest du {{name}} wirklich aus deinem Circle entfernen?",
|
||||
"memberRemoved": "Mitglied erfolgreich entfernt",
|
||||
"circleMemberRequests": "Beitrittsanfragen",
|
||||
"lastUpdated": "Zuletzt aktualisiert: {{time}}",
|
||||
"refreshing": "Wird aktualisiert …",
|
||||
"refreshFailed": "Beitrittsanfragen konnten nicht aktualisiert werden",
|
||||
"wantsToJoin": "{{name}} möchte deinem Circle beitreten.",
|
||||
"accept": "Annehmen",
|
||||
"acceptRequestTitle": "Beitrittsanfrage annehmen",
|
||||
"acceptRequestMessage": "Möchtest du {{name}} (Benutzername: {{username}}) wirklich in deinen Circle aufnehmen?",
|
||||
"requestAccepted": "Anfrage erfolgreich angenommen",
|
||||
"or": "oder",
|
||||
"joinOtherDescription": "Möchtest du dem Circle einer anderen Person beitreten? Frage nach dem Circle-Code oder Beitrittslink. Gib den Code unten ein, um beizutreten.",
|
||||
"enterCircleCode": "Circle-Code eingeben:",
|
||||
"enterCodePlaceholder": "Code eingeben",
|
||||
"joinCircle": "Circle beitreten",
|
||||
"joinedPending": "Circle erfolgreich beigetreten, warte auf die Bestätigung durch die Circle-Inhaberin oder den Circle-Inhaber.",
|
||||
"alreadyMember": "Du bist bereits Mitglied dieses Circles",
|
||||
"joinFailed": "Beitritt zum Circle fehlgeschlagen"
|
||||
},
|
||||
"accountSettings": {
|
||||
"title": "Kontoeinstellungen",
|
||||
"description": "Ändere deine Kontoeinstellungen, deinen Kontotyp oder dein Passwort",
|
||||
"accountType": "Kontotyp: {{type}}",
|
||||
"free": "Kostenlos",
|
||||
"plus": "Plus",
|
||||
"plusUntil": "Plus (bis {{date}})",
|
||||
"activeDescription": "Du hast derzeit den Plus-Tarif abonniert. Dein Abonnement verlängert sich am {{date}}.",
|
||||
"cancelledDescription": "Du hast dein Abonnement gekündigt. Dein Konto wird am {{date}} auf den kostenlosen Tarif zurückgestuft.",
|
||||
"freeDescription": "Du nutzt derzeit den kostenlosen Tarif. Wechsle zu Plus, um mehr Funktionen freizuschalten.",
|
||||
"upgrade": "Upgraden",
|
||||
"cancel": "Kündigen",
|
||||
"password": "Passwort:",
|
||||
"changePassword": "Passwort ändern",
|
||||
"passwordChanged": "Passwort erfolgreich geändert",
|
||||
"passwordChangeFailed": "Passwortänderung fehlgeschlagen",
|
||||
"dangerZone": "Gefahrenzone",
|
||||
"dangerZoneDescription": "Sobald du dein Konto löschst, gibt es kein Zurück. Bitte sei dir sicher.",
|
||||
"deleteAccount": "Konto löschen",
|
||||
"accountDeleted": "Konto erfolgreich gelöscht",
|
||||
"subscriptionCancelled": "Abonnement gekündigt",
|
||||
"subscriptionCancelFailed": "Abonnement konnte nicht gekündigt werden",
|
||||
"purchase": {
|
||||
"success": "Kauf erfolgreich! Bitte starte die App neu, um die Plus-Funktionen zu nutzen.",
|
||||
"storeConnection": "Verbindungsproblem mit dem Store. Bitte prüfe dein Netzwerk und versuche es erneut.",
|
||||
"notAllowed": "Käufe sind auf diesem Gerät nicht erlaubt. Bitte prüfe deine Geräteeinschränkungen.",
|
||||
"unavailable": "Dieses Abonnement ist nicht verfügbar. Bitte versuche es später erneut.",
|
||||
"alreadyProcessed": "Dieser Kauf wurde bereits verarbeitet. Wenn du glaubst, dass dies ein Fehler ist, wende dich bitte an den Support.",
|
||||
"receiptMissing": "Kaufbeleg fehlt. Bitte versuche den Kauf erneut.",
|
||||
"networkError": "Netzwerkfehler. Bitte prüfe deine Verbindung und versuche es erneut.",
|
||||
"invalidReceipt": "Ungültiger Kaufbeleg. Bitte wende dich an den Support, falls das Problem bestehen bleibt.",
|
||||
"pending": "Die Zahlung wartet auf Freigabe. Du erhältst Zugriff, sobald sie bestätigt ist.",
|
||||
"failed": "Kauf fehlgeschlagen: {{error}}. Bitte versuche es erneut oder wende dich an den Support.",
|
||||
"unknownError": "Unbekannter Fehler"
|
||||
}
|
||||
},
|
||||
"subaccounts": {
|
||||
"title": "Verwaltete Konten",
|
||||
"description": "Verwalte Unterkonten. Nutzerinnen und Nutzer von Unterkonten können sich anmelden und zugewiesene Aufgaben erledigen.",
|
||||
"notParentTitle": "Verwaltung von Unterkonten",
|
||||
"notParentMessage": "Nur Hauptkonten können Unterkonten verwalten.",
|
||||
"freePlanNotice": "Im kostenlosen Tarif ist 1 Unterkonto möglich. Wechsle zu Plus für bis zu 5 Unterkonten.",
|
||||
"count": "Unterkonten ({{count}})",
|
||||
"add": "Unterkonto hinzufügen",
|
||||
"loading": "Unterkonten werden geladen …",
|
||||
"emptyTitle": "Keine Unterkonten",
|
||||
"emptyDescription": "Erstelle Unterkonten, damit Teammitglieder sich anmelden und ihre Aufgaben erledigen können.",
|
||||
"addFirst": "Erstes Unterkonto hinzufügen",
|
||||
"username": "Benutzername: {{username}}",
|
||||
"created": "Erstellt: {{date}}",
|
||||
"changePassword": "Passwort ändern",
|
||||
"deleteAccount": "Konto löschen",
|
||||
"createdSuccess": "Unterkonto „{{name}}“ wurde erfolgreich erstellt!",
|
||||
"createFailed": "Unterkonto konnte nicht erstellt werden: {{error}}",
|
||||
"createFailedGeneric": "Unterkonto konnte nicht erstellt werden",
|
||||
"passwordUpdated": "Passwort des Unterkontos erfolgreich aktualisiert",
|
||||
"passwordUpdateFailed": "Passwort konnte nicht aktualisiert werden: {{error}}",
|
||||
"passwordUpdateFailedGeneric": "Passwort konnte nicht aktualisiert werden",
|
||||
"deleteConfirmTitle": "Unterkonto löschen",
|
||||
"deleteConfirmMessage": "Möchtest du das Unterkonto „{{name}}“ wirklich löschen? Diese Aktion kann nicht rückgängig gemacht werden.",
|
||||
"deleted": "Unterkonto „{{name}}“ erfolgreich gelöscht",
|
||||
"deleteFailed": "Unterkonto konnte nicht gelöscht werden: {{error}}",
|
||||
"deleteFailedGeneric": "Unterkonto konnte nicht gelöscht werden",
|
||||
"howItWorksTitle": "So funktionieren verwaltete Konten",
|
||||
"howItWorks1": "Verwaltete Konten werden vom Hauptkonto erstellt – für Personen, deren Konto du löschen und deren Passwort du zurücksetzen können möchtest.",
|
||||
"howItWorks2": "Unterkonten können sich mit eigenem Benutzernamen und Passwort anmelden.",
|
||||
"howItWorks3": "Verwaltete Konten können Aufgaben erledigen, haben aber eingeschränkte Verwaltungsrechte",
|
||||
"howItWorks4": "Verwaltete Konten werden automatisch deinem Circle hinzugefügt"
|
||||
},
|
||||
"notifications": {
|
||||
"title": "Benachrichtigungseinstellungen",
|
||||
"deviceSection": "Gerätebenachrichtigungen",
|
||||
"deviceSectionDescription": "Verwalte deine Gerätebenachrichtigungen",
|
||||
"deviceLabel": "Gerätebenachrichtigung",
|
||||
"deviceHelper": "Erhalte eine Benachrichtigung auf deinem Gerät, wenn eine Aufgabe fällig ist",
|
||||
"mobileOnly": "Diese Funktion ist nur auf Mobilgeräten verfügbar",
|
||||
"testNotification": "Testbenachrichtigung",
|
||||
"testNotificationBody": "Eine Aufgabe wird bald fällig",
|
||||
"dueTitle": "Benachrichtigung bei Fälligkeit",
|
||||
"dueLabel": "Benachrichtigung, wenn die Aufgabe fällig ist",
|
||||
"preDueTitle": "Benachrichtigung vor Fälligkeit",
|
||||
"preDueLabel": "Benachrichtigung einige Stunden vor Fälligkeit der Aufgabe",
|
||||
"overdueTitle": "Benachrichtigung bei Überfälligkeit",
|
||||
"overdueLabel": "Benachrichtigung, wenn die Aufgabe überfällig ist",
|
||||
"pushLabel": "Push-Benachrichtigungen",
|
||||
"pushHelper": "Erhalte Erinnerungen, Ankündigungen und Aufgabenzuweisungen per Push-Benachrichtigung",
|
||||
"registeredDevices": "Registrierte Geräte ({{count}}/5)",
|
||||
"registeredDevicesDescription": "Geräte, die Push-Benachrichtigungen für dein Konto erhalten",
|
||||
"currentDevice": "Aktuelles Gerät: {{platform}} {{model}}",
|
||||
"currentDeviceNotRegistered": "Dieses Gerät ist nicht für Push-Benachrichtigungen registriert",
|
||||
"limitReached": "Limit erreicht",
|
||||
"registerDevice": "Gerät registrieren",
|
||||
"unknownDevice": "Unbekanntes Gerät",
|
||||
"deviceCreatedAt": "Erstellt am: {{date}}",
|
||||
"noDevices": "Keine Geräte für Push-Benachrichtigungen registriert",
|
||||
"customSection": "Benutzerdefinierte Benachrichtigung",
|
||||
"customSectionDescription": "Benachrichtigung über andere Plattformen wie Telegram oder Pushover",
|
||||
"customLabel": "Benutzerdefinierte Benachrichtigung",
|
||||
"customHelper": "Benachrichtigungen über eine andere Plattform erhalten",
|
||||
"targetNone": "Keine",
|
||||
"targetTelegram": "Telegram",
|
||||
"targetPushover": "Pushover",
|
||||
"targetWebhooks": "Webhooks",
|
||||
"telegramBotHelpBefore": "Du musst dem Bot zuerst eine Nachricht senden, damit die Telegram-Benachrichtigung funktioniert",
|
||||
"telegramBotHelpAfter": "um einen Chat zu starten",
|
||||
"clickHere": "Hier klicken",
|
||||
"chatId": "Chat-ID",
|
||||
"chatIdPlaceholder": "Benutzer-ID / Chat-ID",
|
||||
"telegramChatIdHelpBefore": "Wenn du deine Chat-ID nicht kennst, starte einen Chat mit userinfobot – er sendet dir deine Chat-ID.",
|
||||
"telegramChatIdHelpAfter": "um einen Chat mit userinfobot zu starten",
|
||||
"userKey": "Benutzerschlüssel",
|
||||
"userKeyPlaceholder": "Benutzer-ID",
|
||||
"chatIdRequired": "Chat-ID ist erforderlich",
|
||||
"chatIdInvalid": "Ungültige Chat-ID",
|
||||
"userKeyRequired": "Benutzerschlüssel ist erforderlich",
|
||||
"targetUpdated": "Benachrichtigungsziel aktualisiert",
|
||||
"targetUpdateFailed": "Fehler beim Aktualisieren des Benachrichtigungsziels: {{error}}",
|
||||
"deviceRegistered": "Gerät erfolgreich für Push-Benachrichtigungen registriert.",
|
||||
"deviceLimitTitle": "Gerätelimit erreicht",
|
||||
"deviceLimitMessage": "Du hast das Maximum von 5 registrierten Geräten erreicht. Bitte entferne ein Gerät, bevor du dieses registrierst.",
|
||||
"registrationFailedTitle": "Registrierung fehlgeschlagen",
|
||||
"registrationFailedMessage": "Das Gerät konnte nicht automatisch registriert werden. Bitte versuche es erneut.",
|
||||
"permissionRequiredTitle": "Berechtigung erforderlich",
|
||||
"permissionRequiredMessage": "Für die Registrierung dieses Geräts ist die Berechtigung für Push-Benachrichtigungen erforderlich.",
|
||||
"registrationInitiatedTitle": "Registrierung gestartet",
|
||||
"registrationInitiatedMessage": "Die Registrierung für Push-Benachrichtigungen wurde gestartet. Das Gerät wird automatisch registriert.",
|
||||
"registerDeviceFailed": "Gerät konnte nicht registriert werden. Bitte versuche es erneut.",
|
||||
"permissionDeniedTitle": "Benachrichtigungsberechtigung verweigert",
|
||||
"permissionDeniedMessage": "Du hast Benachrichtigungsberechtigungen verweigert. Du kannst sie später in den Geräteeinstellungen aktivieren.",
|
||||
"pushPermissionDeniedTitle": "Push-Benachrichtigungsberechtigung verweigert",
|
||||
"pushPermissionDeniedMessage": "Push-Benachrichtigungen wurden deaktiviert. Du kannst sie bei Bedarf in den Geräteeinstellungen aktivieren.",
|
||||
"unregisterFailed": "Gerät konnte nicht abgemeldet werden"
|
||||
},
|
||||
"mfa": {
|
||||
"title": "Multi-Faktor-Authentifizierung",
|
||||
"description": "Schütze dein Konto zusätzlich mit Multi-Faktor-Authentifizierung (MFA). Wenn sie aktiviert ist, musst du beim Anmelden neben deinem Passwort einen Bestätigungscode aus deiner Authenticator-App eingeben.",
|
||||
"twoFactor": "Zwei-Faktor-Authentifizierung",
|
||||
"enabledSubtitle": "Dein Konto ist mit 2FA geschützt",
|
||||
"disabledSubtitle": "Sichere dein Konto mit einer Authenticator-App",
|
||||
"enable": "Aktivieren",
|
||||
"disable": "Deaktivieren",
|
||||
"enabledSuccess": "MFA wurde erfolgreich aktiviert!",
|
||||
"disabledSuccess": "MFA wurde erfolgreich deaktiviert!",
|
||||
"errors": {
|
||||
"qrGenerationFailed": "QR-Code konnte nicht erstellt werden",
|
||||
"invalidResponse": "Ungültige Antwort vom Server. QR-Code oder Schlüssel fehlt.",
|
||||
"notFound": "MFA-Einrichtungs-Endpunkt nicht gefunden. Diese Funktion ist möglicherweise noch nicht verfügbar.",
|
||||
"unauthorized": "Nicht autorisiert. Bitte melde dich erneut an.",
|
||||
"serverError": "Serverfehler. Bitte versuche es später erneut.",
|
||||
"setupFailed": "MFA-Einrichtung fehlgeschlagen ({{status}}). Bitte versuche es erneut.",
|
||||
"networkError": "Netzwerkfehler. Bitte prüfe deine Verbindung und versuche es erneut.",
|
||||
"invalidCode": "Ungültiger Bestätigungscode. Bitte versuche es erneut.",
|
||||
"confirmFailed": "MFA konnte nicht bestätigt werden. Bitte versuche es erneut.",
|
||||
"disableFailed": "MFA konnte nicht deaktiviert werden. Bitte versuche es erneut."
|
||||
},
|
||||
"setup": {
|
||||
"title": "Multi-Faktor-Authentifizierung einrichten",
|
||||
"addedAccount": "Ich habe das Konto hinzugefügt",
|
||||
"back": "Zurück",
|
||||
"verifyAndEnable": "Prüfen & aktivieren",
|
||||
"savedBackupCodes": "Ich habe meine Backup-Codes gespeichert",
|
||||
"step1Label": "Schritt 1:",
|
||||
"step1": "Scanne den QR-Code unten mit deiner Authenticator-App (Google Authenticator, Authy usw.)",
|
||||
"qrAlt": "MFA-QR-Code",
|
||||
"qrFailed": "Der QR-Code konnte nicht erstellt werden. Bitte versuche es erneut oder nutze den manuellen Schlüssel unten.",
|
||||
"manualKey": "Manueller Schlüssel:",
|
||||
"step2Label": "Schritt 2:",
|
||||
"step2": "Gib den 6-stelligen Bestätigungscode aus deiner Authenticator-App ein",
|
||||
"codePlaceholder": "6-stelligen Code eingeben",
|
||||
"successTitle": "MFA erfolgreich aktiviert!",
|
||||
"backupCodesTitle": "Bewahre diese Backup-Codes an einem sicheren Ort auf",
|
||||
"backupCodesDescription": "Mit diesen Codes kannst du auf dein Konto zugreifen, falls du dein Authenticator-Gerät verlierst. Jeder Code kann nur einmal verwendet werden."
|
||||
},
|
||||
"disableModal": {
|
||||
"title": "Multi-Faktor-Authentifizierung deaktivieren",
|
||||
"warning": "Das Deaktivieren von MFA macht dein Konto weniger sicher. Möchtest du wirklich fortfahren?",
|
||||
"prompt": "Gib zur Bestätigung einen Bestätigungscode aus deiner Authenticator-App ein:",
|
||||
"confirm": "MFA deaktivieren"
|
||||
},
|
||||
"backupCodesModal": {
|
||||
"title": "Neue Backup-Codes",
|
||||
"warning": "Deine bisherigen Backup-Codes sind jetzt ungültig. Bewahre diese neuen Codes an einem sicheren Ort auf. Jeder Code kann nur einmal verwendet werden."
|
||||
}
|
||||
},
|
||||
"apiTokens": {
|
||||
"title": "API-Token",
|
||||
"accessToken": "Zugriffstoken",
|
||||
"description": "Erstelle ein Token, um über die API Dinge zu aktualisieren, die Aufgaben auslösen",
|
||||
"plusNotice": "API-Token sind im Basis-Tarif nicht verfügbar. Wechsle zu Plus, um API-Token für die Anbindung externer Systeme und die Automatisierung deiner Aufgaben zu erstellen.",
|
||||
"showToken": "Token anzeigen",
|
||||
"hideToken": "Token verbergen",
|
||||
"removeTitle": "Token entfernen",
|
||||
"removeMessage": "Möchtest du {{name}} wirklich entfernen?",
|
||||
"removedTitle": "Entfernt",
|
||||
"removedMessage": "Das API-Token wurde entfernt",
|
||||
"tokenCopied": "Token in die Zwischenablage kopiert",
|
||||
"generateNew": "Neues Token erstellen",
|
||||
"nameModalTitle": "Gib deinem neuen Token einen Namen, an dem du es wiedererkennst.",
|
||||
"generateToken": "Token erstellen"
|
||||
},
|
||||
"storage": {
|
||||
"title": "Speichereinstellungen",
|
||||
"serverTitle": "Serverspeicher-Nutzung",
|
||||
"serverDescription": "Das ist der Speicher, den dein Konto auf unseren Servern belegt (z. B. Dateien, Bilder und hochgeladene Daten).",
|
||||
"usagePlaceholder": "-- MB belegt / -- MB gesamt (--)",
|
||||
"usage": "{{used}} MB belegt / {{total}} MB gesamt ({{percent}} %)",
|
||||
"basicPlanNotice": "Serverspeicher ist im Basis-Tarif nicht verfügbar. Wechsle zu Plus, um deine Serverspeicher-Nutzung zu verfolgen.",
|
||||
"localTitleApp": "Lokaler App-Speicher & Cache",
|
||||
"localTitleBrowser": "Lokaler Browser-Speicher & Cache",
|
||||
"localDescription": "Das sind Daten, die für schnelleren Zugriff lokal in deinem Browser gespeichert werden. Das Löschen wirkt sich nicht auf deine Serverdaten aus, meldet dich aber möglicherweise ab.",
|
||||
"clearLocal": "Gesamten lokalen Speicher und Cache löschen",
|
||||
"clearLocalTitle": "Gesamten lokalen Speicher löschen",
|
||||
"clearLocalMessage": "Möchtest du deinen lokalen Speicher und Cache wirklich löschen? Dadurch werden alle Daten aus diesem Browser entfernt und eine erneute Anmeldung ist erforderlich.",
|
||||
"clearAll": "Alles löschen",
|
||||
"appPreferences": "App-Einstellungen",
|
||||
"deviceOnly": "Nur auf dem Gerät",
|
||||
"appPreferencesDescription": "Das sind Einstellungen, die die App lokal auf deinem Gerät speichert. Beim Löschen werden app-spezifische Einstellungen zurückgesetzt und du wirst möglicherweise abgemeldet – deine Serverdaten bleiben unberührt.",
|
||||
"clearPreferences": "App-Einstellungen löschen",
|
||||
"clearPreferencesTitle": "App-Einstellungen löschen",
|
||||
"clearPreferencesMessage": "Möchtest du wirklich alle App-Einstellungen löschen? Dadurch werden deine App-Einstellungen zurückgesetzt und du musst dich möglicherweise erneut anmelden."
|
||||
},
|
||||
"sidepanel": {
|
||||
"title": "Seitenleisten-Anpassung",
|
||||
"heading": "Seitenleisten-Einstellungen",
|
||||
"description": "Lege fest, welche Karten in der Seitenleiste erscheinen und in welcher Reihenfolge. Ziehe die Karten zum Sortieren oder schalte ihre Sichtbarkeit um.",
|
||||
"resetToDefaults": "Auf Standard zurücksetzen",
|
||||
"resetHelper": "Dadurch werden Sichtbarkeit und Reihenfolge aller Karten auf den Standard zurückgesetzt.",
|
||||
"cards": {
|
||||
"welcome": {
|
||||
"name": "Benutzerwechsel",
|
||||
"description": "Ermöglicht Admins/Managern, Aufgaben aus Sicht anderer Nutzer zu sehen"
|
||||
},
|
||||
"circle": {
|
||||
"title": "Kreis-Einstellungen",
|
||||
"description": "Verwalte deinen Kreis, lade Mitglieder ein und bearbeite Beitrittsanfragen."
|
||||
"smartInsights": {
|
||||
"name": "Smarte Einblicke",
|
||||
"description": "Schnellaktionen basierend auf deinen Aufgaben"
|
||||
},
|
||||
"account": {
|
||||
"title": "Account-Einstellungen",
|
||||
"description": "Verwalte dein Abonnement, ändere dein Passwort und Account-Löschoptionen."
|
||||
"assignees": {
|
||||
"name": "Aufgaben nach Zuständigkeit",
|
||||
"description": "Gruppiert Aufgaben nach zugewiesener Person"
|
||||
},
|
||||
"subaccounts": {
|
||||
"title": "Verwaltete Accounts",
|
||||
"description": "Erstelle und verwalte Unter-Accounts zum Anmelden und Erledigen zugewiesener Aufgaben."
|
||||
"calendar": {
|
||||
"name": "Kalenderansicht",
|
||||
"description": "Zeigt Aufgaben im Kalenderformat"
|
||||
},
|
||||
"notifications": {
|
||||
"title": "Benachrichtigungen",
|
||||
"description": "Konfiguriere Push-Benachrichtigungen, E-Mail-Benachrichtigungen und Benachrichtigungsziele für Aufgaben."
|
||||
"activities": {
|
||||
"name": "Letzte Aktivitäten",
|
||||
"description": "Zeigt kürzlich erledigte Aufgaben und Aktivitäten"
|
||||
},
|
||||
"mfa": {
|
||||
"title": "Multi-Faktor-Authentifizierung",
|
||||
"description": "Füge eine zusätzliche Sicherheitsebene mit MFA über Authenticator-Apps hinzu."
|
||||
},
|
||||
"apitokens": {
|
||||
"title": "API-Token",
|
||||
"description": "Generiere und verwalte Zugriffstoken für Drittanbieter-Integrationen und API-Zugang."
|
||||
},
|
||||
"storage": {
|
||||
"title": "Speicher-Einstellungen",
|
||||
"description": "Sichere und stelle deine Daten wieder her, verwalte lokalen Speicher und Synchronisierungseinstellungen."
|
||||
},
|
||||
"sidepanel": {
|
||||
"title": "Seitenleisten-Anpassung",
|
||||
"description": "Passe das Layout und die Sichtbarkeit von Karten in der Seitenleisten-Oberfläche an."
|
||||
},
|
||||
"theme": {
|
||||
"title": "Theme-Einstellungen",
|
||||
"description": "Wähle dein bevorzugtes Theme und konfiguriere Dunkel-/Hell-Modus-Einstellungen."
|
||||
},
|
||||
"localization": {
|
||||
"title": "Sprach- und Formateinstellungen",
|
||||
"description": "Passe Sprache, Datumsformat, Zeitformat und regionale Einstellungen an."
|
||||
},
|
||||
"advanced": {
|
||||
"title": "Erweiterte Einstellungen",
|
||||
"description": "Konfiguriere Webhooks, Echtzeit-Updates und andere erweiterte Funktionen für erhöhte Produktivität."
|
||||
},
|
||||
"developer": {
|
||||
"title": "Entwickler-Einstellungen",
|
||||
"description": "Zeige technische Informationen über Authentifizierungs-Token, SSE-Verbindungen und Debug-Daten an."
|
||||
"weeklyGoals": {
|
||||
"name": "Wochenziele",
|
||||
"description": "Zeigt den Wochenfortschritt und die Erledigungsstatistik der Familie"
|
||||
}
|
||||
}
|
||||
},
|
||||
"theme": {
|
||||
"title": "Design-Einstellungen",
|
||||
"description": "Lege fest, wie die Seite für dich aussieht. Wähle ein festes Design oder synchronisiere mit deinem System, um automatisch zwischen hellem und dunklem Design zu wechseln.",
|
||||
"themeMode": "Design-Modus",
|
||||
"light": "Hell",
|
||||
"dark": "Dunkel",
|
||||
"system": "System"
|
||||
},
|
||||
"localization": {
|
||||
"title": "Lokalisierung",
|
||||
"description": "Passe Sprache, Datumsformat und regionale Einstellungen für dein Konto an.",
|
||||
"language": "Sprache",
|
||||
"languageDescription": "Wähle deine bevorzugte Sprache",
|
||||
"rtlNotice": "Diese Sprache wird von rechts nach links (RTL) geschrieben",
|
||||
"dateFormat": "Datumsformat",
|
||||
"dateFormatDescription": "Lege fest, wie Datumsangaben in der App angezeigt werden",
|
||||
"timeFormat": "Zeitformat",
|
||||
"timeFormatDescription": "Wähle das 12- oder 24-Stunden-Format",
|
||||
"preview": "Vorschau: {{value}}",
|
||||
"12hour": "12 Stunden (AM/PM)",
|
||||
"24hour": "24 Stunden",
|
||||
"firstDayOfWeek": "Erster Wochentag",
|
||||
"firstDayOfWeekDescription": "Lege fest, mit welchem Tag deine Woche beginnt",
|
||||
"sunday": "Sonntag",
|
||||
"monday": "Montag",
|
||||
"saturday": "Samstag",
|
||||
"formats": {
|
||||
"mdy": "MM/TT/JJJJ (USA)",
|
||||
"dmy": "TT.MM.JJJJ (Europa)",
|
||||
"ymd": "JJJJ-MM-TT (ISO)",
|
||||
"long": "Langes Format (z. B. 1. Januar 2024)",
|
||||
"short": "Kurzes Format (z. B. 1. Jan. 2024)"
|
||||
}
|
||||
},
|
||||
"advanced": {
|
||||
"title": "Erweiterte Einstellungen",
|
||||
"description": "Konfiguriere erweiterte Funktionen wie Webhooks und Echtzeit-Updates für mehr Produktivität.",
|
||||
"offlineTitle": "Offline-Unterstützung",
|
||||
"offlineDescription": "Nutze Donetick auch offline auf diesem Gerät/Browser. Deine Änderungen werden lokal gespeichert und synchronisiert, sobald du wieder online bist.",
|
||||
"offlineToggle": "Offline-Unterstützung aktivieren",
|
||||
"offlineHelper": "Beim Deaktivieren werden nicht synchronisierte Offline-Änderungen und gespeicherte Offline-Daten von diesem Gerät/Browser entfernt.",
|
||||
"offlineEnabled": "Offline-Modus für dieses Gerät/diesen Browser aktiviert",
|
||||
"offlineDisabled": "Offline-Modus deaktiviert und lokale Daten gelöscht",
|
||||
"offlineDisabledPartial": "Der Offline-Modus wurde deaktiviert, es können jedoch noch lokale Daten gespeichert sein",
|
||||
"offlineDisableTitle": "Offline-Modus deaktivieren",
|
||||
"offlineDisableMessage": "Beim Deaktivieren des Offline-Modus werden nicht synchronisierte Offline-Änderungen und gespeicherte Offline-Daten auf diesem Gerät/Browser entfernt. Möchtest du fortfahren?",
|
||||
"offlineDisableConfirm": "Deaktivieren & Daten löschen",
|
||||
"webhookTitle": "Webhook-Integration",
|
||||
"webhookDescription": "Mit Webhooks kannst du Echtzeit-Benachrichtigungen an andere Dienste senden, wenn in deinem Circle etwas passiert. Konfiguriere eine Webhook-URL, um Echtzeit-Updates zu erhalten.",
|
||||
"webhookPlusNotice": "Webhook-Benachrichtigungen sind im Basis-Tarif nicht verfügbar. Wechsle zu Plus, um Echtzeit-Updates per Webhook zu erhalten.",
|
||||
"webhookToggle": "Webhook aktivieren",
|
||||
"webhookHelper": "Webhook-Benachrichtigungen für Aufgaben- und Dinge-Updates aktivieren.",
|
||||
"webhookURL": "Webhook-URL",
|
||||
"webhookUpdated": "Webhook-URL erfolgreich aktualisiert",
|
||||
"webhookUpdateFailed": "Webhook-URL konnte nicht aktualisiert werden",
|
||||
"realtimeTitle": "Echtzeit-Updates",
|
||||
"realtimeDescription": "Lege fest, wie du Live-Updates erhältst, wenn sich Aufgaben und Aktivitäten in deinem Circle ändern.",
|
||||
"realtime": {
|
||||
"toggleLabel": "Echtzeit-Updates aktivieren",
|
||||
"title": "Echtzeit-Updates",
|
||||
"subtitle": "Erhalte sofort Benachrichtigungen, wenn Aufgaben aktualisiert werden",
|
||||
"statusLabel": "Status:",
|
||||
"basicPlan": "Echtzeit-Updates sind im Basis-Tarif nicht verfügbar. Wechsle zu Plus, um sofort benachrichtigt zu werden, wenn Aufgaben aktualisiert werden.",
|
||||
"disabled": "Echtzeit-Updates sind deaktiviert. Aktiviere sie, um Live-Änderungen zu sehen, wenn du oder andere Circle-Mitglieder Aufgaben erledigen, überspringen oder ändern.",
|
||||
"connected": "Echtzeit-Updates funktionieren. Du siehst Live-Änderungen, wenn du oder andere Circle-Mitglieder Aufgaben erledigen, überspringen oder ändern.",
|
||||
"connecting": "Verbindung zu Echtzeit-Updates wird hergestellt …",
|
||||
"errored": "Echtzeit-Updates sind aktiviert, funktionieren aber nicht: {{error}}",
|
||||
"notConnected": "Echtzeit-Updates sind aktiviert, aber derzeit nicht verbunden.",
|
||||
"basicPlanNotice": "Echtzeit-Updates sind im Basis-Tarif nicht verfügbar. Wechsle zu Plus, um sofort benachrichtigt zu werden, wenn du oder andere Circle-Mitglieder Aufgaben erledigen, überspringen oder ändern."
|
||||
}
|
||||
},
|
||||
"subscription": {
|
||||
"sessionFailed": "Failed to create subscription session",
|
||||
"errorTitle": "Subscription Error",
|
||||
"errorMessage": "Failed to start subscription process. Please try again.",
|
||||
"subscribe": "Subscribe",
|
||||
"cancelAnytime": "Cancel anytime. No hidden fees. Secure payment powered by Stripe."
|
||||
},
|
||||
"childUsers": {
|
||||
"errNameRequired": "Sub account name is required",
|
||||
"errNameMin": "Sub account name must be at least 2 characters",
|
||||
"errNameMax": "Sub account name must be less than 20 characters",
|
||||
"errNameChars": "Sub account name can only contain lowercase letters, dot and dash",
|
||||
"errPasswordRequired": "Password is required",
|
||||
"errPasswordLength": "Password must be between 8 and 64 characters",
|
||||
"errPasswordMatch": "Passwords do not match",
|
||||
"errDisplayNameMax": "Display name must be less than 50 characters",
|
||||
"createTitle": "Create Sub Account",
|
||||
"createButton": "Create Account",
|
||||
"nameLabel": "Sub Account Name *",
|
||||
"namePlaceholder": "Enter sub account name (e.g., sarah)",
|
||||
"displayNameLabel": "Display Name",
|
||||
"displayNamePlaceholder": "Display name (optional, defaults to sub account name)",
|
||||
"passwordLabel": "Password *",
|
||||
"passwordPlaceholder": "Enter password (8-64 characters)",
|
||||
"confirmPasswordLabel": "Confirm Password *",
|
||||
"confirmPasswordPlaceholder": "Confirm password"
|
||||
},
|
||||
"passwordChange": {
|
||||
"minLength": "Password must be at least 8 characters",
|
||||
"maxLength": "Password must be less than 64 characters"
|
||||
},
|
||||
"payment": {
|
||||
"cancelledTitle": "Payment has been cancelled",
|
||||
"cancelledRedirect": "You will be redirected to the main page shortly.",
|
||||
"successTitle": "Payment Successful!",
|
||||
"successRedirect": "You will be redirected to the settings page shortly."
|
||||
},
|
||||
"developer": {
|
||||
"tokenRefreshed": "Token refreshed successfully",
|
||||
"endpointCalled": "Refresh token endpoint called successfully",
|
||||
"clearDbCleared": "Local offline database cleared. Starting full sync...",
|
||||
"clearDbDone": "Full sync completed from the beginning",
|
||||
"intro": "View technical information about your authentication tokens and session",
|
||||
"refreshCookieNote": "Refresh tokens are managed via HTTP-only cookies on web platform",
|
||||
"noReconnectInfo": "No reconnection information available",
|
||||
"noTimeoutInfo": "No timeout information available",
|
||||
"noDebugInfo": "No debug information available"
|
||||
},
|
||||
"backup": {
|
||||
"keyRequired": "Encryption key is required",
|
||||
"created": "Backup created and downloaded successfully",
|
||||
"createFailed": "Failed to create backup",
|
||||
"selectFile": "Please select a backup file",
|
||||
"restored": "Backup restored successfully. Please refresh the page.",
|
||||
"restoreFailed": "Failed to restore backup",
|
||||
"readFailed": "Failed to read backup file",
|
||||
"createIntro": "Create an encrypted backup of your data. This backup will include all your chores, history, settings, and optionally your uploaded files.",
|
||||
"keyPlaceholder": "Enter a strong encryption key",
|
||||
"includeAssets": "Include uploaded files and assets",
|
||||
"warningLabel": "Warning:",
|
||||
"restoreWarning": "Restoring a backup will replace all your current data. This action cannot be undone.",
|
||||
"restoreKeyPlaceholder": "Enter the encryption key used for this backup"
|
||||
},
|
||||
"deletion": {
|
||||
"passwordRequired": "Please enter your password to continue",
|
||||
"passwordAndDelete": "Please enter your password and type DELETE to confirm",
|
||||
"failed": "Failed to delete account",
|
||||
"passwordPlaceholder": "Enter your password",
|
||||
"transferIntro": "You own circles that require ownership transfer before deletion. Please select new owners:",
|
||||
"selectOwner": "Select new owner",
|
||||
"confirmPrompt": "Please enter your password and type DELETE to confirm",
|
||||
"typeDelete": "DELETE"
|
||||
}
|
||||
}
|
||||
|
||||
18
public/locales/de/things.json
Normal file
18
public/locales/de/things.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"errName": "Name is required",
|
||||
"errStateNumber": "State must be a number",
|
||||
"errStateBool": "State must be true or false",
|
||||
"errStateRequired": "State is required",
|
||||
"name": "Name",
|
||||
"namePlaceholder": "Thing name",
|
||||
"value": "Value",
|
||||
"valuePlaceholder": "Thing value",
|
||||
"updateState": "Update state",
|
||||
"update": "Update",
|
||||
"history": {
|
||||
"overview": "Things Overview",
|
||||
"visualization": "Data Visualization",
|
||||
"changeHistory": "Change History",
|
||||
"updated": "Updated"
|
||||
}
|
||||
}
|
||||
29
public/locales/de/timer.json
Normal file
29
public/locales/de/timer.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"toast": {
|
||||
"sessionUpdatedTitle": "Session updated",
|
||||
"sessionUpdatedMessage": "Timer session has been updated successfully.",
|
||||
"sessionUpdateFailTitle": "Failed to update session",
|
||||
"tryAgain": "Please try again.",
|
||||
"sessionUpdateErrorTitle": "Error updating session",
|
||||
"sessionDeletedTitle": "Session deleted",
|
||||
"sessionDeletedMessage": "Timer session has been deleted successfully.",
|
||||
"sessionDeleteErrorTitle": "Error deleting session",
|
||||
"deleteConfirmTitle": "Delete Timer Session",
|
||||
"deleteConfirmMessage": "Are you sure you want to delete this timer session?"
|
||||
},
|
||||
"loading": "Loading timer data...",
|
||||
"noData": "No timer data found for this chore.",
|
||||
"activeWork": "Active Work",
|
||||
"breakTime": "Break Time",
|
||||
"workSessions": "Work Sessions",
|
||||
"totalTime": "Total Time",
|
||||
"distribution": "Work vs Break Distribution",
|
||||
"noActiveTime": "No active time yet",
|
||||
"sessionBreakdown": "Session Breakdown",
|
||||
"sessions": "Sessions",
|
||||
"addSession": "Add Session",
|
||||
"startTime": "Start Time",
|
||||
"endTime": "End Time",
|
||||
"leaveEmpty": "Leave empty if session is ongoing",
|
||||
"noSessionForChore": "No timer session found for this chore."
|
||||
}
|
||||
111
public/locales/en/auth.json
Normal file
111
public/locales/en/auth.json
Normal file
@@ -0,0 +1,111 @@
|
||||
{
|
||||
"validationError": "Validation Error",
|
||||
"primaryUsernameRequired": "Primary username is required for sub account login",
|
||||
"subNameRequired": "Sub account name is required for sub account login",
|
||||
"usernameRequired": "Username is required",
|
||||
"passwordRequired": "Password is required",
|
||||
"loginFailed": "Login Failed",
|
||||
"genericError": "An error occurred, please try again",
|
||||
"providerLoginFailed": "{{provider}} Login Failed",
|
||||
"providerLoginFailedMsg": "Couldn't log in with {{provider}}, please try again",
|
||||
"providerLoginError": "{{provider}} Login Error",
|
||||
"networkError": "Network error occurred, please try again",
|
||||
"mfaFailed": "Two-Factor Authentication Failed",
|
||||
"oauthError": "OAuth Error",
|
||||
"oauthBrowserFailed": "Failed to open authentication browser",
|
||||
"primaryAccount": "Primary Account",
|
||||
"subAccount": "Sub Account",
|
||||
"username": "Username",
|
||||
"primaryUsernamePlaceholder": "Enter primary account username",
|
||||
"subNamePlaceholder": "Enter sub account name",
|
||||
"forgotPassword": "Forgot password?",
|
||||
"or": "or",
|
||||
"email": "Email",
|
||||
"displayNamePlaceholder": "How others see your name",
|
||||
"signupFailed": "Signup Failed",
|
||||
"signupDisabled": "Signup disabled, please contact admin",
|
||||
"usernameMinLength": "Username must be at least 4 characters",
|
||||
"invalidEmail": "Invalid email address",
|
||||
"passwordLength": "Password must be between 8 and 64 characters",
|
||||
"displayNameRequired": "Display name is required",
|
||||
"displayNameChars": "Display name can only contain letters and numbers",
|
||||
"resetEmailSent": "Reset Email Sent",
|
||||
"resetEmailSentMsg": "Check your email for password reset instructions",
|
||||
"resetFailed": "Reset Failed",
|
||||
"resetFailedMsg": "Failed to send reset email, please try again later",
|
||||
"emailPlaceholder": "you@example.com",
|
||||
"passwordUpdated": "Password Updated",
|
||||
"passwordUpdatedMsg": "Your password has been updated successfully. Redirecting to login...",
|
||||
"passwordUpdateFailed": "Password Update Failed",
|
||||
"passwordUpdateFailedMsg": "Failed to update password, please try again later",
|
||||
"savePassword": "Save password",
|
||||
"server": {
|
||||
"url": "Server URL",
|
||||
"dnsFailed": "Hostname could not be resolved. Check the URL for typos or verify DNS.",
|
||||
"unreachable": "Unable to reach the server. Check the URL, port, and network connection.",
|
||||
"invalidUrl": "Invalid URL format. Include the protocol (http:// or https://) and port if needed."
|
||||
},
|
||||
"mfaModal": {
|
||||
"title": "Two-factor authentication",
|
||||
"codeRequired": "Please enter a verification code",
|
||||
"verifyFailed": "Failed to verify code. Please try again.",
|
||||
"backupHint": "Enter one of the backup codes you saved when setting up two-factor authentication.",
|
||||
"codeHint": "Enter the 6-digit code from your authenticator app.",
|
||||
"verify": "Verify & Sign In",
|
||||
"backupLabel": "Backup code",
|
||||
"codeLabel": "Verification code",
|
||||
"backupPlaceholder": "Enter backup code",
|
||||
"useAuthenticator": "Use authenticator app instead",
|
||||
"useBackup": "Use a backup code instead",
|
||||
"backupOnce": "Each backup code can only be used once.",
|
||||
"invalidCode": "Invalid verification code. Please try again."
|
||||
},
|
||||
"appleLoginFailed": "Apple Login Failed",
|
||||
"googleLoginFailed": "Google Login Failed",
|
||||
"createOne": "Create one",
|
||||
"primaryAccountUsernameLabel": "Primary account username",
|
||||
"subAccountNameLabel": "Sub account name",
|
||||
"serverSettings": "Server settings",
|
||||
"useDifferentAccount": "Use a different account",
|
||||
"yourUsername": "Your username",
|
||||
"backToSignIn": "Back to sign in",
|
||||
"confirmNewPassword": "Confirm new password",
|
||||
"newPassword": "New password",
|
||||
"reenterPassword": "Re-enter your password",
|
||||
"requestNewLink": "Request a new link",
|
||||
"setNewPassword": "Set a new password",
|
||||
"linkInvalid": "This link is not valid",
|
||||
"createAccountButton": "Create account",
|
||||
"createYourAccount": "Create your account",
|
||||
"displayNameLabel": "Display name",
|
||||
"usernameHint": "lowercase letters, numbers, dot and dash",
|
||||
"termsShort": "By creating an account you agree to our Terms of Service and Privacy",
|
||||
"checkYourEmail": "Check your email",
|
||||
"resetYourPassword": "Reset your password",
|
||||
"serverChangeWarning": "Changing the server clears locally cached data on this device.",
|
||||
"serverConnected": "Connected. Taking you to sign in...",
|
||||
"passwordLabel": "Password",
|
||||
"showPassword": "Show password",
|
||||
"hidePassword": "Hide password",
|
||||
"loginPasswordPlaceholder": "Enter your password",
|
||||
"signupPasswordPlaceholder": "At least 8 characters",
|
||||
"signupPasswordHelper": "Use 8 to 64 characters.",
|
||||
"orContinueWith": "or continue with",
|
||||
"signupSignInFailed": "Your account was created, but signing in failed. Please sign in.",
|
||||
"authenticating": {
|
||||
"signingIn": "Signing you in",
|
||||
"signingInSub": "This will only take a moment.",
|
||||
"unknownProvider": "Unknown sign-in provider",
|
||||
"contactSupport": "Please contact support.",
|
||||
"signInFailed": "Sign-in failed",
|
||||
"mfaCancelled": "Two-factor authentication was cancelled.",
|
||||
"requestNotVerified": "The sign-in request could not be verified.",
|
||||
"tryAgain": "Please try again.",
|
||||
"mfaSessionMissing": "The MFA session is missing. Please try again.",
|
||||
"twoFactor": "Two-factor authentication",
|
||||
"verifyToContinue": "Verify your login to continue.",
|
||||
"noToken": "No valid authentication token was returned.",
|
||||
"backToSignIn": "Back to sign in",
|
||||
"mfaFailed": "Two-factor authentication failed. Please try again."
|
||||
}
|
||||
}
|
||||
@@ -63,6 +63,8 @@
|
||||
"skip": "Skip",
|
||||
"cancel": "Cancel",
|
||||
"noPriority": "No Priority",
|
||||
"more": "More",
|
||||
"changeDueDate": "Change due date",
|
||||
"subtasks": "Subtasks",
|
||||
"noDescription": "No description available",
|
||||
"timer": {
|
||||
@@ -70,6 +72,771 @@
|
||||
"paused": "Timer Paused",
|
||||
"reset": "Reset Timer",
|
||||
"delete": "Delete Session"
|
||||
},
|
||||
"unableUndo": "Failed to undo",
|
||||
"offlineComplete": "You're offline — completion will sync when back online",
|
||||
"unableComplete": "Unable to complete task",
|
||||
"offlineSkip": "You're offline — skip will sync when back online",
|
||||
"unableSkip": "Unable to skip task",
|
||||
"offlineStart": "You're offline — start will sync when back online",
|
||||
"unableStart": "Unable to start task",
|
||||
"offlinePause": "You're offline — pause will sync when back online",
|
||||
"unablePause": "Unable to pause task",
|
||||
"offlineRestore": "You're offline — restore will sync when back online",
|
||||
"restoreFailed": "Failed to restore",
|
||||
"unableRestore": "Unable to restore task"
|
||||
},
|
||||
"toolbar": {
|
||||
"defaultProject": "Default Project",
|
||||
"everyone": "Everyone",
|
||||
"mine": "Mine",
|
||||
"availableToMe": "Available to me",
|
||||
"others": "Others",
|
||||
"cards": "Cards",
|
||||
"compact": "Compact",
|
||||
"calendar": "Calendar",
|
||||
"filters": "Filters",
|
||||
"viewGroup": "View & Group",
|
||||
"filterNamePlaceholder": "Filter name…",
|
||||
"clearAll": "Clear all",
|
||||
"saveFilter": "Save Filter",
|
||||
"saveAsNew": "Save as New Filter",
|
||||
"groupBy": "Group by",
|
||||
"showTasksFor": "Show tasks for",
|
||||
"type": {
|
||||
"assignee": "Assignee"
|
||||
},
|
||||
"display": "Display",
|
||||
"displayOptions": "Display options"
|
||||
},
|
||||
"sort": {
|
||||
"assignedToMe": "Assigned to me",
|
||||
"smart": "Smart",
|
||||
"createdDate": "Created Date",
|
||||
"updatedDate": "Updated Date",
|
||||
"sortAndGroup": "Sort and Group (Ctrl+G)",
|
||||
"groupBy": "Group By",
|
||||
"quickFilters": "Quick Filters",
|
||||
"assignedTo": "Assigned to:",
|
||||
"availableForMe": "Available for me",
|
||||
"assignedToOthers": "Assigned to others",
|
||||
"createFilter": "Create Filter",
|
||||
"createFilterHint": "Build advanced filter rules"
|
||||
},
|
||||
"thing": {
|
||||
"triggerHint": "Trigger a task when a thing state changes to a desired state",
|
||||
"selectThing": "Select a thing",
|
||||
"enterText": "Enter the text to trigger the task"
|
||||
},
|
||||
"activity": {
|
||||
"showMore": "Show more",
|
||||
"title": "Recent Activities",
|
||||
"loading": "Loading activities...",
|
||||
"status": {
|
||||
"done": "Done"
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"overdue": "Overdue",
|
||||
"dueToday": "Due Today",
|
||||
"pendingApproval": "Pending Approval",
|
||||
"dueThisWeek": "Due This Week",
|
||||
"noDueDate": "No Due Date",
|
||||
"dueDate": "Due Date",
|
||||
"dueLater": "Due Later"
|
||||
},
|
||||
"insights": {
|
||||
"highPriority": "High Priority"
|
||||
},
|
||||
"labels": {
|
||||
"label": "Labels"
|
||||
},
|
||||
"actionMenu": {
|
||||
"view": "View",
|
||||
"archive": "Archive",
|
||||
"writeNFC": "Write to NFC",
|
||||
"completeWithNote": "Complete with note",
|
||||
"completeInPast": "Complete in past",
|
||||
"skipToNext": "Skip to next due date",
|
||||
"sendNudge": "Send nudge",
|
||||
"history": "History",
|
||||
"clone": "Clone",
|
||||
"moveToProject": "Move to project",
|
||||
"removeDueDate": "Remove due date"
|
||||
},
|
||||
"actions": {
|
||||
"rescheduledTitle": "Task Rescheduled",
|
||||
"rescheduledMessage": "The task due date has been updated successfully.",
|
||||
"unplannedTitle": "Task Unplanned",
|
||||
"unplannedMessage": "The task is now unplanned and has no due date.",
|
||||
"archivedTitle": "Task Archived",
|
||||
"startedTitle": "Task Started",
|
||||
"startedMessage": "The task has been marked as started.",
|
||||
"pausedTitle": "Task Paused",
|
||||
"pausedMessage": "The task has been paused.",
|
||||
"deletedMessage": "The task has been deleted.",
|
||||
"undoable": {
|
||||
"completed": "Task completed"
|
||||
},
|
||||
"completionPending": "Task completion pending",
|
||||
"failCompleteTitle": "Failed to complete",
|
||||
"failStartTitle": "Failed to start",
|
||||
"failPauseTitle": "Failed to pause",
|
||||
"failApproveTitle": "Failed to approve",
|
||||
"failRejectTitle": "Failed to reject",
|
||||
"deletedMessageLong": "The task has been deleted successfully.",
|
||||
"failDeleteTitle": "Failed to delete",
|
||||
"failArchiveTitle": "Failed to archive",
|
||||
"failSkipTitle": "Failed to skip",
|
||||
"movedTitle": "Task Moved",
|
||||
"failMoveTitle": "Failed to move task",
|
||||
"failRescheduleTitle": "Failed to reschedule",
|
||||
"nudgeSentTitle": "Nudge Sent!",
|
||||
"nudgeFailed": "Failed to send nudge",
|
||||
"failNudgeTitle": "Failed to Send Nudge",
|
||||
"bulk": {
|
||||
"completeTitle": "Complete Tasks",
|
||||
"completedTitle": "✅ Tasks Completed",
|
||||
"completeFailedTitle": "Bulk Complete Failed",
|
||||
"archiveTitle": "Archive Tasks",
|
||||
"archivedTitle": "📦 Tasks Archived",
|
||||
"archiveFailedTitle": "Bulk Archive Failed",
|
||||
"deleteTitle": "Delete Tasks",
|
||||
"skipTitle": "Skip Tasks",
|
||||
"skippedTitle": "⏭️ Tasks Skipped",
|
||||
"skipFailedTitle": "Bulk Skip Failed"
|
||||
}
|
||||
},
|
||||
"archived": {
|
||||
"restoredTitle": "Task Restored",
|
||||
"restoredMsg": "The task has been restored and is now active.",
|
||||
"deletedTitle": "Task Deleted",
|
||||
"delete": "Delete",
|
||||
"someFailedTitle": "Some Tasks Failed",
|
||||
"unexpectedError": "An unexpected error occurred. Please try again.",
|
||||
"deletedBulkTitle": "🗑️ Tasks Deleted",
|
||||
"bulkDeleteFailTitle": "Bulk Delete Failed",
|
||||
"archivedDate": "Archived Date",
|
||||
"loadFailTitle": "Failed to load archived tasks",
|
||||
"loadFailMsg": "Please try again later.",
|
||||
"deletedMsg": "The archived task has been permanently deleted.",
|
||||
"restoreTasksTitle": "Restore Tasks",
|
||||
"restore": "Restore",
|
||||
"restoreConfirm_one": "Restore {{count}} task to active list?",
|
||||
"restoreConfirm_other": "Restore {{count}} tasks to active list?",
|
||||
"restoredBulkTitle": "📤 Tasks Restored",
|
||||
"restoredCount_one": "Restored {{count}} task{{offline}}.",
|
||||
"restoredCount_other": "Restored {{count}} tasks{{offline}}.",
|
||||
"restoreFailCount_one": "{{count}} task could not be restored.",
|
||||
"restoreFailCount_other": "{{count}} tasks could not be restored.",
|
||||
"bulkRestoreFailTitle": "Bulk Restore Failed",
|
||||
"deleteTasksTitle": "Delete Archived Tasks",
|
||||
"deleteConfirm_one": "Permanently delete {{count}} archived task?\n\nThis action cannot be undone.",
|
||||
"deleteConfirm_other": "Permanently delete {{count}} archived tasks?\n\nThis action cannot be undone.",
|
||||
"deletedCount_one": "Successfully deleted {{count}} task.",
|
||||
"deletedCount_other": "Successfully deleted {{count}} tasks.",
|
||||
"deleteFailCount_one": "{{count}} task could not be deleted.",
|
||||
"deleteFailCount_other": "{{count}} tasks could not be deleted.",
|
||||
"title": "Archived Tasks",
|
||||
"subtitle": "View and manage tasks that have been archived or completed.",
|
||||
"heading": "Archived Tasks",
|
||||
"searchPlaceholder": "Search archived tasks",
|
||||
"switchToCompact": "Switch to Compact View",
|
||||
"switchToCard": "Switch to Card View",
|
||||
"exitMultiSelect": "Exit Multi-select Mode (Ctrl+S)",
|
||||
"enableMultiSelect": "Enable Multi-select Mode (Ctrl+S)",
|
||||
"selected_one": "{{count}} task selected",
|
||||
"selected_other": "{{count}} tasks selected",
|
||||
"selectAllTitle": "Select all visible tasks (Ctrl+A)",
|
||||
"all": "All",
|
||||
"closeMultiSelect": "Close multi-select (Esc)",
|
||||
"clearMultiSelect": "Clear multi-select (Esc)",
|
||||
"close": "Close",
|
||||
"clear": "Clear",
|
||||
"restoreSelectedTitle": "Restore selected tasks (R)",
|
||||
"deleteSelectedTitle": "Delete selected tasks (E)",
|
||||
"clearSearch": "Clear search",
|
||||
"clearFilters": "Clear filters",
|
||||
"count_one": "{{count}} archived task",
|
||||
"count_other": "{{count}} archived tasks",
|
||||
"matching": " matching \"{{term}}\"",
|
||||
"filtersTitle": "Filters",
|
||||
"sortArchivedDate": "Archived date",
|
||||
"sortName": "Name",
|
||||
"sortPriority": "Priority",
|
||||
"sortDueDate": "Due date",
|
||||
"noMatchTitle": "No archived tasks match",
|
||||
"noMatchSearch": "Nothing in the archive matches \"{{term}}\".",
|
||||
"noMatchFilters": "There are archived tasks, but none fit the filters that are currently on.",
|
||||
"emptyTitle": "Nothing archived",
|
||||
"emptyDescription": "Archiving hides a task without deleting it. Anything you archive from your task list shows up here, ready to restore.",
|
||||
"backToTasks": "Back to tasks"
|
||||
},
|
||||
"edit": {
|
||||
"deleteConfirm": "Are you sure you want to delete this chore?"
|
||||
},
|
||||
"list": {
|
||||
"complete": "Complete",
|
||||
"filterSaved": "Filter Saved",
|
||||
"filterSavedMsg": "\"{{name}}\" has been saved",
|
||||
"nothingScheduled": "Nothing scheduled",
|
||||
"createChore": "Create new chore (Cmd+C)",
|
||||
"filterUpdated": "Filter Updated",
|
||||
"filterUpdatedMsg": "\"{{name}}\" has been updated successfully",
|
||||
"advancedFilterCreated": "Advanced Filter Created",
|
||||
"advancedFilterCreatedMsg": "\"{{name}}\" has been created successfully",
|
||||
"reject": "Reject",
|
||||
"pending": "Pending",
|
||||
"schedule": "Schedule",
|
||||
"nudge": "Nudge"
|
||||
},
|
||||
"multiToolbar": {
|
||||
"skip": "Skip",
|
||||
"completeTitle": "Complete selected tasks (Enter)",
|
||||
"complete": "Complete",
|
||||
"skipTitle": "Skip selected tasks (/)",
|
||||
"archiveTitle": "Archive selected tasks (X)",
|
||||
"archive": "Archive",
|
||||
"deleteTitle": "Delete selected tasks (Shift+X)",
|
||||
"mixed": "Mixed",
|
||||
"due": "Due",
|
||||
"dueTitleSet": "Due date on selected tasks: {{value}}",
|
||||
"dueTitleEmpty": "Set due date on selected tasks",
|
||||
"presetToday": "Today",
|
||||
"presetTomorrow": "Tomorrow",
|
||||
"presetNextWeek": "Next week",
|
||||
"pickDate": "Pick date…",
|
||||
"noDueDate": "No due date",
|
||||
"moveTitle": "Move selected tasks to a project",
|
||||
"move": "Move",
|
||||
"defaultProject": "Default Project",
|
||||
"moreTitle": "Set priority, assignee, or labels",
|
||||
"more": "More",
|
||||
"priority": "Priority",
|
||||
"assignee": "Assignee",
|
||||
"labels": "Labels",
|
||||
"labelsHint": "Tap to add · tap again to remove",
|
||||
"done": "Done",
|
||||
"noPriority": "None"
|
||||
},
|
||||
"remind": {
|
||||
"title": "Reminders"
|
||||
},
|
||||
"assignee": {
|
||||
"anyone": "Anyone"
|
||||
},
|
||||
"filterChip": {
|
||||
"cancelAll": "Cancel All Filters",
|
||||
"unpin": "Unpin filter",
|
||||
"pin": "Pin filter",
|
||||
"edit": "Edit filter",
|
||||
"delete": "Delete filter"
|
||||
},
|
||||
"multiSelect": {
|
||||
"showShortcuts": "Show keyboard shortcuts",
|
||||
"title": "Multi-select Mode",
|
||||
"selection": "Selection",
|
||||
"selectAll": "Select all visible tasks",
|
||||
"clearOrExit": "Clear selection or exit multi-select mode",
|
||||
"actions": "Actions",
|
||||
"markCompleted": "Mark selected tasks as completed",
|
||||
"deleteSelected": "Delete selected tasks",
|
||||
"interface": "Interface",
|
||||
"quickAdd": "Quick add new task"
|
||||
},
|
||||
"notifications": {
|
||||
"needTitle": "Need Notification?",
|
||||
"needBody": "You need to enable permission to receive notifications, do you want to enable it?",
|
||||
"keepDisabled": "No, Keep it Disabled"
|
||||
},
|
||||
"assigneeCard": {
|
||||
"loading": "Loading tasks by assignee...",
|
||||
"title": "Tasks by Assignee",
|
||||
"scheduled": "Scheduled",
|
||||
"pendingReview": "Pending Review"
|
||||
},
|
||||
"filter": {
|
||||
"status": {
|
||||
"inProgress": "In Progress"
|
||||
}
|
||||
},
|
||||
"impersonate": {
|
||||
"viewAs": "View tasks as",
|
||||
"switchTitle": "Switch to user view",
|
||||
"switchHint": "Tasks will be filtered to show only assignments for selected user",
|
||||
"chooseUser": "Choose User",
|
||||
"changeUser": "Change User"
|
||||
},
|
||||
"modals": {
|
||||
"changeDueDate": "Change due date",
|
||||
"completePast": "Save Chore that you completed in the past",
|
||||
"delegate": "Delegate to someone else",
|
||||
"selectPerformer": "Select a performer",
|
||||
"addNote": "Add note to attach to this completion:",
|
||||
"complete": "Complete"
|
||||
},
|
||||
"shortcuts": {
|
||||
"allSelectedTitle": "✅ All Tasks Selected",
|
||||
"someSelectedTitle": "🎯 Tasks Selected",
|
||||
"allSelectedAltTitle": "🎯 All Tasks Selected"
|
||||
},
|
||||
"overview": {
|
||||
"title": "Chores Overviews",
|
||||
"search": "Search",
|
||||
"newChore": "New Chore",
|
||||
"unassigned": "Unassigned",
|
||||
"changeDueDate": "Change due date",
|
||||
"colDue": "Due",
|
||||
"colChore": "Chore",
|
||||
"colAssignee": "Assignee",
|
||||
"colAction": "Action"
|
||||
},
|
||||
"dataError": {
|
||||
"attachmentsFailed": "Failed to fetch attachments"
|
||||
},
|
||||
"nudge": {
|
||||
"title": "Send Nudge",
|
||||
"customMessage": "Custom Message (optional)",
|
||||
"messagePlaceholder": "Add a personal message with your nudge...",
|
||||
"notifyAll": "Notify All Assignees",
|
||||
"notifyAllHint": "If enabled, all members who can see this task will be notified. Otherwise, only the assigned person will receive the nudge."
|
||||
},
|
||||
"nfc": {
|
||||
"errWrite": "Error writing to NFC tag. Please try again.",
|
||||
"errUnsupported": "NFC is not supported by this browser. Copy the URL and write it to an NFC tag using a compatible device.",
|
||||
"titleSuccess": "Tag written!",
|
||||
"titleError": "Something went wrong",
|
||||
"titleWaiting": "Hold near NFC tag",
|
||||
"subSuccess": "Your NFC tag is ready to use.",
|
||||
"subWaiting": "Keep your device near the tag until complete.",
|
||||
"subIdle": "Encode this task link onto any NFC tag.",
|
||||
"tagUrl": "Tag URL",
|
||||
"copyUrl": "Copy URL",
|
||||
"autoComplete": "Auto-complete on scan",
|
||||
"autoCompleteHint": "Mark task done when tag is tapped"
|
||||
},
|
||||
"duePicker": {
|
||||
"today": "Today",
|
||||
"tomorrow": "Tomorrow",
|
||||
"weekend": "Weekend",
|
||||
"nextWeek": "Next week",
|
||||
"title": "Due Date",
|
||||
"apply": "Apply",
|
||||
"remove": "Remove",
|
||||
"quickDate": "Quick date",
|
||||
"quickTime": "Quick time",
|
||||
"nextMonth": "Next month",
|
||||
"morning": "Morning",
|
||||
"noon": "Noon",
|
||||
"afternoon": "Afternoon",
|
||||
"evening": "Evening",
|
||||
"night": "Night",
|
||||
"customTime": "Custom time",
|
||||
"anytime": "Anytime",
|
||||
"specificTime": "Specific time"
|
||||
},
|
||||
"photoTask": {
|
||||
"title": "Scan photo to create task",
|
||||
"cameraUnavailable": "Camera not available",
|
||||
"uploadPhoto": "Upload Photo",
|
||||
"scanDocument": "Scan Document",
|
||||
"capture": "Capture",
|
||||
"processNatively": "Process Natively",
|
||||
"processImage": "Process Image",
|
||||
"createTask": "Create Task",
|
||||
"failedScan": "Failed scan",
|
||||
"retake": "Retake",
|
||||
"upload": "Upload",
|
||||
"keepAsAttachment": "Keep photo as attachment",
|
||||
"altCaptured": "Captured document",
|
||||
"altProcessing": "Processing",
|
||||
"taskIdentified": "Task identified"
|
||||
},
|
||||
"descriptionPlaceholder": "Enter description...",
|
||||
"notificationTemplate": {
|
||||
"onDueDate": "On due date",
|
||||
"timing": {
|
||||
"before": "Before",
|
||||
"ondue": "Due",
|
||||
"after": "After"
|
||||
},
|
||||
"unitName": {
|
||||
"m": "minutes",
|
||||
"h": "hours",
|
||||
"d": "days"
|
||||
},
|
||||
"unitShort": {
|
||||
"m": "Mins",
|
||||
"h": "Hours",
|
||||
"d": "Days"
|
||||
},
|
||||
"beforeDue": "{{count}} {{unit}} before due",
|
||||
"afterDue": "{{count}} {{unit}} after due",
|
||||
"errDuplicate": "This notification setting already exists. Please use a different timing.",
|
||||
"errOneDue": "Only one \"Due Alert\" notification is allowed.",
|
||||
"errAllConfigured": "All common {{type}} times are already configured.",
|
||||
"reminder": "Reminder",
|
||||
"dueAlert": "Due Alert",
|
||||
"followUp": "Follow-up",
|
||||
"rememberFuture": "Remember for Future Tasks"
|
||||
},
|
||||
"choreEdit": {
|
||||
"errNameRequired": "Name is required",
|
||||
"errFrequencyInvalid": "Invalid frequency, the {{unit}} should be > 0",
|
||||
"errSelectDayOfWeek": "Please select at least one day of the week",
|
||||
"errSelectDayOccurrence": "Please select at least one day occurrence for the month",
|
||||
"errSelectMonth": "Please select at least one month",
|
||||
"errStartDateRequired": "Start date is required",
|
||||
"errDueDateRequired": "Due date is required",
|
||||
"errThingTrigger": "Thing trigger is invalid",
|
||||
"errTitle": "Please resolve the following errors:",
|
||||
"savedOfflineTitle": "Saved Offline",
|
||||
"savedOfflineMessage": "Your changes will sync when you are back online.",
|
||||
"savedTitle": "Chore Saved",
|
||||
"savedMessage": "Your task has been saved successfully!",
|
||||
"saveFailedTitle": "Save Failed",
|
||||
"saveFailedMessage": "Failed to save chore, please try again.",
|
||||
"uploadFailedTitle": "Upload Failed",
|
||||
"uploadFailedMessage": "Failed to upload attachment.",
|
||||
"scanFailedTitle": "Scan Failed",
|
||||
"scanFailedMessage": "Could not scan the document.",
|
||||
"scanReadFailedMessage": "Could not read the scanned image.",
|
||||
"deleteFailedTitle": "Delete Failed",
|
||||
"deleteAttachmentFailed": "Failed to delete attachment.",
|
||||
"deleteChoreFailed": "Failed to delete chore: {{error}}",
|
||||
"deleteChoreTitle": "Delete Chore",
|
||||
"name": "Name",
|
||||
"nameDesc": "What is the name of this task?",
|
||||
"description": "Description",
|
||||
"descriptionDesc": "What is this task about?",
|
||||
"priority": "Priority",
|
||||
"priorityDesc": "How important is this task?",
|
||||
"noPriority": "No Priority",
|
||||
"project": "Project",
|
||||
"projectDesc": "Which project does this task belong to?",
|
||||
"defaultProject": "Default Project",
|
||||
"labels": "Labels",
|
||||
"labelsDesc": "Things to remember about this task or to tag it",
|
||||
"addNewLabel": "Add New Label",
|
||||
"subTasks": "Sub Tasks",
|
||||
"attachments": "Attachments",
|
||||
"attachmentsDesc": "Files attached to this task",
|
||||
"uploadFile": "Upload File",
|
||||
"scan": "Scan",
|
||||
"assignees": "Assignees",
|
||||
"assigneesDesc": "Who can do this task?",
|
||||
"anyone": "Anyone",
|
||||
"rememberFuture": "Remember for Future Tasks",
|
||||
"currentlyAssigned": "Currently Assigned To",
|
||||
"currentlyAssignedDesc": "Who is assigned the next due?",
|
||||
"noAssigneesPlaceholder": "No Assignees yet can perform this task",
|
||||
"selectAssigneePlaceholder": "Select an assignee for this task",
|
||||
"assignStrategy": "Assignment Strategy",
|
||||
"assignStrategyDesc": "How to pick the next assignee for the following task?",
|
||||
"strategy": {
|
||||
"random": "Random",
|
||||
"least_assigned": "Least Assigned",
|
||||
"least_completed": "Least Completed",
|
||||
"keep_last_assigned": "Keep Last Assigned",
|
||||
"random_except_last_assigned": "Random Except Last Assigned",
|
||||
"round_robin": "Round Robin",
|
||||
"no_assignee": "No Assignee"
|
||||
},
|
||||
"startDate": "Start Date",
|
||||
"dueDate": "Due Date",
|
||||
"triggerDueHint": "Due Date will be set when the trigger of the thing is met",
|
||||
"giveDueDate": "Give this task a due date",
|
||||
"giveDueDateHelp": "Task needs to be completed by a specific time",
|
||||
"startWhen": "When does this task start?",
|
||||
"dueWhen": "When is the next first time this task is due?",
|
||||
"setSpecificTime": "Set a specific time",
|
||||
"dueAtSpecifiedTime": "Task will be due at the specified time",
|
||||
"dueEndOfDay": "Task will be due at the end of the day (11:59 PM)",
|
||||
"timeLabel": "Time:",
|
||||
"taskWindow": "Task Window",
|
||||
"taskWindowDesc": "Define when this task can be completed and when it expires",
|
||||
"earliestCompletion": "Set earliest completion time",
|
||||
"earliestCompletionHelp": "Task becomes available to complete X hours before the due date",
|
||||
"hoursLabel": "Hours:",
|
||||
"hoursPlaceholder": "Hours",
|
||||
"afterDueDate": "after due date",
|
||||
"schedulingPrefs": "Scheduling Preferences",
|
||||
"schedulingPrefsDesc": "How to reschedule the next due date?",
|
||||
"rescheduleFromDue": "Reschedule from due date",
|
||||
"rescheduleFromDueHelp": "the next task will be scheduled from the original due date, even if the previous task was completed late",
|
||||
"rescheduleFromCompletion": "Reschedule from completion date",
|
||||
"rescheduleFromCompletionHelp": "the next task will be scheduled from the actual completion date of the previous task",
|
||||
"notifications": "Notifications",
|
||||
"notificationsPlanWarning": "Task notifications are not available in the Basic plan. Upgrade to Plus to receive reminders when tasks are due or completed.",
|
||||
"notifyForTask": "Notify for this task",
|
||||
"notifyForTaskHelp": "When should receive notifications for this task",
|
||||
"notificationSchedule": "Notification Schedule",
|
||||
"whoToNotify": "Who to Notify",
|
||||
"allAssignees": "All Assignees",
|
||||
"allAssigneesHelp": "Notify all assignees",
|
||||
"specificGroup": "Specific Group",
|
||||
"specificGroupHelp": "Notify a specific group",
|
||||
"telegramGroupIdLabel": "Telegram Group ID:",
|
||||
"telegramGroupIdPlaceholder": "Telegram Group ID",
|
||||
"taskSettings": "Task Settings:",
|
||||
"pointsSystem": "Points System",
|
||||
"assignPoints": "Assign points for completion",
|
||||
"assignPointsHelp": "Assign points to this task and user will earn points when they completed it",
|
||||
"pointsLabel": "Points:",
|
||||
"pointsPlaceholder": "Points",
|
||||
"approvalRequirement": "Approval Requirement",
|
||||
"requireApproval": "Require admin approval",
|
||||
"requireApprovalHelp": "This task will need approval from an admin before being marked as complete",
|
||||
"privacySettings": "Privacy Settings",
|
||||
"privacyDesc": "Who can see this task?",
|
||||
"public": "Public",
|
||||
"publicHelp": "Everyone in your circle",
|
||||
"limited": "Limited",
|
||||
"limitedHelp": "You and others that are assigned to the task",
|
||||
"limitedDisabledHint": " (No assignees selected, Limited option is disabled)",
|
||||
"createdBy": "Created by",
|
||||
"updatedBy": "Updated by",
|
||||
"archive": "Archive",
|
||||
"unarchive": "Unarchive",
|
||||
"create": "Create"
|
||||
},
|
||||
"addTask": {
|
||||
"title": "Create new task",
|
||||
"defaultProject": "Default Project",
|
||||
"anyone": "Anyone",
|
||||
"taskPlaceholder": "Type your task...",
|
||||
"descriptionChip": "Description",
|
||||
"subtasksChip": "Subtasks",
|
||||
"creating": "Creating…",
|
||||
"createCount": "Create {{count}} Tasks",
|
||||
"useTask": "Use Task",
|
||||
"processing": "Processing",
|
||||
"create": "Create"
|
||||
},
|
||||
"repeat": {
|
||||
"days": {
|
||||
"monday": "Monday",
|
||||
"tuesday": "Tuesday",
|
||||
"wednesday": "Wednesday",
|
||||
"thursday": "Thursday",
|
||||
"friday": "Friday",
|
||||
"saturday": "Saturday",
|
||||
"sunday": "Sunday"
|
||||
},
|
||||
"months": {
|
||||
"january": "January",
|
||||
"february": "February",
|
||||
"march": "March",
|
||||
"april": "April",
|
||||
"may": "May",
|
||||
"june": "June",
|
||||
"july": "July",
|
||||
"august": "August",
|
||||
"september": "September",
|
||||
"october": "October",
|
||||
"november": "November",
|
||||
"december": "December"
|
||||
},
|
||||
"freqType": {
|
||||
"daily": "Daily",
|
||||
"weekly": "Weekly",
|
||||
"monthly": "Monthly",
|
||||
"yearly": "Yearly",
|
||||
"adaptive": "Adaptive",
|
||||
"custom": "Custom"
|
||||
},
|
||||
"freqMessage": {
|
||||
"adaptive": "This chore will be scheduled dynamically based on previous completion dates.",
|
||||
"custom": "This chore will be scheduled based on a custom frequency."
|
||||
},
|
||||
"weekPattern": {
|
||||
"every_week": "Every week",
|
||||
"week_of_month": "Specific occurrences in the month"
|
||||
},
|
||||
"weekPatternHelp": {
|
||||
"every_week": "Task repeats every week on selected days",
|
||||
"week_of_month": "Task repeats on specific day occurrences each month (e.g., 1st Monday, 3rd Friday)"
|
||||
},
|
||||
"occurrence": {
|
||||
"1": "1st occurrence",
|
||||
"2": "2nd occurrence",
|
||||
"3": "3rd occurrence",
|
||||
"4": "4th occurrence",
|
||||
"last": "Last occurrence"
|
||||
},
|
||||
"ordinal": {
|
||||
"1": "1st",
|
||||
"2": "2nd",
|
||||
"3": "3rd",
|
||||
"4": "4th",
|
||||
"last": "last"
|
||||
},
|
||||
"unit": {
|
||||
"hours": "Hours",
|
||||
"days": "Days",
|
||||
"weeks": "Weeks",
|
||||
"months": "Months",
|
||||
"years": "Years"
|
||||
},
|
||||
"repeatOnType": {
|
||||
"interval": "Interval",
|
||||
"days_of_the_week": "Days of the week",
|
||||
"day_of_the_month": "Day of the month"
|
||||
},
|
||||
"timeOfDay": "Time of day: ",
|
||||
"every": "Every: ",
|
||||
"unitPlaceholder": "Unit",
|
||||
"selectAll": "Select All",
|
||||
"unselectAll": "Unselect All",
|
||||
"selectOccurrences": "Select which occurrences of the selected days:",
|
||||
"occurrenceExample": "Example: \"1st Monday\" means the first Monday of each month",
|
||||
"onThe": "on the ",
|
||||
"ofAboveMonths": "of the above month/s",
|
||||
"title": "Repeat:",
|
||||
"repeatThisTask": "Repeat this task",
|
||||
"repeatThisTaskHelp": "Is this something needed to be done regularly?",
|
||||
"howOften": "How often should it be repeated?",
|
||||
"repeatOn": "Repeat on:",
|
||||
"triggerLabel": "Trigger this task based on a thing state",
|
||||
"triggerHelp": "Is this something that should be done when a thing state changes?",
|
||||
"triggerPlanWarning": "Thing-based triggers are not available in the Basic plan. Upgrade to Plus to automatically trigger tasks when device states change.",
|
||||
"previewEvery": "Every {{days}} at {{time}}",
|
||||
"previewOccurrence": "Every {{occurrences}} {{days}} of the month at {{time}}",
|
||||
"defaultTime": "6:00 PM",
|
||||
"daysShort": {
|
||||
"monday": "Mon",
|
||||
"tuesday": "Tue",
|
||||
"wednesday": "Wed",
|
||||
"thursday": "Thu",
|
||||
"friday": "Fri",
|
||||
"saturday": "Sat",
|
||||
"sunday": "Sun"
|
||||
},
|
||||
"monthsShort": {
|
||||
"january": "Jan",
|
||||
"february": "Feb",
|
||||
"march": "Mar",
|
||||
"april": "Apr",
|
||||
"may": "May",
|
||||
"june": "Jun",
|
||||
"july": "Jul",
|
||||
"august": "Aug",
|
||||
"september": "Sep",
|
||||
"october": "Oct",
|
||||
"november": "Nov",
|
||||
"december": "Dec"
|
||||
},
|
||||
"occurrenceShort": {
|
||||
"1": "1st",
|
||||
"2": "2nd",
|
||||
"3": "3rd",
|
||||
"4": "4th",
|
||||
"last": "Last"
|
||||
},
|
||||
"picker": {
|
||||
"modalTitle": "Repeat Schedule",
|
||||
"trigger": "Repeat",
|
||||
"clearAria": "Clear repeat schedule",
|
||||
"remove": "Remove",
|
||||
"apply": "Apply",
|
||||
"frequency": "Frequency",
|
||||
"scheduleType": "Schedule type",
|
||||
"timeOfDay": "Time of day",
|
||||
"repeatEvery": "Repeat every",
|
||||
"days": "Days",
|
||||
"pattern": "Pattern",
|
||||
"everyWeek": "Every week",
|
||||
"specificWeeks": "Specific weeks",
|
||||
"occurrences": "Occurrences",
|
||||
"months": "Months",
|
||||
"dayOfMonth": "Day of month"
|
||||
}
|
||||
},
|
||||
"advancedOptions": {
|
||||
"points": "Points",
|
||||
"pointsDescription": "Award points for completing this task",
|
||||
"requireApproval": "Require approval",
|
||||
"requireApprovalDescription": "Task needs admin sign-off before it can be closed",
|
||||
"limitedVisibility": "Limited visibility",
|
||||
"limitedVisibilityDisabled": "Assign someone to enable limited visibility",
|
||||
"limitedVisibilityDescription": "Only you and assignees can see this task",
|
||||
"assignStrategy": "Assign strategy",
|
||||
"assignStrategyDescription": "How to pick the next assignee each recurrence",
|
||||
"availableFrom": "Available from",
|
||||
"availableFromDescription": "Hours before the due date the task becomes available",
|
||||
"strategy": {
|
||||
"keep_last_assigned": "Keep same assignee",
|
||||
"random": "Random",
|
||||
"least_completed": "Least completed",
|
||||
"round_robin": "Round robin"
|
||||
},
|
||||
"hrs": "hrs",
|
||||
"setDueDateHint": "Set a due date to configure completion window",
|
||||
"more": "More"
|
||||
},
|
||||
"filterBuilder": {
|
||||
"dueDateOption": {
|
||||
"isOverdue": "Overdue",
|
||||
"isDueToday": "Today",
|
||||
"isDueTomorrow": "Tomorrow",
|
||||
"isDueThisWeek": "This Week",
|
||||
"isDueThisMonth": "This Month",
|
||||
"hasNoDueDate": "No Due Date",
|
||||
"hasDueDate": "Has Due Date"
|
||||
},
|
||||
"status": {
|
||||
"0": "Active",
|
||||
"1": "Started",
|
||||
"2": "In Progress",
|
||||
"3": "Pending Approval"
|
||||
},
|
||||
"include": "Include",
|
||||
"exclude": "Exclude",
|
||||
"has": "Has",
|
||||
"doesntHave": "Doesn't Have",
|
||||
"assignee": "Assignee",
|
||||
"createdBy": "Created By",
|
||||
"statusHeading": "Status",
|
||||
"priority": "Priority",
|
||||
"dueDate": "Due Date",
|
||||
"labels": "Labels",
|
||||
"projects": "Projects",
|
||||
"defaultProject": "Default Project",
|
||||
"points": "Points",
|
||||
"project": "Project",
|
||||
"filterFallback": "Filter",
|
||||
"notPrefix": "Not ",
|
||||
"customDueDate": "Custom",
|
||||
"clear": "Clear"
|
||||
},
|
||||
"empty": {
|
||||
"errorTitle": "Can't reach Donetick",
|
||||
"errorDescription": "Your tasks are safe. We just could not load them right now, check your connection and try again.",
|
||||
"errorAction": "Try again",
|
||||
"noTasksTitle": "No tasks yet",
|
||||
"noTasksDescription": "Create your first task and Donetick keeps track of when it is due, whose turn it is, and what comes next.",
|
||||
"createTask": "Create a task",
|
||||
"moreOptions": "More options",
|
||||
"noMatchTitle": "No tasks match this view",
|
||||
"noMatchSearch": "Nothing matches \"{{term}}\". Try a different search, or clear what is narrowing the list.",
|
||||
"noMatchFilters": "You have tasks, but none of them fit the filters that are currently on.",
|
||||
"clearSearch": "Clear search",
|
||||
"showEveryone": "Show everyone's tasks",
|
||||
"clearFilters": "Clear filters",
|
||||
"projectTitle": "Nothing in {{name}} yet",
|
||||
"projectDescription": "Tasks you add to this project show up here. Your other tasks are still where you left them.",
|
||||
"addTaskHere": "Add a task here",
|
||||
"seeOutsideProjects": "See tasks outside projects",
|
||||
"noProjectTitle": "No tasks here yet",
|
||||
"noProjectDescription": "Tasks that do not belong to a project live here. Add one, or switch projects to see what is in them.",
|
||||
"dayFreeDescription": "This day is free. Add a task if you want something to land here.",
|
||||
"addTask": "Add task",
|
||||
"assignee": {
|
||||
"assigned_to_me": "There are tasks here, but none of them are assigned to you. Switch back to everyone to see the rest.",
|
||||
"available_for_me": "There are tasks here, but none of them are available for you to pick up. Switch back to everyone to see the rest.",
|
||||
"assigned_to_others": "There are tasks here, but none of them are assigned to someone else. Switch back to everyone to see the rest.",
|
||||
"assigned_to_me_tasks": "There are tasks here, but none of them are assigned to you. Switch back to everyone to see the rest.",
|
||||
"created_by_me": "There are tasks here, but none of them are created by you. Switch back to everyone to see the rest."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,32 @@
|
||||
"error": "Error",
|
||||
"success": "Success",
|
||||
"warning": "Warning",
|
||||
"colors": {
|
||||
"Salmon": "Salmon",
|
||||
"Teal": "Teal",
|
||||
"Sky Blue": "Sky Blue",
|
||||
"Grape": "Grape",
|
||||
"Sunshine": "Sunshine",
|
||||
"Coral": "Coral",
|
||||
"Lavender": "Lavender",
|
||||
"Rose": "Rose",
|
||||
"Charcoal": "Charcoal",
|
||||
"Sienna": "Sienna",
|
||||
"Mint": "Mint",
|
||||
"Amber": "Amber",
|
||||
"Cobalt": "Cobalt",
|
||||
"Emerald": "Emerald",
|
||||
"Peach": "Peach",
|
||||
"Ocean": "Ocean",
|
||||
"Mustard": "Mustard",
|
||||
"Ruby": "Ruby",
|
||||
"Periwinkle": "Periwinkle",
|
||||
"Turquoise": "Turquoise",
|
||||
"Lime": "Lime",
|
||||
"Blush": "Blush",
|
||||
"Ash": "Ash",
|
||||
"Sand": "Sand"
|
||||
},
|
||||
"refresh": "Refresh",
|
||||
"copy": "Copy",
|
||||
"copied": "Copied!",
|
||||
@@ -20,6 +46,7 @@
|
||||
"logout": "Logout",
|
||||
"version": "Version",
|
||||
"navigation": {
|
||||
"search": "Search",
|
||||
"allTasks": "All Tasks",
|
||||
"archived": "Archived",
|
||||
"things": "Things",
|
||||
@@ -28,7 +55,70 @@
|
||||
"filters": "Filters",
|
||||
"activities": "Activities",
|
||||
"points": "Points",
|
||||
"settings": "Settings"
|
||||
"settings": "Settings",
|
||||
"reportBug": "Report an Issue"
|
||||
},
|
||||
"search": {
|
||||
"title": "Search",
|
||||
"placeholder": "Search Donetick",
|
||||
"inputAriaLabel": "Search tasks, history, projects, labels and settings",
|
||||
"deviceNote": "Searching content available on this device",
|
||||
"escape": "Esc",
|
||||
"recent": "Recent",
|
||||
"empty": {
|
||||
"title": "No direct matches",
|
||||
"subtitle": "You can still filter the task list with this search.",
|
||||
"actionsSubtitle": "No view or action matches. Press backspace to search everything."
|
||||
},
|
||||
"groups": {
|
||||
"tasks": "Tasks",
|
||||
"history": "Notes",
|
||||
"projects": "Projects",
|
||||
"labels": "Labels",
|
||||
"people": "People",
|
||||
"settings": "Settings",
|
||||
"actions": "Quick actions"
|
||||
},
|
||||
"actions": {
|
||||
"quickAction": "Quick action",
|
||||
"navigation": "Navigation",
|
||||
"createTask": "Create a task",
|
||||
"createLabel": "Create a label",
|
||||
"createProject": "Create a project",
|
||||
"createFilter": "Create a filter",
|
||||
"viewAllTasks": "View all tasks",
|
||||
"viewArchivedTasks": "View archived tasks",
|
||||
"viewThings": "View things",
|
||||
"viewLabels": "View labels",
|
||||
"viewProjects": "View projects",
|
||||
"viewFilters": "View filters",
|
||||
"viewActivities": "View activities",
|
||||
"viewPoints": "View points",
|
||||
"openSettings": "Open settings",
|
||||
"filterTasks": "Show tasks matching “{{query}}”",
|
||||
"filterTasksSubtitle": "Filter the task list"
|
||||
},
|
||||
"footer": {
|
||||
"navigate": "Navigate",
|
||||
"open": "Open",
|
||||
"results_one": "{{count}} result",
|
||||
"results_other": "{{count}} results",
|
||||
"typeToSearch": "Type to search",
|
||||
"slashHint": "/ to jump to a view"
|
||||
},
|
||||
"modes": {
|
||||
"actions": {
|
||||
"label": "Go to",
|
||||
"placeholder": "Jump to a view or action"
|
||||
}
|
||||
}
|
||||
},
|
||||
"policyUpdate": {
|
||||
"title": "We've updated our Privacy Policy and Terms",
|
||||
"subtitle": "Please take a moment to review them. By continuing to use Donetick, you accept the updated documents.",
|
||||
"readPrivacy": "Privacy Policy",
|
||||
"readTerms": "Terms",
|
||||
"acknowledge": "Got it"
|
||||
},
|
||||
"feedback": {
|
||||
"later": "Maybe later",
|
||||
@@ -75,5 +165,295 @@
|
||||
"subtitle": "We've filled in an issue with your notes and version details. Nothing has been sent yet — review it and post when you're ready.",
|
||||
"open": "Open the issue"
|
||||
}
|
||||
},
|
||||
"done": "Done",
|
||||
"clearAll": "Clear all",
|
||||
"upload": {
|
||||
"quotaTitle": "Storage Quota Exceeded",
|
||||
"quotaMessage": "You have exceeded your quota for uploading files.",
|
||||
"tooLargeTitle": "File Too Large",
|
||||
"tooLargeMessage": "The file you are trying to upload is too large.",
|
||||
"deniedTitle": "Permission Denied",
|
||||
"deniedMessage": "You do not have permission to upload files.",
|
||||
"plusFeatureTitle": "Plus Feature",
|
||||
"plusFeatureMessage": "Image uploads are not available in the Basic plan. Upgrade to Plus to add images to your content.",
|
||||
"upgradeTitle": "Upgrade Required",
|
||||
"upgradeMessage": "Image uploads are only available for Plus accounts.",
|
||||
"failedTitle": "Upload Failed",
|
||||
"failedMessage": "Failed to upload image.",
|
||||
"processingMessage": "An error occurred while processing the image."
|
||||
},
|
||||
"getStarted": "Get Started!",
|
||||
"imageLoadFailed": "Failed to load image.",
|
||||
"typeHere": "Type in here…",
|
||||
"summaryOfChores": "This is a summary of your chores",
|
||||
"loadingOffline": "You are offline",
|
||||
"loadingOfflineSub": "This not available while offline. Please check your internet connection and try again.",
|
||||
"loadingSlow": "This is taking longer than usual. There might be an issue.",
|
||||
"navigateBack": "Navigate Back",
|
||||
"bottomNav": "Bottom Navigation",
|
||||
"profile": "Profile",
|
||||
"autocompletePlaceholder": "Type here...",
|
||||
"errorScreen": {
|
||||
"title": "Something went wrong",
|
||||
"fallback": "An unexpected error occurred. Try reloading — it usually fixes it.",
|
||||
"tryAgain": "Try again",
|
||||
"home": "Home",
|
||||
"login": "Login",
|
||||
"hideDetails": "Hide error details",
|
||||
"showDetails": "Show error details",
|
||||
"copyToClipboard": "Copy to clipboard",
|
||||
"copied": "Error details copied to clipboard"
|
||||
},
|
||||
"userMenu": {
|
||||
"actAsAnother": "Act as another user",
|
||||
"stopImpersonating": "Stop Impersonating",
|
||||
"returnToAccount": "Return to your account",
|
||||
"accountPrefs": "Account & preferences",
|
||||
"invitePeople": "Invite People",
|
||||
"addMembers": "Add members to your circle",
|
||||
"sidePanelSettings": "Side Panel Settings",
|
||||
"planFree": "Free",
|
||||
"planPlus": "Plus",
|
||||
"planPlusExpiring": "Plus (expires soon)",
|
||||
"switchUser": "Switch User",
|
||||
"impersonateUser": "Impersonate User",
|
||||
"switchToLight": "Switch to Light",
|
||||
"switchToDark": "Switch to Dark",
|
||||
"unlockPremium": "Unlock premium features",
|
||||
"impersonating": "Impersonating",
|
||||
"toggleThemeAppearance": "Toggle theme appearance",
|
||||
"upgradeToPlus": "Upgrade to Plus"
|
||||
},
|
||||
"realtime": {
|
||||
"newTaskTitle": "New Task Created",
|
||||
"connected": "You are now receiving real-time as they happen.",
|
||||
"errorTitle": "Real-time Error",
|
||||
"parseTitle": "Message Error",
|
||||
"parseMessage": "Failed to parse server message",
|
||||
"disabledTitle": "Connection Temporarily Disabled",
|
||||
"failedTitle": "Connection Failed",
|
||||
"stateConnectionError": "Connection error occurred",
|
||||
"stateAuthExpired": "Authentication expired - refreshing token...",
|
||||
"stateTokenRefreshed": "Token refreshed - reconnecting...",
|
||||
"stateRefreshInProgress": "Token refresh in progress - reconnecting soon...",
|
||||
"stateSessionExpired": "Session expired - please log in again",
|
||||
"stateAuthFailed": "Authentication failed - please log in again",
|
||||
"stateAuthError": "Authentication error - please log in again",
|
||||
"stateTimeout": "Connection timeout - reconnecting...",
|
||||
"connectErrorTitle": "Connection Error",
|
||||
"connectErrorMessage": "Failed to establish real-time connection. Please try again."
|
||||
},
|
||||
"removeAll": "Remove all",
|
||||
"apply": "Apply",
|
||||
"cancelAll": "Cancel all",
|
||||
"sync": {
|
||||
"aria": "Open sync and network status",
|
||||
"allSynced": "All changes synced",
|
||||
"willSync": "Will sync when back online",
|
||||
"cancelAll": "Cancel All"
|
||||
},
|
||||
"attachments": "Attachments",
|
||||
"fileNumbered": "File {{index}}",
|
||||
"onboarding": {
|
||||
"sources": {
|
||||
"speak": "Speak",
|
||||
"snap": "Snap",
|
||||
"type": "Type"
|
||||
},
|
||||
"capture": {
|
||||
"voiceCaption": "Dates, labels and points from your words",
|
||||
"deviceCaption": "Read on your device",
|
||||
"typeCaption": "#labels @people *points as you type",
|
||||
"trashTitle": "♻️ Take out the trash",
|
||||
"trashDue": "Due tomorrow",
|
||||
"trashRepeat": "Every Monday",
|
||||
"homeLabel": "Home",
|
||||
"vehicleTitle": "🚗 Vehicle Registration Renewal",
|
||||
"vehicleDue": "Due Aug 3",
|
||||
"acTitle": "💨 Change the AC filter",
|
||||
"acDue": "Due Fri",
|
||||
"acRepeat": "Every 3 months"
|
||||
},
|
||||
"schedule": {
|
||||
"fromDueDate": "Reschedule from due date",
|
||||
"fromCompletionDate": "Reschedule from completion date",
|
||||
"due": "Due",
|
||||
"done": "Done",
|
||||
"next": "Next"
|
||||
},
|
||||
"nfc": {
|
||||
"tagOnWasher": "Tag on the washer",
|
||||
"tapToOpen": "Tap to open",
|
||||
"swapFilter": "Swap the washer filter",
|
||||
"done": "Done",
|
||||
"skip": "Skip",
|
||||
"startTimer": "Start timer",
|
||||
"waitingApproval": "{{name}} marked it done · waiting on you",
|
||||
"approve": "Approve",
|
||||
"reject": "Reject",
|
||||
"completed": "Completed",
|
||||
"note": "Used the delicate cycle — filter needs a clean next time.",
|
||||
"metaJustNow": "Just now · ★ 5 pts",
|
||||
"metaLastWeek": "Last week · ★ 5 pts"
|
||||
},
|
||||
"circle": {
|
||||
"kitchenTitle": "Kitchen deep clean",
|
||||
"kitchenDue": "Due Sat",
|
||||
"kitchenRepeat": "Every week",
|
||||
"takesTurns": "Takes turns"
|
||||
},
|
||||
"turns": {
|
||||
"binsTitle": "🗑️ Take bins to the curb",
|
||||
"binsDue": "Due Tomorrow",
|
||||
"binsRepeat": "Every week",
|
||||
"completed": "Completed",
|
||||
"metaJustNow": "Just now · ★ 5 pts"
|
||||
},
|
||||
"widget": {
|
||||
"schoolForms": "School forms",
|
||||
"takeOutTrash": "Take out the trash",
|
||||
"waterPlants": "Water the plants",
|
||||
"today": "Today",
|
||||
"left": "{{count}} left"
|
||||
},
|
||||
"reminders": {
|
||||
"trashTitle": "Take out the trash",
|
||||
"trashBody": "Due in 30 minutes · Bin night",
|
||||
"finishedTitle": "Amalie finished Kitchen deep clean",
|
||||
"finishedBody": "Your turn is next Saturday"
|
||||
},
|
||||
"things": {
|
||||
"waterBill": "Water bill",
|
||||
"acFilter": "AC filter",
|
||||
"trashDay": "Trash day",
|
||||
"dogMedicine": "Dog's medicine",
|
||||
"whoseTurn": "Whose turn to cook",
|
||||
"monthly": "Monthly",
|
||||
"everyThreeMonths": "Every 3 months",
|
||||
"everyMonday": "Every Monday",
|
||||
"daily": "Daily",
|
||||
"weekly": "Weekly",
|
||||
"tagBills": "Bills",
|
||||
"tagHome": "Home",
|
||||
"tagPets": "Pets",
|
||||
"tagCooking": "Cooking"
|
||||
},
|
||||
"slides": {
|
||||
"problemTitle": "Stop forgetting the little things",
|
||||
"problemBody": "Donetick remembers the last time it happened, and when it's due next. So nobody else has to.",
|
||||
"captureTitle": "Add it before you forget it",
|
||||
"captureBody": "Type it, say it out loud, or snap a photo. Donetick fills in the due date, priority, labels, and who's on it.",
|
||||
"scheduleTitle": "It comes back exactly when it should",
|
||||
"scheduleBody": "Every week, every 3 months, or a month after you actually did it. Finishing late doesn't throw the rest of the year off.",
|
||||
"circleTitle": "Everyone gets a turn, No more arguing",
|
||||
"circleBody": "Rotate in the order you pick, or at random. Donetick remembers who went last, so turns stay fair.",
|
||||
"remindersTitle": "A nudge right when it matters & Widgets!",
|
||||
"remindersBody": "Get a reminder before something's due, or send a heads-up when someone forgets theirs. Today's list sits on your home screen too."
|
||||
},
|
||||
"carousel": {
|
||||
"skip": "Skip",
|
||||
"ariaLabel": "What you can do with Donetick",
|
||||
"goToStep": "Go to step {{number}}",
|
||||
"slidePosition": "{{index}} of {{total}}",
|
||||
"turnOnReminders": "Turn on reminders",
|
||||
"notNow": "Not now",
|
||||
"next": "Next"
|
||||
},
|
||||
"heardAbout": {
|
||||
"title": "Where'd you hear about Donetick?",
|
||||
"subtitle": "Helps us know what's working. Totally optional.",
|
||||
"detailPlaceholder": "Tell us where",
|
||||
"continue": "Continue",
|
||||
"skip": "Skip",
|
||||
"sources": {
|
||||
"appStore": "App Store / Google Play",
|
||||
"reddit": "Reddit or a forum",
|
||||
"friend": "Friend or family",
|
||||
"video": "YouTube or TikTok",
|
||||
"search": "Search engine",
|
||||
"other": "Something else"
|
||||
}
|
||||
},
|
||||
"privacy": {
|
||||
"title": "Help us improve Donetick",
|
||||
"subtitle": "Your server, your data. Both of these are off from this point unless you turn them on.",
|
||||
"crashReportsLabel": "Share crash reports",
|
||||
"crashReportsDescription": "When Donetick crashes, send us the error and what led to it (device, app version, the screen you were on) no task content. It's how we catch bugs that never show up in our own testing and ship fixes faster.",
|
||||
"analyticsLabel": "Share anonymous usage analytics",
|
||||
"analyticsDescription": "Send anonymous usage events which features get used, which get ignored so we know what to build next instead of guessing. No task content, no personal data, nothing tied back to you."
|
||||
}
|
||||
},
|
||||
"errorReport": {
|
||||
"titleBug": "Report an issue",
|
||||
"titleCrash": "Report this problem",
|
||||
"subtitleBug": "Tell us what went wrong and we’ll attach the technical details for you.",
|
||||
"subtitleCrash": "A sentence about what you were doing turns this into something we can actually fix.",
|
||||
"labelBug": "What went wrong?",
|
||||
"labelCrash": "What were you doing?",
|
||||
"placeholderBug": "e.g. Completing a chore from the list doesn’t update the due date",
|
||||
"placeholderCrash": "e.g. I tapped a chore in My Chores and the screen went blank",
|
||||
"email": "Email",
|
||||
"emailOptional": "(optional — only if you want a reply)",
|
||||
"emailPlaceholder": "you@example.com",
|
||||
"showWhatGetsSent": "Show what gets sent",
|
||||
"hideWhatGetsSent": "Hide what gets sent",
|
||||
"copyDiagnostics": "Copy diagnostics",
|
||||
"collecting": "Collecting diagnostics…",
|
||||
"privacyNote": "No chore names, notes or attachments are included.",
|
||||
"send": "Send report",
|
||||
"cancel": "Cancel",
|
||||
"notNow": "Not now",
|
||||
"sentTitle": "Report sent",
|
||||
"sentBody": "Thanks! this goes straight to the people who can fix it.",
|
||||
"reference": "Reference",
|
||||
"copyReference": "Copy reference",
|
||||
"done": "Done",
|
||||
"githubTitle": "Finish on GitHub",
|
||||
"githubBody": "Nothing has been sent. We've filled in an issue with your notes and the diagnostics — review it and post when you're happy with it.",
|
||||
"openIssue": "Open pre-filled issue",
|
||||
"copied": "Copied",
|
||||
"copyInstead": "Copy details instead",
|
||||
"close": "Close"
|
||||
},
|
||||
"circleSetup": {
|
||||
"inviteTitle": "Bring your squad in",
|
||||
"inviteSubtitle": "Everyone who joins your Circle sees the same chores, takes their own turn, and stays in sync automatically.",
|
||||
"joinTitle": "Join a circle",
|
||||
"joinSubtitle": "Enter the code you were given and we'll send a request to join — the circle owner just needs to approve it.",
|
||||
"loadingCode": "Loading…",
|
||||
"copyCodeAria": "Copy circle code",
|
||||
"copyLinkInstead": "Copy invite link instead",
|
||||
"continue": "Continue",
|
||||
"joinInstead": "Join an existing circle instead",
|
||||
"codePlaceholder": "Enter code",
|
||||
"joinButton": "Join Circle",
|
||||
"back": "Back",
|
||||
"codeCopied": "Code copied to clipboard",
|
||||
"linkCopied": "Link copied to clipboard",
|
||||
"requestSentTitle": "Request Sent",
|
||||
"requestSentBody": "Your join request has been sent! The circle owner will need to approve it before you can see their chores. You'll get a notification once you're in.",
|
||||
"alreadyMember": "You are already a member of this circle",
|
||||
"joinFailed": "Failed to join circle"
|
||||
},
|
||||
"joinCircle": {
|
||||
"title": "You're invited to join a circle",
|
||||
"incompleteTitle": "Invite link is incomplete",
|
||||
"incompleteSubtitle": "This invite link is missing a code. Ask the person who invited you to send a new link.",
|
||||
"goToDonetick": "Go to Donetick",
|
||||
"signedOutSubtitle": "Sign in or create a Donetick account to continue. We'll send your join request once you're signed in.",
|
||||
"signIn": "Sign in",
|
||||
"createAccount": "Create an account",
|
||||
"sendingTitle": "Sending your request",
|
||||
"sendingSubtitle": "Sending your request…",
|
||||
"greetingSubtitle": "Hi {{name}}. Send a request to share this circle's chores with its members.",
|
||||
"adminReviewNote": "A circle admin will review your request before you get access.",
|
||||
"sendRequest": "Send join request",
|
||||
"requestSentTitle": "Request sent",
|
||||
"requestSentBody": "Your request has been sent. A circle admin will need to approve it before you can access the circle and its chores. We'll notify you when it's approved.",
|
||||
"gotIt": "Got it",
|
||||
"alreadyMember": "You are already a member of this circle",
|
||||
"joinFailed": "Failed to join circle",
|
||||
"requestError": "Could not send your join request. Please try again."
|
||||
}
|
||||
}
|
||||
|
||||
23
public/locales/en/filters.json
Normal file
23
public/locales/en/filters.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"builder": {
|
||||
"errorName": "Please enter a filter name",
|
||||
"errorConditions": "Please configure at least one filter condition",
|
||||
"editTitle": "Edit Filter",
|
||||
"newTitle": "New Filter",
|
||||
"addConditions": "Add conditions to preview",
|
||||
"save": "Save Filter",
|
||||
"name": "Filter Name",
|
||||
"namePlaceholder": "e.g. Overdue tasks for Alice",
|
||||
"color": "Color"
|
||||
},
|
||||
"nameExists": "A filter with this name already exists",
|
||||
"tasks_one": "{{count}} task",
|
||||
"tasks_other": "{{count}} tasks",
|
||||
"overdue": "{{count}} overdue",
|
||||
"delete": {
|
||||
"title": "Delete Filter"
|
||||
},
|
||||
"empty": {
|
||||
"title": "No saved filters yet"
|
||||
}
|
||||
}
|
||||
126
public/locales/en/history.json
Normal file
126
public/locales/en/history.json
Normal file
@@ -0,0 +1,126 @@
|
||||
{
|
||||
"edit": {
|
||||
"title": "Edit History",
|
||||
"completedDate": "Completed Date",
|
||||
"note": "Note",
|
||||
"additionalNotes": "Additional Notes",
|
||||
"deleteTitle": "Delete History",
|
||||
"deleteMessage": "Are you sure you want to delete this history?"
|
||||
},
|
||||
"status": {
|
||||
"inProgress": "In Progress",
|
||||
"completed": "Completed",
|
||||
"skipped": "Skipped",
|
||||
"pendingApproval": "Pending Approval",
|
||||
"rejected": "Rejected",
|
||||
"missed": "Missed",
|
||||
"rescheduled": "Rescheduled",
|
||||
"scheduled": "Scheduled"
|
||||
},
|
||||
"badge": {
|
||||
"onTime": "On Time",
|
||||
"onTimeLabel": "On time"
|
||||
},
|
||||
"card": {
|
||||
"wasDue": "Was due {{date}}",
|
||||
"daysBeforeDue_one": "{{count}}d before due date",
|
||||
"daysBeforeDue_other": "{{count}}d before due date",
|
||||
"daysAfterDue_one": "{{count}}d after due date",
|
||||
"daysAfterDue_other": "{{count}}d after due date",
|
||||
"hoursBeforeDue_one": "{{count}}h before due date",
|
||||
"hoursBeforeDue_other": "{{count}}h before due date",
|
||||
"hoursAfterDue_one": "{{count}}h after due date",
|
||||
"hoursAfterDue_other": "{{count}}h after due date",
|
||||
"assignedTo": "Assigned to {{name}}",
|
||||
"points_one": "★ {{count}} pt",
|
||||
"points_other": "★ {{count}} pts"
|
||||
},
|
||||
"detail": {
|
||||
"title": "Activity Detail",
|
||||
"openTask": "Open Task",
|
||||
"editEntry": "Edit Entry",
|
||||
"performedBy": "Performed by",
|
||||
"assignedTo": "Assigned to",
|
||||
"lastUpdated": "Last updated",
|
||||
"duration": "Duration",
|
||||
"pointsEarned": "Points earned",
|
||||
"points_one": "{{count}} pt",
|
||||
"points_other": "{{count}} pts",
|
||||
"note": "Note"
|
||||
},
|
||||
"charts": {
|
||||
"noData": "No data available",
|
||||
"noLabels": "No Labels",
|
||||
"unassigned": "Unassigned",
|
||||
"unknownTask": "Unknown Task",
|
||||
"late": "Late",
|
||||
"status": {
|
||||
"title": "Status",
|
||||
"description": "Completed tasks status"
|
||||
},
|
||||
"due": {
|
||||
"title": "Due Date",
|
||||
"description": "Current tasks due date"
|
||||
},
|
||||
"priority": {
|
||||
"title": "Priority",
|
||||
"description": "Tasks by priority"
|
||||
},
|
||||
"labels": {
|
||||
"title": "Labels",
|
||||
"description": "Tasks by labels"
|
||||
},
|
||||
"labelsDuration": {
|
||||
"title": "Labels (time)",
|
||||
"description": "Time spent by labels (hours)"
|
||||
},
|
||||
"tasksTime": {
|
||||
"title": "Tasks (time)",
|
||||
"description": "Time spent by individual tasks (hours)"
|
||||
},
|
||||
"assigneeBreakdown": {
|
||||
"title": "by Assignee",
|
||||
"description": "Tasks grouped by assignee"
|
||||
}
|
||||
},
|
||||
"filter": {
|
||||
"status": "Status",
|
||||
"pending": "Pending",
|
||||
"labels": "Labels",
|
||||
"hasNotes": "Has Notes",
|
||||
"hasPoints": "Has Points",
|
||||
"timePeriod": "Time Period",
|
||||
"user": "User",
|
||||
"completedBy": "Completed By",
|
||||
"completedAt": "Completed At"
|
||||
},
|
||||
"period": {
|
||||
"days_one": "{{count}} Day",
|
||||
"days_other": "{{count}} Days",
|
||||
"allTime": "All Time"
|
||||
},
|
||||
"activities": {
|
||||
"title": "Activities"
|
||||
},
|
||||
"title": {
|
||||
"summary": "Task Summary",
|
||||
"activity": "Task Activity"
|
||||
},
|
||||
"noResults": {
|
||||
"clear": "Clear filters"
|
||||
},
|
||||
"toast": {
|
||||
"updateQueued": {
|
||||
"title": "History Update Queued"
|
||||
},
|
||||
"updated": {
|
||||
"title": "History Updated"
|
||||
},
|
||||
"deleteQueued": {
|
||||
"title": "History Delete Queued"
|
||||
},
|
||||
"deleted": {
|
||||
"title": "History Deleted"
|
||||
}
|
||||
}
|
||||
}
|
||||
47
public/locales/en/labels.json
Normal file
47
public/locales/en/labels.json
Normal file
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"shared": "Shared",
|
||||
"delete": {
|
||||
"title": "Delete Label",
|
||||
"message": "Are you sure you want to delete this label? This will remove the label from all tasks."
|
||||
},
|
||||
"loadError": "Failed to load labels. Please try again.",
|
||||
"search": {
|
||||
"placeholder": "Search labels",
|
||||
"noResultsTitle": "No labels match",
|
||||
"noResultsDescription": "No label matches \"{{searchTerm}}\".",
|
||||
"noFilterResultsDescription": "No label matches the current filter.",
|
||||
"clear": "Clear search",
|
||||
"showAll": "Show all labels"
|
||||
},
|
||||
"detail": {
|
||||
"taskCount_one": "{{count}} task",
|
||||
"taskCount_other": "{{count}} tasks",
|
||||
"labelActions": "Label actions",
|
||||
"filters": {
|
||||
"all": "All",
|
||||
"overdue": "Overdue",
|
||||
"today": "Today",
|
||||
"undated": "No date"
|
||||
},
|
||||
"noMatchingStatus": "No task in this label is in that state right now.",
|
||||
"clearFilters": "Show all tasks",
|
||||
"searchPlaceholder": "Search tasks in this label",
|
||||
"emptyTitle": "No tasks with this label",
|
||||
"emptyDescription": "Nothing is tagged \"{{label}}\" yet. Add the label to a task and it will show up here.",
|
||||
"browseTasks": "Browse tasks",
|
||||
"noResultsTitle": "No tasks match",
|
||||
"noResultsDescription": "No task in this label matches \"{{searchTerm}}\".",
|
||||
"notFoundTitle": "Label not found",
|
||||
"notFoundDescription": "This label may have been deleted or is no longer shared with you.",
|
||||
"backToLabels": "Back to labels"
|
||||
},
|
||||
"blurb": "Manage your labels and organize your tasks effectively. Labels will be automatically shared with your circle if they are used on a shared task.",
|
||||
"modal": {
|
||||
"errorEmptyName": "Name cannot be empty",
|
||||
"errorDuplicate": "Label with this name already exists",
|
||||
"errorNoColor": "Please select a color",
|
||||
"saveFailedTitle": "Failed to save label",
|
||||
"saveFailedMessage": "Unable to save label. Please try again.",
|
||||
"name": "Name"
|
||||
}
|
||||
}
|
||||
74
public/locales/en/points.json
Normal file
74
public/locales/en/points.json
Normal file
@@ -0,0 +1,74 @@
|
||||
{
|
||||
"redeem": "Redeem Points",
|
||||
"redeemModal": {
|
||||
"redeemButton": "Redeem",
|
||||
"pointsAvailable": "{{count}} points available",
|
||||
"pointsToRedeem": "Points to Redeem",
|
||||
"placeholder": "Enter points...",
|
||||
"cannotExceed": "Cannot exceed available points",
|
||||
"quickAdd": "Quick Add:",
|
||||
"aboutToRedeem": "You are about to redeem",
|
||||
"amount": "{{count}} points",
|
||||
"remaining": "Remaining: {{count}} points"
|
||||
},
|
||||
"leaderboard": {
|
||||
"titlePoints": "Points Leaderboard",
|
||||
"titleTasks": "Tasks Leaderboard",
|
||||
"subtitlePoints": "Rankings based on points earned during the selected time period",
|
||||
"subtitleTasks": "Rankings based on tasks completed during the selected time period",
|
||||
"modePoints": "Points",
|
||||
"modeTasks": "Tasks",
|
||||
"you": "You",
|
||||
"tasksAndAvg": "{{tasks}} tasks • {{avg}} avg per task",
|
||||
"available": "{{count}} available",
|
||||
"points_one": "{{count}} point",
|
||||
"points_other": "{{count}} points"
|
||||
},
|
||||
"tabs": {
|
||||
"short7d": "7D",
|
||||
"short6m": "6M",
|
||||
"shortAll": "All",
|
||||
"days7": "7 Days",
|
||||
"months6": "6 Months",
|
||||
"allTime": "All Time"
|
||||
},
|
||||
"filter": {
|
||||
"analysisTitle": "Filter & Analysis",
|
||||
"title": "Filter Points",
|
||||
"showFor": "Show points for:",
|
||||
"timePeriod": "Time period:"
|
||||
},
|
||||
"cards": {
|
||||
"available": {
|
||||
"title": "Available",
|
||||
"subtext": "Ready to redeem"
|
||||
},
|
||||
"redeemed": {
|
||||
"title": "Redeemed",
|
||||
"subtext": "Previously used"
|
||||
},
|
||||
"total": {
|
||||
"title": "Total",
|
||||
"subtext": "All time earned"
|
||||
},
|
||||
"period": {
|
||||
"title": "Period Points",
|
||||
"allTime": "All time",
|
||||
"last6Months": "Last 6 months",
|
||||
"lastDays_one": "Last {{count}} day",
|
||||
"lastDays_other": "Last {{count}} days"
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"showingFor": "Showing points for",
|
||||
"unknownUser": "Unknown User",
|
||||
"overThe": "over the",
|
||||
"allTime": "All Time",
|
||||
"last6Months": "Last 6 Months",
|
||||
"lastDays_one": "Last {{count}} Day",
|
||||
"lastDays_other": "Last {{count}} Days"
|
||||
},
|
||||
"trend": {
|
||||
"title": "Points Trend"
|
||||
}
|
||||
}
|
||||
70
public/locales/en/projects.json
Normal file
70
public/locales/en/projects.json
Normal file
@@ -0,0 +1,70 @@
|
||||
{
|
||||
"iconPicker": {
|
||||
"chooseIcon": "Choose Project Icon",
|
||||
"availableIcons": "Available Icons"
|
||||
},
|
||||
"icons": {
|
||||
"FolderOpen": "Folder",
|
||||
"Work": "Work",
|
||||
"Home": "Home",
|
||||
"School": "School",
|
||||
"BusinessCenter": "Business",
|
||||
"Code": "Code",
|
||||
"Build": "Build",
|
||||
"Palette": "Design",
|
||||
"SportsSoccer": "Sports",
|
||||
"FitnessCenter": "Fitness",
|
||||
"ShoppingCart": "Shopping",
|
||||
"Restaurant": "Food",
|
||||
"Flight": "Travel",
|
||||
"Book": "Study",
|
||||
"MusicNote": "Music",
|
||||
"PhotoCamera": "Photo",
|
||||
"Games": "Games",
|
||||
"Science": "Science",
|
||||
"AccountBalance": "Finance",
|
||||
"LocalHospital": "Health",
|
||||
"DirectionsCar": "Auto",
|
||||
"Pets": "Pets",
|
||||
"Garden": "Garden",
|
||||
"Computer": "Tech"
|
||||
},
|
||||
"defaultChip": "Default",
|
||||
"tasks_one": "{{count}} task",
|
||||
"tasks_other": "{{count}} tasks",
|
||||
"shared": "Shared",
|
||||
"delete": {
|
||||
"title": "Delete Project",
|
||||
"message": "Are you sure you want to delete \"{{name}}\"? This will remove the project but keep all tasks (they'll move to the Default Project)."
|
||||
},
|
||||
"loadError": "Failed to load projects. Please try again.",
|
||||
"search": {
|
||||
"placeholder": "Search projects",
|
||||
"noResultsTitle": "No projects match",
|
||||
"noResultsDescription": "No project matches \"{{searchTerm}}\".",
|
||||
"noFilterResultsDescription": "No project matches the current filter.",
|
||||
"clear": "Clear search",
|
||||
"showAll": "Show all projects"
|
||||
},
|
||||
"blurb": "Organize your tasks into projects. Create custom workspaces to keep your tasks organized and easily accessible.",
|
||||
"defaultDescription": "All tasks without a specific project",
|
||||
"selector": {
|
||||
"title": "Projects",
|
||||
"createNew": "Create New Project",
|
||||
"createNewDescription": "Add a custom project workspace",
|
||||
"manage": "Manage Projects",
|
||||
"manageDescription": "View, edit, and organize all projects"
|
||||
},
|
||||
"modal": {
|
||||
"errorNameRequired": "Project name is required",
|
||||
"errorUpdate": "Failed to update project",
|
||||
"errorCreate": "Failed to create project",
|
||||
"namePlaceholder": "Enter project name...",
|
||||
"descriptionPlaceholder": "Optional project description...",
|
||||
"nameLabel": "Project Name",
|
||||
"descriptionLabel": "Description",
|
||||
"iconLabel": "Project Icon",
|
||||
"selectIcon": "Select Icon",
|
||||
"colorLabel": "Project Color"
|
||||
}
|
||||
}
|
||||
@@ -1,106 +1,19 @@
|
||||
{
|
||||
"title": "Settings",
|
||||
"circleSettings": {
|
||||
"title": "Circle settings",
|
||||
"description": "Your account is automatically connected to a Circle when you create or join one. Easily invite friends by sharing the unique Circle code or link below. You'll receive a notification below when someone requests to join your Circle. If you'd like to leave, simply hit the 'Leave Circle' button.",
|
||||
"circleCode": "Circle Code",
|
||||
"copyCode": "Copy Code",
|
||||
"copyLink": "Copy Link",
|
||||
"codeCopied": "Circle code copied!",
|
||||
"linkCopied": "Circle link copied!",
|
||||
"joinCircle": "Join a Circle",
|
||||
"joinCirclePlaceholder": "Enter Circle Code",
|
||||
"join": "Join",
|
||||
"leave": "Leave Circle",
|
||||
"leaveConfirmTitle": "Leave Circle",
|
||||
"leaveConfirmMessage": "Are you sure you want to leave this circle?",
|
||||
"circleMembers": "Circle Members",
|
||||
"circleMemberRequests": "Circle Member Requests",
|
||||
"admin": "Admin",
|
||||
"member": "Member",
|
||||
"pending": "Pending",
|
||||
"accept": "Accept",
|
||||
"reject": "Reject",
|
||||
"makeAdmin": "Make Admin",
|
||||
"makeMember": "Make Member",
|
||||
"remove": "Remove",
|
||||
"webhookURL": "Webhook URL",
|
||||
"webhookDescription": "Enter a webhook URL to receive notifications for circle events",
|
||||
"webhookPlaceholder": "https://your-webhook-url.com"
|
||||
},
|
||||
"accountSettings": {
|
||||
"title": "Account Settings",
|
||||
"subscription": "Subscription",
|
||||
"subscriptionStatus": "Current Plan",
|
||||
"free": "Free",
|
||||
"plus": "Plus",
|
||||
"upgrade": "Upgrade",
|
||||
"cancel": "Cancel",
|
||||
"changePassword": "Change Password",
|
||||
"password": "Password",
|
||||
"dangerZone": "Danger Zone",
|
||||
"dangerZoneDescription": "Once you delete your account, there is no going back. Please be certain.",
|
||||
"deleteAccount": "Delete Account"
|
||||
},
|
||||
"localization": {
|
||||
"title": "Localization",
|
||||
"description": "Customize language, date format, and regional preferences for your account.",
|
||||
"language": "Language",
|
||||
"languageDescription": "Select your preferred language",
|
||||
"dateFormat": "Date Format",
|
||||
"dateFormatDescription": "Choose how dates should be displayed throughout the application",
|
||||
"timeFormat": "Time Format",
|
||||
"timeFormatDescription": "Select 12-hour or 24-hour time format",
|
||||
"12hour": "12-hour (AM/PM)",
|
||||
"24hour": "24-hour",
|
||||
"firstDayOfWeek": "First Day of Week",
|
||||
"firstDayOfWeekDescription": "Select which day starts your week",
|
||||
"sunday": "Sunday",
|
||||
"monday": "Monday",
|
||||
"saturday": "Saturday",
|
||||
"formats": {
|
||||
"mdy": "MM/DD/YYYY (US)",
|
||||
"dmy": "DD/MM/YYYY (Europe)",
|
||||
"ymd": "YYYY-MM-DD (ISO)",
|
||||
"long": "Long format (e.g., January 1, 2024)",
|
||||
"short": "Short format (e.g., Jan 1, 2024)"
|
||||
}
|
||||
},
|
||||
"sidepanel": {
|
||||
"title": "Sidepanel Customization",
|
||||
"description": "Customize the layout and visibility of cards in the sidepanel. This section is only available on large screen devices such as tablets and desktops."
|
||||
},
|
||||
"theme": {
|
||||
"title": "Theme preferences",
|
||||
"description": "Choose how the site looks to you. Select a single theme, or sync with your system and automatically switch between day and night themes.",
|
||||
"themeMode": "Theme mode",
|
||||
"light": "Light",
|
||||
"dark": "Dark",
|
||||
"system": "System"
|
||||
},
|
||||
"notifications": {
|
||||
"settingsSaved": "Settings saved successfully",
|
||||
"settingsSaveFailed": "Failed to save settings",
|
||||
"invalidWebhook": "Invalid webhook URL"
|
||||
},
|
||||
"profile": {
|
||||
"title": "Profile Settings",
|
||||
"description": "Update your display name and profile photo.",
|
||||
"photoUpdated": "Photo Updated",
|
||||
"photoUpdatedMessage": "Your profile photo has been updated successfully!",
|
||||
"uploadFailed": "Upload Failed",
|
||||
"uploadFailedMessage": "Failed to upload your photo. Please try again.",
|
||||
"profileUpdated": "Profile Updated",
|
||||
"profileUpdatedMessage": "Your profile information has been saved successfully!",
|
||||
"updateFailed": "Update Failed",
|
||||
"updateFailedMessage": "Unable to update your profile. Please check your connection and try again.",
|
||||
"changePhoto": "Change Photo",
|
||||
"displayName": "Display Name",
|
||||
"displayNamePlaceholder": "Enter your display name",
|
||||
"timezone": "Timezone",
|
||||
"timezonePlaceholder": "Select your timezone",
|
||||
"common": {
|
||||
"save": "Save",
|
||||
"cancel": "Cancel"
|
||||
"cancel": "Cancel",
|
||||
"confirm": "Confirm",
|
||||
"remove": "Remove",
|
||||
"delete": "Delete",
|
||||
"refresh": "Refresh",
|
||||
"loading": "Loading...",
|
||||
"on": "On",
|
||||
"off": "Off",
|
||||
"error": "Error",
|
||||
"success": "Success",
|
||||
"plusFeature": "Plus Feature",
|
||||
"earlyAccess": "Early Access"
|
||||
},
|
||||
"overview": {
|
||||
"title": "Settings",
|
||||
@@ -165,14 +78,562 @@
|
||||
"title": "Advanced Settings",
|
||||
"description": "Configure webhooks, real-time updates, and other advanced features for enhanced productivity."
|
||||
},
|
||||
"privacy": {
|
||||
"title": "Privacy & Analytics",
|
||||
"description": "Control anonymous usage analytics and crash reporting."
|
||||
},
|
||||
"developer": {
|
||||
"title": "Developer Settings",
|
||||
"description": "View technical information about authentication tokens, SSE connections, and debug data."
|
||||
},
|
||||
"feedback": {
|
||||
"title": "Send Feedback",
|
||||
"description": "Tell us how Donetick is working for you, report a bug, or request a feature."
|
||||
"description": "Tell us how Donetick is working for you or request a feature."
|
||||
},
|
||||
"bugReport": {
|
||||
"title": "Report an Issue",
|
||||
"description": "Tell us what's not working and we'll attach the technical details for you."
|
||||
}
|
||||
}
|
||||
},
|
||||
"profile": {
|
||||
"title": "Profile Settings",
|
||||
"description": "Update your display name and profile photo.",
|
||||
"photoUpdated": "Photo Updated",
|
||||
"photoUpdatedMessage": "Your profile photo has been updated successfully!",
|
||||
"uploadFailed": "Upload Failed",
|
||||
"uploadFailedMessage": "Failed to upload your photo. Please try again.",
|
||||
"profileUpdated": "Profile Updated",
|
||||
"profileUpdatedMessage": "Your profile information has been saved successfully!",
|
||||
"updateFailed": "Update Failed",
|
||||
"updateFailedMessage": "Unable to update your profile. Please check your connection and try again.",
|
||||
"changePhoto": "Change Photo",
|
||||
"editPhoto": "Edit profile photo",
|
||||
"displayName": "Display Name",
|
||||
"displayNamePlaceholder": "Enter your display name",
|
||||
"timezone": "Timezone",
|
||||
"timezonePlaceholder": "Select your timezone",
|
||||
"save": "Save",
|
||||
"cancel": "Cancel"
|
||||
},
|
||||
"circleSettings": {
|
||||
"title": "Circle Settings",
|
||||
"description": "Your account is automatically connected to a Circle when you create or join one. Easily invite friends by sharing the unique Circle code or link below. You'll receive a notification below when someone requests to join your Circle.",
|
||||
"memberOf": "You are part of {{name}}",
|
||||
"yourCircleCode": "Your circle code is:",
|
||||
"copyCode": "Copy Code",
|
||||
"shareInvite": "Share Invite",
|
||||
"codeCopied": "Code copied to clipboard",
|
||||
"linkCopied": "Invite link copied to clipboard",
|
||||
"myCircle": "my Circle",
|
||||
"shareTitle": "Join {{name}} on Donetick",
|
||||
"shareText": "I'd like to invite you to join {{name}} on Donetick.",
|
||||
"shareDialogTitle": "Share Circle invite",
|
||||
"leave": "Leave Circle",
|
||||
"leaveConfirmTitle": "Leave Circle",
|
||||
"leaveConfirmMessage": "Are you sure you want to leave your circle?",
|
||||
"leaveConfirmButton": "Leave",
|
||||
"leftCircle": "Left circle successfully",
|
||||
"leaveFailed": "Failed to leave circle",
|
||||
"circleMembers": "Circle Members",
|
||||
"you": "(You)",
|
||||
"pendingApproval": "Pending Approval",
|
||||
"joinedOn": "Joined on {{date}}",
|
||||
"requestedToJoin": "Request to join {{date}}",
|
||||
"roles": {
|
||||
"member": "Member",
|
||||
"memberDescription": "Just a regular member of the circle",
|
||||
"manager": "Manager",
|
||||
"managerDescription": "Can impersonate users and perform actions on their behalf",
|
||||
"admin": "Admin",
|
||||
"adminDescription": "Full access to the circle"
|
||||
},
|
||||
"roleUpdateFailed": "Failed to update role",
|
||||
"removeMemberTitle": "Remove Member",
|
||||
"removeMemberMessage": "Are you sure you want to remove {{name}} from your circle?",
|
||||
"memberRemoved": "Removed member successfully",
|
||||
"circleMemberRequests": "Circle Member Requests",
|
||||
"lastUpdated": "Last updated: {{time}}",
|
||||
"refreshing": "Refreshing...",
|
||||
"refreshFailed": "Failed to refresh member requests",
|
||||
"wantsToJoin": "{{name}} wants to join your circle.",
|
||||
"accept": "Accept",
|
||||
"acceptRequestTitle": "Accept Member Request",
|
||||
"acceptRequestMessage": "Are you sure you want to accept {{name}} (username: {{username}}) to join your circle?",
|
||||
"requestAccepted": "Accepted request successfully",
|
||||
"or": "or",
|
||||
"joinOtherDescription": "Want to join someone else's Circle? Ask them for their unique Circle code or join link. Enter the code below to join their Circle.",
|
||||
"enterCircleCode": "Enter Circle code:",
|
||||
"enterCodePlaceholder": "Enter code",
|
||||
"joinCircle": "Join Circle",
|
||||
"joinedPending": "Joined circle successfully, wait for the circle owner to accept your request.",
|
||||
"alreadyMember": "You are already a member of this circle",
|
||||
"joinFailed": "Failed to join circle",
|
||||
"copyLink": "Copy Link"
|
||||
},
|
||||
"accountSettings": {
|
||||
"title": "Account Settings",
|
||||
"description": "Change your account settings, type or update your password",
|
||||
"accountType": "Account Type : {{type}}",
|
||||
"free": "Free",
|
||||
"plus": "Plus",
|
||||
"plusUntil": "Plus (until {{date}})",
|
||||
"activeDescription": "You are currently subscribed to the Plus plan. Your subscription will renew on {{date}}.",
|
||||
"cancelledDescription": "You have cancelled your subscription. Your account will be downgraded to the Free plan on {{date}}.",
|
||||
"freeDescription": "You are currently on the Free plan. Upgrade to the Plus plan to unlock more features.",
|
||||
"upgrade": "Upgrade",
|
||||
"cancel": "Cancel",
|
||||
"password": "Password :",
|
||||
"changePassword": "Change Password",
|
||||
"passwordChanged": "Password changed successfully",
|
||||
"passwordChangeFailed": "Password change failed",
|
||||
"dangerZone": "Danger Zone",
|
||||
"dangerZoneDescription": "Once you delete your account, there is no going back. Please be certain.",
|
||||
"deleteAccount": "Delete Account",
|
||||
"accountDeleted": "Account deleted successfully",
|
||||
"subscriptionCancelled": "Subscription cancelled",
|
||||
"subscriptionCancelFailed": "Failed to cancel subscription",
|
||||
"purchase": {
|
||||
"success": "Purchase successful! Please restart the app to access Plus features.",
|
||||
"storeConnection": "Store connection issue. Please check your network and try again.",
|
||||
"notAllowed": "Purchases are not allowed on this device. Please check your device restrictions.",
|
||||
"unavailable": "This subscription is not available. Please try again later.",
|
||||
"alreadyProcessed": "This purchase has already been processed. If you believe this is an error, please contact support.",
|
||||
"receiptMissing": "Purchase receipt missing. Please try purchasing again.",
|
||||
"networkError": "Network error. Please check your connection and try again.",
|
||||
"invalidReceipt": "Invalid purchase receipt. Please contact support if this persists.",
|
||||
"pending": "Payment is pending approval. You will receive access once approved.",
|
||||
"failed": "Purchase failed: {{error}}. Please try again or contact support.",
|
||||
"unknownError": "Unknown error"
|
||||
}
|
||||
},
|
||||
"subaccounts": {
|
||||
"title": "Managed Accounts",
|
||||
"description": "Manage sub accounts. Sub account users can log in and complete assigned tasks.",
|
||||
"notParentTitle": "Sub Account Management",
|
||||
"notParentMessage": "Only primary users can manage sub accounts.",
|
||||
"freePlanNotice": "Sub account limited to 1 on Free plan. Upgrade to Plus to have up to 5 sub accounts.",
|
||||
"count": "Sub Accounts ({{count}})",
|
||||
"add": "Add Sub Account",
|
||||
"loading": "Loading sub accounts...",
|
||||
"emptyTitle": "No Sub Accounts",
|
||||
"emptyDescription": "Create sub accounts so team members can log in and complete their assigned tasks.",
|
||||
"addFirst": "Add Your First Sub Account",
|
||||
"username": "Username: {{username}}",
|
||||
"created": "Created: {{date}}",
|
||||
"changePassword": "Change Password",
|
||||
"deleteAccount": "Delete Account",
|
||||
"createdSuccess": "Child account \"{{name}}\" created successfully!",
|
||||
"createFailed": "Failed to create child account: {{error}}",
|
||||
"createFailedGeneric": "Failed to create child user",
|
||||
"passwordUpdated": "Child password updated successfully",
|
||||
"passwordUpdateFailed": "Failed to update password: {{error}}",
|
||||
"passwordUpdateFailedGeneric": "Failed to update password",
|
||||
"deleteConfirmTitle": "Delete Sub Account",
|
||||
"deleteConfirmMessage": "Are you sure you want to delete the child account \"{{name}}\"? This action cannot be undone.",
|
||||
"deleted": "Sub account \"{{name}}\" deleted successfully",
|
||||
"deleteFailed": "Failed to delete Sub account: {{error}}",
|
||||
"deleteFailedGeneric": "Failed to delete Sub user",
|
||||
"howItWorksTitle": "How Managed Accounts Work",
|
||||
"howItWorks1": "Managed accounts created by the primary user, these specific for user you want to have ability to delete and reset password.",
|
||||
"howItWorks2": "Sub accounts can log in with their own username and password.",
|
||||
"howItWorks3": "Managed accounts can complete tasks but have limited administrative permissions",
|
||||
"howItWorks4": "Managed accounts automatically added to your circle"
|
||||
},
|
||||
"notifications": {
|
||||
"title": "Notification Settings",
|
||||
"deviceSection": "Device Notification",
|
||||
"deviceSectionDescription": "Manage your Device Notification",
|
||||
"deviceLabel": "Device Notification",
|
||||
"deviceHelper": "Receive notification on your device when a task is due",
|
||||
"mobileOnly": "This feature is only available on mobile devices",
|
||||
"testNotification": "Test Notification",
|
||||
"testNotificationBody": "You have a task due soon",
|
||||
"dueTitle": "Due Date Notification",
|
||||
"dueLabel": "Notification when the task is due",
|
||||
"preDueTitle": "Pre-Due Date Notification",
|
||||
"preDueLabel": "Notification a few hours before the task is due",
|
||||
"overdueTitle": "Overdue Notification",
|
||||
"overdueLabel": "Notification when the task is overdue",
|
||||
"pushLabel": "Push Notifications",
|
||||
"pushHelper": "Receive Nudges, Announcements, and Chore Assignments via Push Notifications",
|
||||
"registeredDevices": "Registered Devices ({{count}}/5)",
|
||||
"registeredDevicesDescription": "Devices registered to receive push notifications for your account",
|
||||
"currentDevice": "Current Device: {{platform}} {{model}}",
|
||||
"currentDeviceNotRegistered": "This device is not registered for push notifications",
|
||||
"limitReached": "Limit Reached",
|
||||
"registerDevice": "Register Device",
|
||||
"unknownDevice": "Unknown Device",
|
||||
"deviceCreatedAt": "Created At: {{date}}",
|
||||
"noDevices": "No devices registered for push notifications",
|
||||
"customSection": "Custom Notification",
|
||||
"customSectionDescription": "Notification through other platform like Telegram or Pushover",
|
||||
"customLabel": "Custom Notification",
|
||||
"customHelper": "Receive notification on other platform",
|
||||
"targetNone": "None",
|
||||
"targetTelegram": "Telegram",
|
||||
"targetPushover": "Pushover",
|
||||
"targetWebhooks": "Webhooks",
|
||||
"telegramBotHelpBefore": "You need to initiate a message to the bot in order for the Telegram notification to work",
|
||||
"telegramBotHelpAfter": "to start a chat",
|
||||
"clickHere": "Click here",
|
||||
"chatId": "Chat ID",
|
||||
"chatIdPlaceholder": "User ID / Chat ID",
|
||||
"telegramChatIdHelpBefore": "If you don't know your Chat ID, start chat with userinfobot and it will send you your Chat ID.",
|
||||
"telegramChatIdHelpAfter": "to start chat with userinfobot",
|
||||
"userKey": "User key",
|
||||
"userKeyPlaceholder": "User ID",
|
||||
"chatIdRequired": "Chat ID is required",
|
||||
"chatIdInvalid": "Invalid Chat ID",
|
||||
"userKeyRequired": "User key is required",
|
||||
"targetUpdated": "Notification target updated",
|
||||
"targetUpdateFailed": "Error while updating notification target: {{error}}",
|
||||
"deviceRegistered": "Device registered successfully for push notifications.",
|
||||
"deviceLimitTitle": "Device Limit Reached",
|
||||
"deviceLimitMessage": "You have reached the maximum limit of 5 registered devices. Please remove a device before registering this one.",
|
||||
"registrationFailedTitle": "Registration Failed",
|
||||
"registrationFailedMessage": "Failed to register device automatically. Please try again.",
|
||||
"permissionRequiredTitle": "Permission Required",
|
||||
"permissionRequiredMessage": "Push notification permission is required to register this device.",
|
||||
"registrationInitiatedTitle": "Registration Initiated",
|
||||
"registrationInitiatedMessage": "Push notification registration has been initiated. The device will be registered automatically.",
|
||||
"registerDeviceFailed": "Failed to register device. Please try again.",
|
||||
"permissionDeniedTitle": "Notification Permission Denied",
|
||||
"permissionDeniedMessage": "You have denied notification permissions. You can enable them later in your device settings.",
|
||||
"pushPermissionDeniedTitle": "Push Notification Permission Denied",
|
||||
"pushPermissionDeniedMessage": "Push notifications have been disabled. You can enable them in your device settings if needed.",
|
||||
"unregisterFailed": "Failed to unregister device"
|
||||
},
|
||||
"mfa": {
|
||||
"title": "Multi-Factor Authentication",
|
||||
"description": "Add an extra layer of security to your account with multi-factor authentication (MFA). When enabled, you'll need to provide a verification code from your authenticator app in addition to your password when signing in.",
|
||||
"twoFactor": "Two-Factor Authentication",
|
||||
"enabledSubtitle": "Your account is protected with 2FA",
|
||||
"disabledSubtitle": "Secure your account with an authenticator app",
|
||||
"enable": "Enable",
|
||||
"disable": "Disable",
|
||||
"enabledSuccess": "MFA has been successfully enabled!",
|
||||
"disabledSuccess": "MFA has been disabled successfully!",
|
||||
"errors": {
|
||||
"qrGenerationFailed": "Failed to generate QR code",
|
||||
"invalidResponse": "Invalid response from server. Missing QR code or secret.",
|
||||
"notFound": "MFA setup endpoint not found. This feature may not be available yet.",
|
||||
"unauthorized": "Unauthorized. Please login again.",
|
||||
"serverError": "Server error. Please try again later.",
|
||||
"setupFailed": "Failed to setup MFA ({{status}}). Please try again.",
|
||||
"networkError": "Network error. Please check your connection and try again.",
|
||||
"invalidCode": "Invalid verification code. Please try again.",
|
||||
"confirmFailed": "Failed to confirm MFA. Please try again.",
|
||||
"disableFailed": "Failed to disable MFA. Please try again."
|
||||
},
|
||||
"setup": {
|
||||
"title": "Set up Multi-Factor Authentication",
|
||||
"addedAccount": "I've added the account",
|
||||
"back": "Back",
|
||||
"verifyAndEnable": "Verify & Enable",
|
||||
"savedBackupCodes": "I've saved my backup codes",
|
||||
"step1Label": "Step 1:",
|
||||
"step1": "Scan the QR code below with your authenticator app (Google Authenticator, Authy, etc.)",
|
||||
"qrAlt": "MFA QR Code",
|
||||
"qrFailed": "QR code could not be generated. Please try again or use the manual entry key below.",
|
||||
"manualKey": "Manual entry key:",
|
||||
"step2Label": "Step 2:",
|
||||
"step2": "Enter the 6-digit verification code from your authenticator app",
|
||||
"codePlaceholder": "Enter 6-digit code",
|
||||
"successTitle": "MFA Successfully Enabled!",
|
||||
"backupCodesTitle": "Save these backup codes in a safe place",
|
||||
"backupCodesDescription": "You can use these codes to access your account if you lose your authenticator device. Each code can only be used once."
|
||||
},
|
||||
"disableModal": {
|
||||
"title": "Disable Multi-Factor Authentication",
|
||||
"warning": "Disabling MFA will make your account less secure. Are you sure you want to continue?",
|
||||
"prompt": "Enter a verification code from your authenticator app to confirm:",
|
||||
"confirm": "Disable MFA"
|
||||
},
|
||||
"backupCodesModal": {
|
||||
"title": "New Backup Codes",
|
||||
"warning": "Your previous backup codes are now invalid. Save these new codes in a safe place. Each code can only be used once."
|
||||
},
|
||||
"generateCodes": "Generate New Codes"
|
||||
},
|
||||
"apiTokens": {
|
||||
"title": "API Tokens",
|
||||
"accessToken": "Access Token",
|
||||
"description": "Create token to use with the API to update things that trigger task or chores",
|
||||
"plusNotice": "API tokens are not available in the Basic plan. Upgrade to Plus to generate API tokens for integrating with external systems and automating your tasks.",
|
||||
"showToken": "Show Token",
|
||||
"hideToken": "Hide Token",
|
||||
"removeTitle": "Remove Token",
|
||||
"removeMessage": "Are you sure you want to remove {{name}}?",
|
||||
"removedTitle": "Removed",
|
||||
"removedMessage": "API token has been removed",
|
||||
"tokenCopied": "Token copied to clipboard",
|
||||
"generateNew": "Generate New Token",
|
||||
"nameModalTitle": "Give a name for your new token, something to remember it by.",
|
||||
"generateToken": "Generate Token"
|
||||
},
|
||||
"storage": {
|
||||
"title": "Storage Settings",
|
||||
"serverTitle": "Server Storage Usage",
|
||||
"serverDescription": "This is the storage used by your account on our servers (e.g. files, images, and data you have uploaded).",
|
||||
"usagePlaceholder": "-- MB used / -- MB total (--)",
|
||||
"usage": "{{used}} MB used / {{total}} MB total ({{percent}}%)",
|
||||
"basicPlanNotice": "Server storage is not available in the Basic plan. Upgrade to Plus to track your server storage usage.",
|
||||
"localTitleApp": "App Local Storage & Cache",
|
||||
"localTitleBrowser": "Browser Local Storage & Cache",
|
||||
"localDescription": "This is data stored locally in your browser for faster access. Clearing this will not affect your server data, but may log you out.",
|
||||
"clearLocal": "Clear All Local Storage and Cache",
|
||||
"clearLocalTitle": "Clear All Local Storage",
|
||||
"clearLocalMessage": "Are you sure you want to clear your local storage and cache? This will remove all your data from this browser and require login.",
|
||||
"clearAll": "Clear All",
|
||||
"appPreferences": "App Preferences",
|
||||
"deviceOnly": "Device Only",
|
||||
"appPreferencesDescription": "These are preferences and settings stored locally on your device by the app. Clearing them will reset app-specific settings and may log you out, but will not affect your server data.",
|
||||
"clearPreferences": "Clear App Preferences",
|
||||
"clearPreferencesTitle": "Clear App Preferences",
|
||||
"clearPreferencesMessage": "Are you sure you want to clear all app preferences? This will reset your app settings and may require you to log in again."
|
||||
},
|
||||
"sidepanel": {
|
||||
"title": "Sidepanel Customization",
|
||||
"heading": "Sidepanel Settings",
|
||||
"description": "Customize which cards appear in the sidepanel and their order. Drag and drop to reorder, or toggle visibility for each card.",
|
||||
"resetToDefaults": "Reset to Defaults",
|
||||
"resetHelper": "This will restore all cards to their default visibility and order.",
|
||||
"cards": {
|
||||
"welcome": {
|
||||
"name": "User Switcher",
|
||||
"description": "Allows admins/managers to view tasks as different users"
|
||||
},
|
||||
"smartInsights": {
|
||||
"name": "Smart Insights",
|
||||
"description": "Quick actions based on your tasks"
|
||||
},
|
||||
"assignees": {
|
||||
"name": "Tasks by Assignee",
|
||||
"description": "Groups tasks by who they are assigned to"
|
||||
},
|
||||
"calendar": {
|
||||
"name": "Calendar View",
|
||||
"description": "Shows tasks in a calendar format"
|
||||
},
|
||||
"activities": {
|
||||
"name": "Recent Activities",
|
||||
"description": "Shows recent task completions and activities"
|
||||
},
|
||||
"weeklyGoals": {
|
||||
"name": "Weekly Goals",
|
||||
"description": "Shows weekly progress and family completion stats"
|
||||
}
|
||||
},
|
||||
"detailedDescription": "Customize the layout and visibility of cards in the sidepanel. the section only available on large screen devices such as tablets and desktops.."
|
||||
},
|
||||
"theme": {
|
||||
"title": "Theme Preferences",
|
||||
"description": "Choose how the site looks to you. Select a single theme, or sync with your system and automatically switch between day and night themes.",
|
||||
"themeMode": "Theme mode",
|
||||
"light": "Light",
|
||||
"dark": "Dark",
|
||||
"system": "System"
|
||||
},
|
||||
"localization": {
|
||||
"title": "Localization",
|
||||
"description": "Customize language, date format, and regional preferences for your account.",
|
||||
"language": "Language",
|
||||
"languageDescription": "Select your preferred language",
|
||||
"rtlNotice": "This language uses right-to-left (RTL) text direction",
|
||||
"dateFormat": "Date Format",
|
||||
"dateFormatDescription": "Choose how dates should be displayed throughout the application",
|
||||
"timeFormat": "Time Format",
|
||||
"timeFormatDescription": "Select 12-hour or 24-hour time format",
|
||||
"preview": "Preview: {{value}}",
|
||||
"12hour": "12-hour (AM/PM)",
|
||||
"24hour": "24-hour",
|
||||
"firstDayOfWeek": "First Day of Week",
|
||||
"firstDayOfWeekDescription": "Select which day starts your week",
|
||||
"sunday": "Sunday",
|
||||
"monday": "Monday",
|
||||
"saturday": "Saturday",
|
||||
"formats": {
|
||||
"mdy": "MM/DD/YYYY (US)",
|
||||
"dmy": "DD/MM/YYYY (Europe)",
|
||||
"ymd": "YYYY-MM-DD (ISO)",
|
||||
"long": "Long format (e.g., January 1, 2024)",
|
||||
"short": "Short format (e.g., Jan 1, 2024)"
|
||||
},
|
||||
"descriptionLong": "Customize language, date format, and regional preferences for your account. These settings will apply throughout the application."
|
||||
},
|
||||
"advanced": {
|
||||
"title": "Advanced Settings",
|
||||
"description": "Configure advanced features like webhooks and real-time updates for enhanced productivity.",
|
||||
"offlineTitle": "Offline Support",
|
||||
"offlineDescription": "Keep using Donetick when you're offline on this device/browser. Your changes are saved locally and synced when you're back online.",
|
||||
"offlineToggle": "Enable Offline Support",
|
||||
"offlineHelper": "Turning this off removes unsynced offline changes and saved offline data from this device/browser.",
|
||||
"offlineEnabled": "Offline mode turned on for this device/browser",
|
||||
"offlineDisabled": "Offline mode turned off and local data was cleared",
|
||||
"offlineDisabledPartial": "Offline mode was turned off, but some local data may still be stored",
|
||||
"offlineDisableTitle": "Turn Off Offline Mode",
|
||||
"offlineDisableMessage": "Turning off offline mode will remove unsynced offline changes and saved offline data on this device/browser. Do you want to continue?",
|
||||
"offlineDisableConfirm": "Turn Off & Clear Data",
|
||||
"webhookTitle": "Webhook Integration",
|
||||
"webhookDescription": "Webhooks allow you to send real-time notifications to other services when events happen in your Circle. Configure a webhook URL to receive real-time updates.",
|
||||
"webhookPlusNotice": "Webhook notifications are not available in the Basic plan. Upgrade to Plus to receive real-time updates via webhooks.",
|
||||
"webhookToggle": "Enable Webhook",
|
||||
"webhookHelper": "Enable webhook notifications for tasks and things updates.",
|
||||
"webhookURL": "Webhook URL",
|
||||
"webhookUpdated": "Webhook URL updated successfully",
|
||||
"webhookUpdateFailed": "Failed to update webhook URL",
|
||||
"realtimeTitle": "Real-time Updates",
|
||||
"realtimeDescription": "Configure how you receive live updates when tasks and activities change in your circle.",
|
||||
"realtime": {
|
||||
"toggleLabel": "Enable Real-time Updates",
|
||||
"title": "Real-time Updates",
|
||||
"subtitle": "Get instant notifications when tasks are updated",
|
||||
"statusLabel": "Status:",
|
||||
"basicPlan": "Real-time updates are not available in the Basic plan. Upgrade to Plus to receive instant notifications when tasks are updated.",
|
||||
"disabled": "Real-time updates are disabled. Enable them to see live changes when you or other circle members complete, skip, or modify tasks.",
|
||||
"connected": "Real-time updates are working. You'll see live changes when you or other circle members complete, skip, or modify tasks.",
|
||||
"connecting": "Connecting to real-time updates...",
|
||||
"errored": "Real-time updates are enabled but not working: {{error}}",
|
||||
"notConnected": "Real-time updates are enabled but not currently connected.",
|
||||
"basicPlanNotice": "Real-time updates are not available in the Basic plan. Upgrade to Plus to receive instant notifications when you or other circle members complete, skip, or modify tasks."
|
||||
}
|
||||
},
|
||||
"privacyAnalytics": {
|
||||
"title": "Privacy & Analytics",
|
||||
"description": "Donetick never sends task names, descriptions, notes, or other task content. Session recording is never enabled.",
|
||||
"analyticsToggle": "Anonymous analytics",
|
||||
"analyticsHelper": "Help improve Donetick by sharing anonymous usage statistics.",
|
||||
"crashToggle": "Crash reports",
|
||||
"crashHelper": "Send us the error and what led to it when Donetick crashes no task content.",
|
||||
"footnote": "You can change these choices at any time."
|
||||
},
|
||||
"subscription": {
|
||||
"sessionFailed": "Failed to create subscription session",
|
||||
"errorTitle": "Subscription Error",
|
||||
"errorMessage": "Failed to start subscription process. Please try again.",
|
||||
"subscribe": "Subscribe",
|
||||
"cancelAnytime": "Cancel anytime. No hidden fees. Secure payment powered by Stripe."
|
||||
},
|
||||
"childUsers": {
|
||||
"errNameRequired": "Sub account name is required",
|
||||
"errNameMin": "Sub account name must be at least 2 characters",
|
||||
"errNameMax": "Sub account name must be less than 20 characters",
|
||||
"errNameChars": "Sub account name can only contain lowercase letters, dot and dash",
|
||||
"errPasswordRequired": "Password is required",
|
||||
"errPasswordLength": "Password must be between 8 and 64 characters",
|
||||
"errPasswordMatch": "Passwords do not match",
|
||||
"errDisplayNameMax": "Display name must be less than 50 characters",
|
||||
"createTitle": "Create Sub Account",
|
||||
"createButton": "Create Account",
|
||||
"nameLabel": "Sub Account Name *",
|
||||
"namePlaceholder": "Enter sub account name (e.g., sarah)",
|
||||
"displayNameLabel": "Display Name",
|
||||
"displayNamePlaceholder": "Display name (optional, defaults to sub account name)",
|
||||
"passwordLabel": "Password *",
|
||||
"passwordPlaceholder": "Enter password (8-64 characters)",
|
||||
"confirmPasswordLabel": "Confirm Password *",
|
||||
"confirmPasswordPlaceholder": "Confirm password"
|
||||
},
|
||||
"passwordChange": {
|
||||
"minLength": "Password must be at least 8 characters",
|
||||
"maxLength": "Password must be less than 64 characters",
|
||||
"description": "Choose a password between 8 and 64 characters.",
|
||||
"mismatch": "Passwords do not match",
|
||||
"newPassword": "New password",
|
||||
"newPasswordPlaceholder": "Enter password",
|
||||
"confirmPassword": "Confirm password",
|
||||
"confirmPasswordPlaceholder": "Repeat password"
|
||||
},
|
||||
"payment": {
|
||||
"cancelledTitle": "Payment has been cancelled",
|
||||
"cancelledRedirect": "You will be redirected to the main page shortly.",
|
||||
"successTitle": "Payment Successful!",
|
||||
"successRedirect": "You will be redirected to the settings page shortly."
|
||||
},
|
||||
"developer": {
|
||||
"tokenRefreshed": "Token refreshed successfully",
|
||||
"endpointCalled": "Refresh token endpoint called successfully",
|
||||
"clearDbCleared": "Local offline database cleared. Starting full sync...",
|
||||
"clearDbDone": "Full sync completed from the beginning",
|
||||
"intro": "View technical information about your authentication tokens and session",
|
||||
"refreshCookieNote": "Refresh tokens are managed via HTTP-only cookies on web platform",
|
||||
"noReconnectInfo": "No reconnection information available",
|
||||
"noTimeoutInfo": "No timeout information available",
|
||||
"noDebugInfo": "No debug information available"
|
||||
},
|
||||
"backup": {
|
||||
"keyRequired": "Encryption key is required",
|
||||
"created": "Backup created and downloaded successfully",
|
||||
"createFailed": "Failed to create backup",
|
||||
"selectFile": "Please select a backup file",
|
||||
"restored": "Backup restored successfully. Please refresh the page.",
|
||||
"restoreFailed": "Failed to restore backup",
|
||||
"readFailed": "Failed to read backup file",
|
||||
"createIntro": "Create an encrypted backup of your data. This backup will include all your chores, history, settings, and optionally your uploaded files.",
|
||||
"keyPlaceholder": "Enter a strong encryption key",
|
||||
"includeAssets": "Include uploaded files and assets",
|
||||
"warningLabel": "Warning:",
|
||||
"restoreWarning": "Restoring a backup will replace all your current data. This action cannot be undone.",
|
||||
"restoreKeyPlaceholder": "Enter the encryption key used for this backup",
|
||||
"title": "Backup & Restore",
|
||||
"createTab": "Create Backup",
|
||||
"restoreTab": "Restore Backup",
|
||||
"creating": "Creating backup...",
|
||||
"restoring": "Restoring backup..."
|
||||
},
|
||||
"deletion": {
|
||||
"passwordRequired": "Please enter your password to continue",
|
||||
"passwordAndDelete": "Please enter your password and type DELETE to confirm",
|
||||
"failed": "Failed to delete account",
|
||||
"passwordPlaceholder": "Enter your password",
|
||||
"transferIntro": "You own circles that require ownership transfer before deletion. Please select new owners:",
|
||||
"selectOwner": "Select new owner",
|
||||
"confirmPrompt": "Please enter your password and type DELETE to confirm",
|
||||
"typeDelete": "DELETE",
|
||||
"warningLead": "This action cannot be undone.",
|
||||
"warningIntro": "Deleting your account will permanently remove:",
|
||||
"removesProfile": "Your user profile and authentication data",
|
||||
"removesChores": "All your chores, chore history, and time tracking sessions",
|
||||
"removesTokens": "API tokens, MFA sessions, and password reset tokens",
|
||||
"removesStorage": "Storage files and usage data",
|
||||
"removesPoints": "Points history and notifications",
|
||||
"removesCircles": "Circle memberships and relationships",
|
||||
"passwordToContinue": "Enter your password to continue",
|
||||
"circleLabel": "Circle: {{name}}",
|
||||
"newOwner": "New Owner",
|
||||
"logoutNotice": "On successful deletion, you will be logged out and redirected to the login page.",
|
||||
"passwordLabel": "Password",
|
||||
"typeToConfirm": "Type \"{{word}}\" to confirm"
|
||||
},
|
||||
"realtime": {
|
||||
"titleSse": "Real-time Updates (SSE)",
|
||||
"subtitleSse": "Get instant notifications via Server-Sent Events"
|
||||
},
|
||||
"nativeCancel": {
|
||||
"title": "Cancel Subscription",
|
||||
"dismiss": "Dismiss",
|
||||
"cancelViaStore": "I'll cancel from my app store",
|
||||
"cancelDesktop": "Cancel desktop subscription",
|
||||
"intro": "To cancel your subscription, please follow the instructions for your platform (you should cancel through the same platform you used to subscribe).",
|
||||
"iosHeading": "For iOS (iPhone/iPad):",
|
||||
"iosStep1": "1. Open the <b>Settings</b> app on your device",
|
||||
"iosStep2": "2. Tap your name at the top of the screen",
|
||||
"iosStep3": "3. Tap <b>Subscriptions</b>",
|
||||
"iosStep4": "4. Find and tap <b>Donetick</b>",
|
||||
"iosStep5": "5. Tap <b>Cancel Subscription</b>",
|
||||
"iosNote": "<b>Note:</b> If you subscribed through iOS and are using the web/desktop version, you must cancel through iOS Settings as described above.",
|
||||
"androidHeading": "For Android:",
|
||||
"androidStep1": "1. Open the <b>Google Play Store</b> app",
|
||||
"androidStep2": "2. Tap the profile icon in the top right",
|
||||
"androidStep3": "3. Tap <b>Payments & subscriptions</b>",
|
||||
"androidStep4": "4. Tap <b>Subscriptions</b>",
|
||||
"androidStep5": "5. Find and tap <b>Donetick</b>",
|
||||
"androidStep6": "6. Tap <b>Cancel subscription</b>",
|
||||
"androidNote": "<b>Note:</b> If you subscribed through Google Play and are using the web/desktop version, you must cancel through Google Play as described above.",
|
||||
"webHeading": "For Web/Desktop Subscriptions:",
|
||||
"webBody": "If you originally subscribed through our website or desktop app, you can cancel your subscription by going to the Account Settings section on our website. using a web browser",
|
||||
"webNote": "<b>Important:</b> You must cancel your subscription through the same platform where you originally subscribed. If you subscribed through the iOS App Store or Google Play Store (even if you're now using the web/desktop version), you must cancel through that original platform using the instructions above.",
|
||||
"footer": "Your subscription will remain active until the end of your current billing period."
|
||||
}
|
||||
}
|
||||
|
||||
60
public/locales/en/things.json
Normal file
60
public/locales/en/things.json
Normal file
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"errName": "Name is required",
|
||||
"errStateNumber": "State must be a number",
|
||||
"errStateBool": "State must be true or false",
|
||||
"errStateRequired": "State is required",
|
||||
"name": "Name",
|
||||
"namePlaceholder": "Thing name",
|
||||
"value": "Value",
|
||||
"valuePlaceholder": "Thing value",
|
||||
"updateState": "Update state",
|
||||
"update": "Update",
|
||||
"history": {
|
||||
"overview": "Things Overview",
|
||||
"visualization": "Data Visualization",
|
||||
"changeHistory": "Change History",
|
||||
"updated": "Updated"
|
||||
},
|
||||
"view": {
|
||||
"title": "Things",
|
||||
"description": "Things are custom fields that can be attached to tasks to capture additional information. They can be of type text, number, or boolean. You can associate things with tasks and have the task due once condition is met",
|
||||
"searchPlaceholder": "Search things",
|
||||
"sortName": "Name",
|
||||
"sortType": "Type",
|
||||
"sortState": "State",
|
||||
"sortUpdated": "Last updated",
|
||||
"filterTitle": "Type",
|
||||
"filterAll": "All types",
|
||||
"emptyTitle": "No things yet",
|
||||
"emptyDescription": "A thing tracks a value, like a counter or a switch, that other tasks can react to. Create one to trigger tasks automatically.",
|
||||
"emptyAction": "Create a thing",
|
||||
"noResultsTitle": "No things match",
|
||||
"noResultsSearch": "No thing matches \"{{term}}\".",
|
||||
"noResultsFilter": "No thing matches the current filter.",
|
||||
"clearSearch": "Clear search",
|
||||
"showAll": "Show all things",
|
||||
"toggle": "Toggle"
|
||||
},
|
||||
"types": {
|
||||
"text": "Text",
|
||||
"number": "Number",
|
||||
"boolean": "Boolean"
|
||||
},
|
||||
"notify": {
|
||||
"savedTitle": "Saved",
|
||||
"savedMessage": "Thing saved successfully",
|
||||
"saveFailTitle": "Unable to save thing",
|
||||
"queuedMessage": "You are offline and the request has been queued",
|
||||
"saveFailMessage": "An error occurred while saving the thing",
|
||||
"deleteTitle": "Delete Things",
|
||||
"deleteMessage": "Are you sure you want to delete this Thing?",
|
||||
"deleteBlockedTitle": "Unable to Delete Thing",
|
||||
"deleteBlockedMessage": "Unable to delete thing with associated tasks",
|
||||
"deleteFailTitle": "Unable to delete thing",
|
||||
"deleteFailMessage": "An error occurred while deleting the thing",
|
||||
"updatedTitle": "Updated",
|
||||
"updatedMessage": "Thing state updated successfully",
|
||||
"updateFailTitle": "Unable to update thing state",
|
||||
"updateFailMessage": "An error occurred while updating the thing state"
|
||||
}
|
||||
}
|
||||
45
public/locales/en/timer.json
Normal file
45
public/locales/en/timer.json
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"toast": {
|
||||
"sessionUpdatedTitle": "Session updated",
|
||||
"sessionUpdatedMessage": "Timer session has been updated successfully.",
|
||||
"sessionUpdateFailTitle": "Failed to update session",
|
||||
"tryAgain": "Please try again.",
|
||||
"sessionUpdateErrorTitle": "Error updating session",
|
||||
"sessionDeletedTitle": "Session deleted",
|
||||
"sessionDeletedMessage": "Timer session has been deleted successfully.",
|
||||
"sessionDeleteErrorTitle": "Error deleting session",
|
||||
"deleteConfirmTitle": "Delete Timer Session",
|
||||
"deleteConfirmMessage": "Are you sure you want to delete this timer session?",
|
||||
"startedTitle": "Timer Started",
|
||||
"startedMessage": "Work session has been started successfully.",
|
||||
"startQueuedTitle": "Start queued",
|
||||
"startFailTitle": "Failed to start timer",
|
||||
"pausedTitle": "Timer Paused",
|
||||
"pausedMessage": "Work session has been paused.",
|
||||
"pauseQueuedTitle": "Pause queued",
|
||||
"pauseFailTitle": "Failed to pause timer",
|
||||
"deleteSessionTitle": "Delete Session"
|
||||
},
|
||||
"loading": "Loading timer data...",
|
||||
"noData": "No timer data found for this chore.",
|
||||
"activeWork": "Active Work",
|
||||
"breakTime": "Break Time",
|
||||
"workSessions": "Work Sessions",
|
||||
"totalTime": "Total Time",
|
||||
"distribution": "Work vs Break Distribution",
|
||||
"noActiveTime": "No active time yet",
|
||||
"sessionBreakdown": "Session Breakdown",
|
||||
"sessions": "Sessions",
|
||||
"addSession": "Add Session",
|
||||
"startTime": "Start Time",
|
||||
"endTime": "End Time",
|
||||
"leaveEmpty": "Leave empty if session is ongoing",
|
||||
"noSessionForChore": "No timer session found for this chore.",
|
||||
"saveChanges": "Save Changes",
|
||||
"emptySessionsTitle": "No work sessions yet",
|
||||
"emptySessionsDescription": "Start the timer on this task and each session lands here.",
|
||||
"percentActive": "{{percent}}% active",
|
||||
"activityTimeline": "Activity Timeline",
|
||||
"liveSession": "Live Session",
|
||||
"live": "Live"
|
||||
}
|
||||
@@ -20,6 +20,7 @@
|
||||
"logout": "Cerrar Sesión",
|
||||
"version": "Versión",
|
||||
"navigation": {
|
||||
"search": "Buscar",
|
||||
"allTasks": "Todas las Tareas",
|
||||
"archived": "Archivadas",
|
||||
"things": "Cosas",
|
||||
@@ -29,5 +30,43 @@
|
||||
"activities": "Actividades",
|
||||
"points": "Puntos",
|
||||
"settings": "Configuración"
|
||||
},
|
||||
"search": {
|
||||
"title": "Buscar",
|
||||
"placeholder": "Buscar en Donetick",
|
||||
"inputAriaLabel": "Buscar tareas, historial, proyectos, etiquetas y configuración",
|
||||
"deviceNote": "Se busca en el contenido disponible en este dispositivo",
|
||||
"escape": "Esc",
|
||||
"recent": "Recientes",
|
||||
"empty": {
|
||||
"title": "Sin coincidencias directas",
|
||||
"subtitle": "Aún puedes filtrar la lista de tareas con esta búsqueda."
|
||||
},
|
||||
"groups": {
|
||||
"tasks": "Tareas",
|
||||
"history": "Notas",
|
||||
"projects": "Proyectos",
|
||||
"labels": "Etiquetas",
|
||||
"people": "Personas",
|
||||
"settings": "Configuración",
|
||||
"actions": "Acciones rápidas"
|
||||
},
|
||||
"actions": {
|
||||
"quickAction": "Acción rápida",
|
||||
"navigation": "Navegación",
|
||||
"createTask": "Crear una tarea",
|
||||
"viewAllTasks": "Ver todas las tareas",
|
||||
"viewArchivedTasks": "Ver tareas archivadas",
|
||||
"openSettings": "Abrir configuración",
|
||||
"filterTasks": "Mostrar tareas que coincidan con «{{query}}»",
|
||||
"filterTasksSubtitle": "Filtrar la lista de tareas"
|
||||
},
|
||||
"footer": {
|
||||
"navigate": "Navegar",
|
||||
"open": "Abrir",
|
||||
"results_one": "{{count}} resultado",
|
||||
"results_other": "{{count}} resultados",
|
||||
"typeToSearch": "Escribe para buscar"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,174 +1,494 @@
|
||||
{
|
||||
"title": "Configuración",
|
||||
"circleSettings": {
|
||||
"title": "Configuración del círculo",
|
||||
"description": "Tu cuenta se conecta automáticamente a un Círculo cuando creas o te unes a uno. Invita fácilmente a amigos compartiendo el código único del Círculo o el enlace a continuación.",
|
||||
"circleCode": "Código del Círculo",
|
||||
"copyCode": "Copiar Código",
|
||||
"copyLink": "Copiar Enlace",
|
||||
"codeCopied": "¡Código del círculo copiado!",
|
||||
"linkCopied": "¡Enlace copiado!",
|
||||
"joinCircle": "Unirse a un Círculo",
|
||||
"joinCirclePlaceholder": "Ingresa el Código del Círculo",
|
||||
"join": "Unirse",
|
||||
"leave": "Salir del Círculo",
|
||||
"leaveConfirmTitle": "Salir del Círculo",
|
||||
"leaveConfirmMessage": "¿Estás seguro de que quieres salir de este círculo?",
|
||||
"circleMembers": "Miembros del Círculo",
|
||||
"circleMemberRequests": "Solicitudes de Miembros del Círculo",
|
||||
"admin": "Administrador",
|
||||
"member": "Miembro",
|
||||
"pending": "Pendiente",
|
||||
"accept": "Aceptar",
|
||||
"reject": "Rechazar",
|
||||
"makeAdmin": "Hacer Administrador",
|
||||
"makeMember": "Hacer Miembro",
|
||||
"remove": "Eliminar",
|
||||
"webhookURL": "URL del Webhook",
|
||||
"webhookDescription": "Ingresa una URL de webhook para recibir notificaciones de eventos del círculo",
|
||||
"webhookPlaceholder": "https://tu-url-webhook.com"
|
||||
},
|
||||
"accountSettings": {
|
||||
"title": "Configuración de la Cuenta",
|
||||
"subscription": "Suscripción",
|
||||
"subscriptionStatus": "Plan Actual",
|
||||
"free": "Gratis",
|
||||
"plus": "Plus",
|
||||
"upgrade": "Actualizar",
|
||||
"cancel": "Cancelar",
|
||||
"changePassword": "Cambiar Contraseña",
|
||||
"password": "Contraseña",
|
||||
"dangerZone": "Zona de Peligro",
|
||||
"dangerZoneDescription": "Una vez que elimines tu cuenta, no hay vuelta atrás. Por favor, está seguro.",
|
||||
"deleteAccount": "Eliminar Cuenta"
|
||||
},
|
||||
"localization": {
|
||||
"title": "Localización",
|
||||
"description": "Personaliza el idioma, formato de fecha y preferencias regionales para tu cuenta.",
|
||||
"language": "Idioma",
|
||||
"languageDescription": "Selecciona tu idioma preferido",
|
||||
"dateFormat": "Formato de Fecha",
|
||||
"dateFormatDescription": "Elige cómo se deben mostrar las fechas en toda la aplicación",
|
||||
"timeFormat": "Formato de Hora",
|
||||
"timeFormatDescription": "Selecciona formato de 12 o 24 horas",
|
||||
"12hour": "12 horas (AM/PM)",
|
||||
"24hour": "24 horas",
|
||||
"firstDayOfWeek": "Primer Día de la Semana",
|
||||
"firstDayOfWeekDescription": "Selecciona qué día comienza tu semana",
|
||||
"sunday": "Domingo",
|
||||
"monday": "Lunes",
|
||||
"saturday": "Sábado",
|
||||
"formats": {
|
||||
"mdy": "MM/DD/AAAA (EE.UU.)",
|
||||
"dmy": "DD/MM/AAAA (Europa)",
|
||||
"ymd": "AAAA-MM-DD (ISO)",
|
||||
"long": "Formato largo (ej., 1 de enero de 2024)",
|
||||
"short": "Formato corto (ej., 1 ene 2024)"
|
||||
}
|
||||
},
|
||||
"sidepanel": {
|
||||
"title": "Personalización del Panel Lateral",
|
||||
"description": "Personaliza el diseño y la visibilidad de las tarjetas en el panel lateral. Esta sección solo está disponible en dispositivos de pantalla grande como tabletas y computadoras de escritorio."
|
||||
},
|
||||
"theme": {
|
||||
"title": "Preferencias de tema",
|
||||
"description": "Elige cómo se ve el sitio para ti. Selecciona un solo tema o sincronízalo con tu sistema y cambia automáticamente entre temas de día y noche.",
|
||||
"themeMode": "Modo de tema",
|
||||
"light": "Claro",
|
||||
"dark": "Oscuro",
|
||||
"system": "Sistema"
|
||||
},
|
||||
"notifications": {
|
||||
"settingsSaved": "Configuración guardada con éxito",
|
||||
"settingsSaveFailed": "Error al guardar la configuración",
|
||||
"invalidWebhook": "URL de webhook no válida"
|
||||
},
|
||||
"profile": {
|
||||
"title": "Configuración del Perfil",
|
||||
"description": "Actualiza tu nombre para mostrar y foto de perfil.",
|
||||
"photoUpdated": "Foto Actualizada",
|
||||
"photoUpdatedMessage": "¡Tu foto de perfil ha sido actualizada con éxito!",
|
||||
"uploadFailed": "Error al Subir",
|
||||
"uploadFailedMessage": "Error al subir tu foto. Por favor, inténtalo de nuevo.",
|
||||
"profileUpdated": "Perfil Actualizado",
|
||||
"profileUpdatedMessage": "¡Tu información de perfil ha sido guardada con éxito!",
|
||||
"updateFailed": "Error al Actualizar",
|
||||
"updateFailedMessage": "No se pudo actualizar tu perfil. Por favor, verifica tu conexión e inténtalo de nuevo.",
|
||||
"changePhoto": "Cambiar Foto",
|
||||
"displayName": "Nombre para Mostrar",
|
||||
"displayNamePlaceholder": "Ingresa tu nombre para mostrar",
|
||||
"timezone": "Zona Horaria",
|
||||
"timezonePlaceholder": "Selecciona tu zona horaria",
|
||||
"title": "Ajustes",
|
||||
"common": {
|
||||
"save": "Guardar",
|
||||
"cancel": "Cancelar"
|
||||
"cancel": "Cancelar",
|
||||
"confirm": "Confirmar",
|
||||
"remove": "Eliminar",
|
||||
"delete": "Borrar",
|
||||
"refresh": "Actualizar",
|
||||
"loading": "Cargando…",
|
||||
"on": "Sí",
|
||||
"off": "No",
|
||||
"error": "Error",
|
||||
"success": "Listo",
|
||||
"plusFeature": "Función Plus",
|
||||
"earlyAccess": "Acceso anticipado"
|
||||
},
|
||||
"overview": {
|
||||
"title": "Configuración",
|
||||
"subtitle": "Personaliza tu experiencia y administra las preferencias de tu cuenta",
|
||||
"title": "Ajustes",
|
||||
"subtitle": "Personaliza tu experiencia y gestiona las preferencias de tu cuenta",
|
||||
"upgrade": {
|
||||
"title": "Actualizar a Plus",
|
||||
"description": "Desbloquea funciones potentes para mejorar tu productividad",
|
||||
"button": "Actualizar Ahora",
|
||||
"title": "Mejora a Plus",
|
||||
"description": "Desbloquea funciones potentes para aumentar tu productividad",
|
||||
"button": "Mejorar ahora",
|
||||
"features": {
|
||||
"richText": "Descripciones en texto enriquecido",
|
||||
"richText": "Descripciones con texto enriquecido",
|
||||
"notifications": "Notificaciones de tareas",
|
||||
"apiIntegrations": "Integraciones API",
|
||||
"apiIntegrations": "Integraciones con API",
|
||||
"advancedAutomation": "Automatización avanzada"
|
||||
}
|
||||
},
|
||||
"sections": {
|
||||
"profile": {
|
||||
"title": "Configuración del Perfil",
|
||||
"description": "Actualiza tu información de perfil, foto, nombre para mostrar y preferencias de zona horaria."
|
||||
"title": "Ajustes de perfil",
|
||||
"description": "Actualiza tu información de perfil, foto, nombre visible y zona horaria."
|
||||
},
|
||||
"circle": {
|
||||
"title": "Configuración del Círculo",
|
||||
"description": "Administra tu círculo, invita miembros y gestiona solicitudes de unión."
|
||||
"title": "Ajustes del círculo",
|
||||
"description": "Gestiona tu círculo, invita miembros y atiende las solicitudes de acceso."
|
||||
},
|
||||
"account": {
|
||||
"title": "Configuración de la Cuenta",
|
||||
"description": "Administra tu suscripción, cambia la contraseña y opciones de eliminación de cuenta."
|
||||
"title": "Ajustes de cuenta",
|
||||
"description": "Gestiona tu suscripción, cambia la contraseña y elimina tu cuenta."
|
||||
},
|
||||
"subaccounts": {
|
||||
"title": "Cuentas Administradas",
|
||||
"description": "Crea y administra subcuentas para iniciar sesión y completar tareas asignadas."
|
||||
"title": "Cuentas gestionadas",
|
||||
"description": "Crea y gestiona subcuentas para que puedan iniciar sesión y completar las tareas asignadas."
|
||||
},
|
||||
"notifications": {
|
||||
"title": "Notificaciones",
|
||||
"description": "Configura notificaciones push, alertas por correo electrónico y destinos de notificación para tareas."
|
||||
"description": "Configura notificaciones push, avisos por correo y destinos de notificación para las tareas."
|
||||
},
|
||||
"mfa": {
|
||||
"title": "Autenticación Multifactor",
|
||||
"description": "Agrega una capa adicional de seguridad con MFA usando aplicaciones de autenticación."
|
||||
"title": "Autenticación multifactor",
|
||||
"description": "Añade una capa extra de seguridad con MFA usando apps de autenticación."
|
||||
},
|
||||
"apitokens": {
|
||||
"title": "Tokens API",
|
||||
"description": "Genera y administra tokens de acceso para integraciones de terceros y acceso a la API."
|
||||
"title": "Tokens de API",
|
||||
"description": "Genera y gestiona tokens de acceso para integraciones de terceros y acceso a la API."
|
||||
},
|
||||
"storage": {
|
||||
"title": "Configuración de Almacenamiento",
|
||||
"description": "Respalda y restaura tus datos, administra el almacenamiento local y las preferencias de sincronización."
|
||||
"title": "Ajustes de almacenamiento",
|
||||
"description": "Haz copias de seguridad y restaura tus datos, gestiona el almacenamiento local y la sincronización."
|
||||
},
|
||||
"sidepanel": {
|
||||
"title": "Personalización del Panel Lateral",
|
||||
"description": "Personaliza el diseño y la visibilidad de las tarjetas en la interfaz del panel lateral."
|
||||
"title": "Personalización del panel lateral",
|
||||
"description": "Personaliza la disposición y la visibilidad de las tarjetas del panel lateral."
|
||||
},
|
||||
"theme": {
|
||||
"title": "Preferencias de Tema",
|
||||
"description": "Elige tu tema preferido y configura los ajustes de modo oscuro/claro."
|
||||
"title": "Preferencias de tema",
|
||||
"description": "Elige tu tema preferido y configura el modo claro/oscuro."
|
||||
},
|
||||
"localization": {
|
||||
"title": "Localización",
|
||||
"description": "Personaliza el idioma, formato de fecha, formato de hora y preferencias regionales."
|
||||
"description": "Personaliza el idioma, el formato de fecha y hora y las preferencias regionales."
|
||||
},
|
||||
"advanced": {
|
||||
"title": "Configuración Avanzada",
|
||||
"description": "Configura webhooks, actualizaciones en tiempo real y otras funciones avanzadas para mejorar la productividad."
|
||||
"title": "Ajustes avanzados",
|
||||
"description": "Configura webhooks, actualizaciones en tiempo real y otras funciones avanzadas."
|
||||
},
|
||||
"developer": {
|
||||
"title": "Configuración de Desarrollador",
|
||||
"description": "Ver información técnica sobre tokens de autenticación, conexiones SSE y datos de depuración."
|
||||
"title": "Ajustes de desarrollador",
|
||||
"description": "Consulta información técnica sobre tokens de autenticación, conexiones SSE y datos de depuración."
|
||||
},
|
||||
"feedback": {
|
||||
"title": "Enviar comentarios",
|
||||
"description": "Cuéntanos qué tal te funciona Donetick o pide una función."
|
||||
},
|
||||
"bugReport": {
|
||||
"title": "Informar de un error",
|
||||
"description": "¿Algo no funciona bien? Envíanos los detalles junto con una instantánea técnica."
|
||||
}
|
||||
}
|
||||
},
|
||||
"profile": {
|
||||
"title": "Ajustes de perfil",
|
||||
"description": "Actualiza tu nombre visible y tu foto de perfil.",
|
||||
"photoUpdated": "Foto actualizada",
|
||||
"photoUpdatedMessage": "¡Tu foto de perfil se ha actualizado correctamente!",
|
||||
"uploadFailed": "Error al subir",
|
||||
"uploadFailedMessage": "No se pudo subir tu foto. Inténtalo de nuevo.",
|
||||
"profileUpdated": "Perfil actualizado",
|
||||
"profileUpdatedMessage": "¡La información de tu perfil se ha guardado correctamente!",
|
||||
"updateFailed": "Error al actualizar",
|
||||
"updateFailedMessage": "No se pudo actualizar tu perfil. Comprueba tu conexión e inténtalo de nuevo.",
|
||||
"changePhoto": "Cambiar foto",
|
||||
"editPhoto": "Editar foto de perfil",
|
||||
"displayName": "Nombre visible",
|
||||
"displayNamePlaceholder": "Escribe tu nombre visible",
|
||||
"timezone": "Zona horaria",
|
||||
"timezonePlaceholder": "Selecciona tu zona horaria",
|
||||
"save": "Guardar",
|
||||
"cancel": "Cancelar"
|
||||
},
|
||||
"circleSettings": {
|
||||
"title": "Ajustes del círculo",
|
||||
"description": "Tu cuenta se conecta automáticamente a un círculo cuando creas uno o te unes. Invita a tus amigos compartiendo el código o el enlace del círculo que aparece abajo. Recibirás un aviso aquí cuando alguien pida unirse a tu círculo.",
|
||||
"memberOf": "Formas parte de {{name}}",
|
||||
"yourCircleCode": "Tu código de círculo es:",
|
||||
"copyCode": "Copiar código",
|
||||
"shareInvite": "Compartir invitación",
|
||||
"codeCopied": "Código copiado al portapapeles",
|
||||
"linkCopied": "Enlace de invitación copiado al portapapeles",
|
||||
"myCircle": "mi círculo",
|
||||
"shareTitle": "Únete a {{name}} en Donetick",
|
||||
"shareText": "Me gustaría invitarte a unirte a {{name}} en Donetick.",
|
||||
"shareDialogTitle": "Compartir invitación al círculo",
|
||||
"leave": "Salir del círculo",
|
||||
"leaveConfirmTitle": "Salir del círculo",
|
||||
"leaveConfirmMessage": "¿Seguro que quieres salir de tu círculo?",
|
||||
"leaveConfirmButton": "Salir",
|
||||
"leftCircle": "Has salido del círculo correctamente",
|
||||
"leaveFailed": "No se pudo salir del círculo",
|
||||
"circleMembers": "Miembros del círculo",
|
||||
"you": "(Tú)",
|
||||
"pendingApproval": "Pendiente de aprobación",
|
||||
"joinedOn": "Se unió el {{date}}",
|
||||
"requestedToJoin": "Solicitud de acceso {{date}}",
|
||||
"roles": {
|
||||
"member": "Miembro",
|
||||
"memberDescription": "Un miembro normal del círculo",
|
||||
"manager": "Gestor",
|
||||
"managerDescription": "Puede suplantar a otras personas y actuar en su nombre",
|
||||
"admin": "Administrador",
|
||||
"adminDescription": "Acceso total al círculo"
|
||||
},
|
||||
"roleUpdateFailed": "No se pudo actualizar el rol",
|
||||
"removeMemberTitle": "Eliminar miembro",
|
||||
"removeMemberMessage": "¿Seguro que quieres eliminar a {{name}} de tu círculo?",
|
||||
"memberRemoved": "Miembro eliminado correctamente",
|
||||
"circleMemberRequests": "Solicitudes de acceso al círculo",
|
||||
"lastUpdated": "Última actualización: {{time}}",
|
||||
"refreshing": "Actualizando…",
|
||||
"refreshFailed": "No se pudieron actualizar las solicitudes de acceso",
|
||||
"wantsToJoin": "{{name}} quiere unirse a tu círculo.",
|
||||
"accept": "Aceptar",
|
||||
"acceptRequestTitle": "Aceptar solicitud de acceso",
|
||||
"acceptRequestMessage": "¿Seguro que quieres aceptar a {{name}} (usuario: {{username}}) en tu círculo?",
|
||||
"requestAccepted": "Solicitud aceptada correctamente",
|
||||
"or": "o",
|
||||
"joinOtherDescription": "¿Quieres unirte al círculo de otra persona? Pídele su código de círculo o su enlace de invitación. Escribe el código abajo para unirte.",
|
||||
"enterCircleCode": "Introduce el código del círculo:",
|
||||
"enterCodePlaceholder": "Introduce el código",
|
||||
"joinCircle": "Unirse al círculo",
|
||||
"joinedPending": "Te has unido al círculo correctamente; espera a que la persona propietaria acepte tu solicitud.",
|
||||
"alreadyMember": "Ya eres miembro de este círculo",
|
||||
"joinFailed": "No se pudo unir al círculo"
|
||||
},
|
||||
"accountSettings": {
|
||||
"title": "Ajustes de cuenta",
|
||||
"description": "Cambia los ajustes de tu cuenta, el tipo de plan o tu contraseña",
|
||||
"accountType": "Tipo de cuenta: {{type}}",
|
||||
"free": "Gratis",
|
||||
"plus": "Plus",
|
||||
"plusUntil": "Plus (hasta el {{date}})",
|
||||
"activeDescription": "Actualmente tienes el plan Plus. Tu suscripción se renovará el {{date}}.",
|
||||
"cancelledDescription": "Has cancelado tu suscripción. Tu cuenta pasará al plan Gratis el {{date}}.",
|
||||
"freeDescription": "Actualmente tienes el plan Gratis. Mejora a Plus para desbloquear más funciones.",
|
||||
"upgrade": "Mejorar",
|
||||
"cancel": "Cancelar",
|
||||
"password": "Contraseña:",
|
||||
"changePassword": "Cambiar contraseña",
|
||||
"passwordChanged": "Contraseña cambiada correctamente",
|
||||
"passwordChangeFailed": "No se pudo cambiar la contraseña",
|
||||
"dangerZone": "Zona de peligro",
|
||||
"dangerZoneDescription": "Una vez que elimines tu cuenta, no hay vuelta atrás. Asegúrate antes de continuar.",
|
||||
"deleteAccount": "Eliminar cuenta",
|
||||
"accountDeleted": "Cuenta eliminada correctamente",
|
||||
"subscriptionCancelled": "Suscripción cancelada",
|
||||
"subscriptionCancelFailed": "No se pudo cancelar la suscripción",
|
||||
"purchase": {
|
||||
"success": "¡Compra realizada! Reinicia la app para acceder a las funciones Plus.",
|
||||
"storeConnection": "Problema de conexión con la tienda. Comprueba tu red e inténtalo de nuevo.",
|
||||
"notAllowed": "Las compras no están permitidas en este dispositivo. Revisa las restricciones de tu dispositivo.",
|
||||
"unavailable": "Esta suscripción no está disponible. Inténtalo más tarde.",
|
||||
"alreadyProcessed": "Esta compra ya se ha procesado. Si crees que es un error, ponte en contacto con el soporte.",
|
||||
"receiptMissing": "Falta el recibo de compra. Intenta comprar de nuevo.",
|
||||
"networkError": "Error de red. Comprueba tu conexión e inténtalo de nuevo.",
|
||||
"invalidReceipt": "Recibo de compra no válido. Ponte en contacto con el soporte si el problema persiste.",
|
||||
"pending": "El pago está pendiente de aprobación. Tendrás acceso en cuanto se apruebe.",
|
||||
"failed": "La compra ha fallado: {{error}}. Inténtalo de nuevo o contacta con el soporte.",
|
||||
"unknownError": "Error desconocido"
|
||||
}
|
||||
},
|
||||
"subaccounts": {
|
||||
"title": "Cuentas gestionadas",
|
||||
"description": "Gestiona las subcuentas. Sus usuarios pueden iniciar sesión y completar las tareas asignadas.",
|
||||
"notParentTitle": "Gestión de subcuentas",
|
||||
"notParentMessage": "Solo las cuentas principales pueden gestionar subcuentas.",
|
||||
"freePlanNotice": "El plan Gratis permite 1 subcuenta. Mejora a Plus para tener hasta 5 subcuentas.",
|
||||
"count": "Subcuentas ({{count}})",
|
||||
"add": "Añadir subcuenta",
|
||||
"loading": "Cargando subcuentas…",
|
||||
"emptyTitle": "No hay subcuentas",
|
||||
"emptyDescription": "Crea subcuentas para que los miembros del equipo puedan iniciar sesión y completar sus tareas.",
|
||||
"addFirst": "Añade tu primera subcuenta",
|
||||
"username": "Usuario: {{username}}",
|
||||
"created": "Creada: {{date}}",
|
||||
"changePassword": "Cambiar contraseña",
|
||||
"deleteAccount": "Eliminar cuenta",
|
||||
"createdSuccess": "¡La subcuenta «{{name}}» se ha creado correctamente!",
|
||||
"createFailed": "No se pudo crear la subcuenta: {{error}}",
|
||||
"createFailedGeneric": "No se pudo crear la subcuenta",
|
||||
"passwordUpdated": "Contraseña de la subcuenta actualizada correctamente",
|
||||
"passwordUpdateFailed": "No se pudo actualizar la contraseña: {{error}}",
|
||||
"passwordUpdateFailedGeneric": "No se pudo actualizar la contraseña",
|
||||
"deleteConfirmTitle": "Eliminar subcuenta",
|
||||
"deleteConfirmMessage": "¿Seguro que quieres eliminar la subcuenta «{{name}}»? Esta acción no se puede deshacer.",
|
||||
"deleted": "Subcuenta «{{name}}» eliminada correctamente",
|
||||
"deleteFailed": "No se pudo eliminar la subcuenta: {{error}}",
|
||||
"deleteFailedGeneric": "No se pudo eliminar la subcuenta",
|
||||
"howItWorksTitle": "Cómo funcionan las cuentas gestionadas",
|
||||
"howItWorks1": "Las cuentas gestionadas las crea la cuenta principal; son para personas cuya cuenta quieres poder eliminar y cuya contraseña quieres poder restablecer.",
|
||||
"howItWorks2": "Las subcuentas pueden iniciar sesión con su propio usuario y contraseña.",
|
||||
"howItWorks3": "Las cuentas gestionadas pueden completar tareas, pero tienen permisos administrativos limitados",
|
||||
"howItWorks4": "Las cuentas gestionadas se añaden automáticamente a tu círculo"
|
||||
},
|
||||
"notifications": {
|
||||
"title": "Ajustes de notificaciones",
|
||||
"deviceSection": "Notificaciones del dispositivo",
|
||||
"deviceSectionDescription": "Gestiona las notificaciones de tu dispositivo",
|
||||
"deviceLabel": "Notificación del dispositivo",
|
||||
"deviceHelper": "Recibe una notificación en tu dispositivo cuando venza una tarea",
|
||||
"mobileOnly": "Esta función solo está disponible en dispositivos móviles",
|
||||
"testNotification": "Notificación de prueba",
|
||||
"testNotificationBody": "Tienes una tarea que vence pronto",
|
||||
"dueTitle": "Notificación de vencimiento",
|
||||
"dueLabel": "Notificación cuando la tarea vence",
|
||||
"preDueTitle": "Notificación previa al vencimiento",
|
||||
"preDueLabel": "Notificación unas horas antes de que venza la tarea",
|
||||
"overdueTitle": "Notificación de retraso",
|
||||
"overdueLabel": "Notificación cuando la tarea está vencida",
|
||||
"pushLabel": "Notificaciones push",
|
||||
"pushHelper": "Recibe recordatorios, anuncios y asignaciones de tareas por notificación push",
|
||||
"registeredDevices": "Dispositivos registrados ({{count}}/5)",
|
||||
"registeredDevicesDescription": "Dispositivos registrados para recibir notificaciones push de tu cuenta",
|
||||
"currentDevice": "Dispositivo actual: {{platform}} {{model}}",
|
||||
"currentDeviceNotRegistered": "Este dispositivo no está registrado para notificaciones push",
|
||||
"limitReached": "Límite alcanzado",
|
||||
"registerDevice": "Registrar dispositivo",
|
||||
"unknownDevice": "Dispositivo desconocido",
|
||||
"deviceCreatedAt": "Creado el: {{date}}",
|
||||
"noDevices": "No hay dispositivos registrados para notificaciones push",
|
||||
"customSection": "Notificación personalizada",
|
||||
"customSectionDescription": "Notificaciones a través de otras plataformas como Telegram o Pushover",
|
||||
"customLabel": "Notificación personalizada",
|
||||
"customHelper": "Recibe notificaciones en otra plataforma",
|
||||
"targetNone": "Ninguna",
|
||||
"targetTelegram": "Telegram",
|
||||
"targetPushover": "Pushover",
|
||||
"targetWebhooks": "Webhooks",
|
||||
"telegramBotHelpBefore": "Debes escribir primero al bot para que funcionen las notificaciones de Telegram",
|
||||
"telegramBotHelpAfter": "para iniciar un chat",
|
||||
"clickHere": "Haz clic aquí",
|
||||
"chatId": "ID de chat",
|
||||
"chatIdPlaceholder": "ID de usuario / ID de chat",
|
||||
"telegramChatIdHelpBefore": "Si no conoces tu ID de chat, inicia un chat con userinfobot y te lo enviará.",
|
||||
"telegramChatIdHelpAfter": "para iniciar un chat con userinfobot",
|
||||
"userKey": "Clave de usuario",
|
||||
"userKeyPlaceholder": "ID de usuario",
|
||||
"chatIdRequired": "El ID de chat es obligatorio",
|
||||
"chatIdInvalid": "ID de chat no válido",
|
||||
"userKeyRequired": "La clave de usuario es obligatoria",
|
||||
"targetUpdated": "Destino de notificación actualizado",
|
||||
"targetUpdateFailed": "Error al actualizar el destino de notificación: {{error}}",
|
||||
"deviceRegistered": "Dispositivo registrado correctamente para notificaciones push.",
|
||||
"deviceLimitTitle": "Límite de dispositivos alcanzado",
|
||||
"deviceLimitMessage": "Has alcanzado el máximo de 5 dispositivos registrados. Elimina uno antes de registrar este.",
|
||||
"registrationFailedTitle": "Error de registro",
|
||||
"registrationFailedMessage": "No se pudo registrar el dispositivo automáticamente. Inténtalo de nuevo.",
|
||||
"permissionRequiredTitle": "Permiso necesario",
|
||||
"permissionRequiredMessage": "Se necesita permiso de notificaciones push para registrar este dispositivo.",
|
||||
"registrationInitiatedTitle": "Registro iniciado",
|
||||
"registrationInitiatedMessage": "Se ha iniciado el registro de notificaciones push. El dispositivo se registrará automáticamente.",
|
||||
"registerDeviceFailed": "No se pudo registrar el dispositivo. Inténtalo de nuevo.",
|
||||
"permissionDeniedTitle": "Permiso de notificaciones denegado",
|
||||
"permissionDeniedMessage": "Has denegado los permisos de notificación. Puedes activarlos más tarde en los ajustes de tu dispositivo.",
|
||||
"pushPermissionDeniedTitle": "Permiso de notificaciones push denegado",
|
||||
"pushPermissionDeniedMessage": "Se han desactivado las notificaciones push. Puedes activarlas en los ajustes de tu dispositivo si lo necesitas.",
|
||||
"unregisterFailed": "No se pudo dar de baja el dispositivo"
|
||||
},
|
||||
"mfa": {
|
||||
"title": "Autenticación multifactor",
|
||||
"description": "Añade una capa extra de seguridad a tu cuenta con la autenticación multifactor (MFA). Cuando está activada, al iniciar sesión tendrás que introducir un código de verificación de tu app de autenticación además de tu contraseña.",
|
||||
"twoFactor": "Autenticación en dos pasos",
|
||||
"enabledSubtitle": "Tu cuenta está protegida con 2FA",
|
||||
"disabledSubtitle": "Protege tu cuenta con una app de autenticación",
|
||||
"enable": "Activar",
|
||||
"disable": "Desactivar",
|
||||
"enabledSuccess": "¡La MFA se ha activado correctamente!",
|
||||
"disabledSuccess": "¡La MFA se ha desactivado correctamente!",
|
||||
"errors": {
|
||||
"qrGenerationFailed": "No se pudo generar el código QR",
|
||||
"invalidResponse": "Respuesta del servidor no válida. Falta el código QR o la clave.",
|
||||
"notFound": "No se encontró el endpoint de configuración de MFA. Puede que esta función aún no esté disponible.",
|
||||
"unauthorized": "No autorizado. Inicia sesión de nuevo.",
|
||||
"serverError": "Error del servidor. Inténtalo más tarde.",
|
||||
"setupFailed": "No se pudo configurar la MFA ({{status}}). Inténtalo de nuevo.",
|
||||
"networkError": "Error de red. Comprueba tu conexión e inténtalo de nuevo.",
|
||||
"invalidCode": "Código de verificación no válido. Inténtalo de nuevo.",
|
||||
"confirmFailed": "No se pudo confirmar la MFA. Inténtalo de nuevo.",
|
||||
"disableFailed": "No se pudo desactivar la MFA. Inténtalo de nuevo."
|
||||
},
|
||||
"setup": {
|
||||
"title": "Configurar la autenticación multifactor",
|
||||
"addedAccount": "Ya he añadido la cuenta",
|
||||
"back": "Atrás",
|
||||
"verifyAndEnable": "Verificar y activar",
|
||||
"savedBackupCodes": "He guardado mis códigos de respaldo",
|
||||
"step1Label": "Paso 1:",
|
||||
"step1": "Escanea el código QR de abajo con tu app de autenticación (Google Authenticator, Authy, etc.)",
|
||||
"qrAlt": "Código QR de MFA",
|
||||
"qrFailed": "No se pudo generar el código QR. Inténtalo de nuevo o usa la clave manual de abajo.",
|
||||
"manualKey": "Clave de introducción manual:",
|
||||
"step2Label": "Paso 2:",
|
||||
"step2": "Introduce el código de verificación de 6 dígitos de tu app de autenticación",
|
||||
"codePlaceholder": "Introduce el código de 6 dígitos",
|
||||
"successTitle": "¡MFA activada correctamente!",
|
||||
"backupCodesTitle": "Guarda estos códigos de respaldo en un lugar seguro",
|
||||
"backupCodesDescription": "Puedes usar estos códigos para acceder a tu cuenta si pierdes tu dispositivo de autenticación. Cada código solo se puede usar una vez."
|
||||
},
|
||||
"disableModal": {
|
||||
"title": "Desactivar la autenticación multifactor",
|
||||
"warning": "Desactivar la MFA hará que tu cuenta sea menos segura. ¿Seguro que quieres continuar?",
|
||||
"prompt": "Introduce un código de verificación de tu app de autenticación para confirmar:",
|
||||
"confirm": "Desactivar MFA"
|
||||
},
|
||||
"backupCodesModal": {
|
||||
"title": "Nuevos códigos de respaldo",
|
||||
"warning": "Tus códigos de respaldo anteriores ya no son válidos. Guarda estos nuevos códigos en un lugar seguro. Cada código solo se puede usar una vez."
|
||||
}
|
||||
},
|
||||
"apiTokens": {
|
||||
"title": "Tokens de API",
|
||||
"accessToken": "Token de acceso",
|
||||
"description": "Crea un token para usar con la API y actualizar cosas que activan tareas",
|
||||
"plusNotice": "Los tokens de API no están disponibles en el plan Básico. Mejora a Plus para generar tokens de API e integrarte con sistemas externos y automatizar tus tareas.",
|
||||
"showToken": "Mostrar token",
|
||||
"hideToken": "Ocultar token",
|
||||
"removeTitle": "Eliminar token",
|
||||
"removeMessage": "¿Seguro que quieres eliminar {{name}}?",
|
||||
"removedTitle": "Eliminado",
|
||||
"removedMessage": "El token de API se ha eliminado",
|
||||
"tokenCopied": "Token copiado al portapapeles",
|
||||
"generateNew": "Generar nuevo token",
|
||||
"nameModalTitle": "Dale un nombre a tu nuevo token, algo con lo que lo reconozcas.",
|
||||
"generateToken": "Generar token"
|
||||
},
|
||||
"storage": {
|
||||
"title": "Ajustes de almacenamiento",
|
||||
"serverTitle": "Uso del almacenamiento en el servidor",
|
||||
"serverDescription": "Este es el almacenamiento que usa tu cuenta en nuestros servidores (por ejemplo, archivos, imágenes y datos que has subido).",
|
||||
"usagePlaceholder": "-- MB usados / -- MB en total (--)",
|
||||
"usage": "{{used}} MB usados / {{total}} MB en total ({{percent}} %)",
|
||||
"basicPlanNotice": "El almacenamiento en el servidor no está disponible en el plan Básico. Mejora a Plus para consultar tu uso.",
|
||||
"localTitleApp": "Almacenamiento local y caché de la app",
|
||||
"localTitleBrowser": "Almacenamiento local y caché del navegador",
|
||||
"localDescription": "Son datos guardados localmente en tu navegador para un acceso más rápido. Borrarlos no afectará a tus datos del servidor, pero puede cerrar tu sesión.",
|
||||
"clearLocal": "Borrar todo el almacenamiento local y la caché",
|
||||
"clearLocalTitle": "Borrar todo el almacenamiento local",
|
||||
"clearLocalMessage": "¿Seguro que quieres borrar tu almacenamiento local y la caché? Se eliminarán todos tus datos de este navegador y tendrás que iniciar sesión de nuevo.",
|
||||
"clearAll": "Borrar todo",
|
||||
"appPreferences": "Preferencias de la app",
|
||||
"deviceOnly": "Solo en el dispositivo",
|
||||
"appPreferencesDescription": "Son preferencias y ajustes que la app guarda localmente en tu dispositivo. Al borrarlos se restablecerán los ajustes de la app y puede que se cierre tu sesión, pero no afectará a tus datos del servidor.",
|
||||
"clearPreferences": "Borrar preferencias de la app",
|
||||
"clearPreferencesTitle": "Borrar preferencias de la app",
|
||||
"clearPreferencesMessage": "¿Seguro que quieres borrar todas las preferencias de la app? Se restablecerán tus ajustes y puede que tengas que iniciar sesión de nuevo."
|
||||
},
|
||||
"sidepanel": {
|
||||
"title": "Personalización del panel lateral",
|
||||
"heading": "Ajustes del panel lateral",
|
||||
"description": "Elige qué tarjetas aparecen en el panel lateral y en qué orden. Arrastra y suelta para reordenarlas o cambia su visibilidad.",
|
||||
"resetToDefaults": "Restablecer valores predeterminados",
|
||||
"resetHelper": "Se restablecerán la visibilidad y el orden predeterminados de todas las tarjetas.",
|
||||
"cards": {
|
||||
"welcome": {
|
||||
"name": "Cambio de usuario",
|
||||
"description": "Permite a administradores y gestores ver las tareas como otras personas"
|
||||
},
|
||||
"smartInsights": {
|
||||
"name": "Ideas inteligentes",
|
||||
"description": "Acciones rápidas basadas en tus tareas"
|
||||
},
|
||||
"assignees": {
|
||||
"name": "Tareas por responsable",
|
||||
"description": "Agrupa las tareas según a quién estén asignadas"
|
||||
},
|
||||
"calendar": {
|
||||
"name": "Vista de calendario",
|
||||
"description": "Muestra las tareas en formato de calendario"
|
||||
},
|
||||
"activities": {
|
||||
"name": "Actividad reciente",
|
||||
"description": "Muestra las tareas completadas y la actividad reciente"
|
||||
},
|
||||
"weeklyGoals": {
|
||||
"name": "Objetivos semanales",
|
||||
"description": "Muestra el progreso semanal y las estadísticas de la familia"
|
||||
}
|
||||
}
|
||||
},
|
||||
"theme": {
|
||||
"title": "Preferencias de tema",
|
||||
"description": "Elige cómo se ve la aplicación. Selecciona un tema fijo o sincronízalo con tu sistema para cambiar automáticamente entre el modo claro y oscuro.",
|
||||
"themeMode": "Modo de tema",
|
||||
"light": "Claro",
|
||||
"dark": "Oscuro",
|
||||
"system": "Sistema"
|
||||
},
|
||||
"localization": {
|
||||
"title": "Localización",
|
||||
"description": "Personaliza el idioma, el formato de fecha y las preferencias regionales de tu cuenta.",
|
||||
"language": "Idioma",
|
||||
"languageDescription": "Selecciona tu idioma preferido",
|
||||
"rtlNotice": "Este idioma se escribe de derecha a izquierda (RTL)",
|
||||
"dateFormat": "Formato de fecha",
|
||||
"dateFormatDescription": "Elige cómo se muestran las fechas en toda la aplicación",
|
||||
"timeFormat": "Formato de hora",
|
||||
"timeFormatDescription": "Selecciona el formato de 12 o 24 horas",
|
||||
"preview": "Vista previa: {{value}}",
|
||||
"12hour": "12 horas (a. m./p. m.)",
|
||||
"24hour": "24 horas",
|
||||
"firstDayOfWeek": "Primer día de la semana",
|
||||
"firstDayOfWeekDescription": "Elige con qué día empieza tu semana",
|
||||
"sunday": "Domingo",
|
||||
"monday": "Lunes",
|
||||
"saturday": "Sábado",
|
||||
"formats": {
|
||||
"mdy": "MM/DD/AAAA (EE. UU.)",
|
||||
"dmy": "DD/MM/AAAA (Europa)",
|
||||
"ymd": "AAAA-MM-DD (ISO)",
|
||||
"long": "Formato largo (p. ej., 1 de enero de 2024)",
|
||||
"short": "Formato corto (p. ej., 1 ene 2024)"
|
||||
}
|
||||
},
|
||||
"advanced": {
|
||||
"title": "Ajustes avanzados",
|
||||
"description": "Configura funciones avanzadas como webhooks y actualizaciones en tiempo real para mejorar tu productividad.",
|
||||
"offlineTitle": "Modo sin conexión",
|
||||
"offlineDescription": "Sigue usando Donetick sin conexión en este dispositivo o navegador. Tus cambios se guardan localmente y se sincronizan cuando vuelvas a estar en línea.",
|
||||
"offlineToggle": "Activar el modo sin conexión",
|
||||
"offlineHelper": "Al desactivarlo se eliminan los cambios sin conexión no sincronizados y los datos guardados en este dispositivo o navegador.",
|
||||
"offlineEnabled": "Modo sin conexión activado en este dispositivo o navegador",
|
||||
"offlineDisabled": "Modo sin conexión desactivado y datos locales borrados",
|
||||
"offlineDisabledPartial": "Se desactivó el modo sin conexión, pero puede que aún queden algunos datos locales guardados",
|
||||
"offlineDisableTitle": "Desactivar el modo sin conexión",
|
||||
"offlineDisableMessage": "Al desactivar el modo sin conexión se eliminarán los cambios sin sincronizar y los datos guardados en este dispositivo o navegador. ¿Quieres continuar?",
|
||||
"offlineDisableConfirm": "Desactivar y borrar datos",
|
||||
"webhookTitle": "Integración con webhooks",
|
||||
"webhookDescription": "Los webhooks te permiten enviar notificaciones en tiempo real a otros servicios cuando ocurre algo en tu círculo. Configura una URL de webhook para recibir actualizaciones en tiempo real.",
|
||||
"webhookPlusNotice": "Las notificaciones por webhook no están disponibles en el plan Básico. Mejora a Plus para recibir actualizaciones en tiempo real por webhook.",
|
||||
"webhookToggle": "Activar webhook",
|
||||
"webhookHelper": "Activa las notificaciones por webhook para las actualizaciones de tareas y cosas.",
|
||||
"webhookURL": "URL del webhook",
|
||||
"webhookUpdated": "URL del webhook actualizada correctamente",
|
||||
"webhookUpdateFailed": "No se pudo actualizar la URL del webhook",
|
||||
"realtimeTitle": "Actualizaciones en tiempo real",
|
||||
"realtimeDescription": "Configura cómo recibes actualizaciones en vivo cuando cambian las tareas y actividades de tu círculo.",
|
||||
"realtime": {
|
||||
"toggleLabel": "Activar actualizaciones en tiempo real",
|
||||
"title": "Actualizaciones en tiempo real",
|
||||
"subtitle": "Recibe notificaciones al instante cuando se actualicen las tareas",
|
||||
"statusLabel": "Estado:",
|
||||
"basicPlan": "Las actualizaciones en tiempo real no están disponibles en el plan Básico. Mejora a Plus para recibir notificaciones instantáneas cuando se actualicen las tareas.",
|
||||
"disabled": "Las actualizaciones en tiempo real están desactivadas. Actívalas para ver los cambios en vivo cuando tú u otros miembros del círculo completéis, omitáis o modifiquéis tareas.",
|
||||
"connected": "Las actualizaciones en tiempo real funcionan. Verás los cambios en vivo cuando tú u otros miembros del círculo completéis, omitáis o modifiquéis tareas.",
|
||||
"connecting": "Conectando a las actualizaciones en tiempo real…",
|
||||
"errored": "Las actualizaciones en tiempo real están activadas pero no funcionan: {{error}}",
|
||||
"notConnected": "Las actualizaciones en tiempo real están activadas pero ahora mismo no hay conexión.",
|
||||
"basicPlanNotice": "Las actualizaciones en tiempo real no están disponibles en el plan Básico. Mejora a Plus para recibir notificaciones instantáneas cuando tú u otros miembros del círculo completéis, omitáis o modifiquéis tareas."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
111
public/locales/es/auth.json
Normal file
111
public/locales/es/auth.json
Normal file
@@ -0,0 +1,111 @@
|
||||
{
|
||||
"validationError": "Validation Error",
|
||||
"primaryUsernameRequired": "Primary username is required for sub account login",
|
||||
"subNameRequired": "Sub account name is required for sub account login",
|
||||
"usernameRequired": "Username is required",
|
||||
"passwordRequired": "Password is required",
|
||||
"loginFailed": "Login Failed",
|
||||
"genericError": "An error occurred, please try again",
|
||||
"providerLoginFailed": "{{provider}} Login Failed",
|
||||
"providerLoginFailedMsg": "Couldn't log in with {{provider}}, please try again",
|
||||
"providerLoginError": "{{provider}} Login Error",
|
||||
"networkError": "Network error occurred, please try again",
|
||||
"mfaFailed": "Two-Factor Authentication Failed",
|
||||
"oauthError": "OAuth Error",
|
||||
"oauthBrowserFailed": "Failed to open authentication browser",
|
||||
"primaryAccount": "Primary Account",
|
||||
"subAccount": "Sub Account",
|
||||
"username": "Username",
|
||||
"primaryUsernamePlaceholder": "Enter primary account username",
|
||||
"subNamePlaceholder": "Enter sub account name",
|
||||
"forgotPassword": "Forgot password?",
|
||||
"or": "or",
|
||||
"email": "Email",
|
||||
"displayNamePlaceholder": "How others see your name",
|
||||
"signupFailed": "Signup Failed",
|
||||
"signupDisabled": "Signup disabled, please contact admin",
|
||||
"usernameMinLength": "Username must be at least 4 characters",
|
||||
"invalidEmail": "Invalid email address",
|
||||
"passwordLength": "Password must be between 8 and 64 characters",
|
||||
"displayNameRequired": "Display name is required",
|
||||
"displayNameChars": "Display name can only contain letters and numbers",
|
||||
"resetEmailSent": "Reset Email Sent",
|
||||
"resetEmailSentMsg": "Check your email for password reset instructions",
|
||||
"resetFailed": "Reset Failed",
|
||||
"resetFailedMsg": "Failed to send reset email, please try again later",
|
||||
"emailPlaceholder": "you@example.com",
|
||||
"passwordUpdated": "Password Updated",
|
||||
"passwordUpdatedMsg": "Your password has been updated successfully. Redirecting to login...",
|
||||
"passwordUpdateFailed": "Password Update Failed",
|
||||
"passwordUpdateFailedMsg": "Failed to update password, please try again later",
|
||||
"savePassword": "Save password",
|
||||
"server": {
|
||||
"url": "Server URL",
|
||||
"dnsFailed": "Hostname could not be resolved. Check the URL for typos or verify DNS.",
|
||||
"unreachable": "Unable to reach the server. Check the URL, port, and network connection.",
|
||||
"invalidUrl": "Invalid URL format. Include the protocol (http:// or https://) and port if needed."
|
||||
},
|
||||
"mfaModal": {
|
||||
"title": "Two-factor authentication",
|
||||
"codeRequired": "Please enter a verification code",
|
||||
"verifyFailed": "Failed to verify code. Please try again.",
|
||||
"backupHint": "Enter one of the backup codes you saved when setting up two-factor authentication.",
|
||||
"codeHint": "Enter the 6-digit code from your authenticator app.",
|
||||
"verify": "Verify & Sign In",
|
||||
"backupLabel": "Backup code",
|
||||
"codeLabel": "Verification code",
|
||||
"backupPlaceholder": "Enter backup code",
|
||||
"useAuthenticator": "Use authenticator app instead",
|
||||
"useBackup": "Use a backup code instead",
|
||||
"backupOnce": "Each backup code can only be used once.",
|
||||
"invalidCode": "Invalid verification code. Please try again."
|
||||
},
|
||||
"appleLoginFailed": "Apple Login Failed",
|
||||
"googleLoginFailed": "Google Login Failed",
|
||||
"createOne": "Create one",
|
||||
"primaryAccountUsernameLabel": "Primary account username",
|
||||
"subAccountNameLabel": "Sub account name",
|
||||
"serverSettings": "Server settings",
|
||||
"useDifferentAccount": "Use a different account",
|
||||
"yourUsername": "Your username",
|
||||
"backToSignIn": "Back to sign in",
|
||||
"confirmNewPassword": "Confirm new password",
|
||||
"newPassword": "New password",
|
||||
"reenterPassword": "Re-enter your password",
|
||||
"requestNewLink": "Request a new link",
|
||||
"setNewPassword": "Set a new password",
|
||||
"linkInvalid": "This link is not valid",
|
||||
"createAccountButton": "Create account",
|
||||
"createYourAccount": "Create your account",
|
||||
"displayNameLabel": "Display name",
|
||||
"usernameHint": "lowercase letters, numbers, dot and dash",
|
||||
"termsShort": "By creating an account you agree to our Terms of Service and Privacy",
|
||||
"checkYourEmail": "Check your email",
|
||||
"resetYourPassword": "Reset your password",
|
||||
"serverChangeWarning": "Changing the server clears locally cached data on this device.",
|
||||
"serverConnected": "Connected. Taking you to sign in...",
|
||||
"passwordLabel": "Password",
|
||||
"showPassword": "Show password",
|
||||
"hidePassword": "Hide password",
|
||||
"loginPasswordPlaceholder": "Enter your password",
|
||||
"signupPasswordPlaceholder": "At least 8 characters",
|
||||
"signupPasswordHelper": "Use 8 to 64 characters.",
|
||||
"orContinueWith": "or continue with",
|
||||
"signupSignInFailed": "Your account was created, but signing in failed. Please sign in.",
|
||||
"authenticating": {
|
||||
"signingIn": "Signing you in",
|
||||
"signingInSub": "This will only take a moment.",
|
||||
"unknownProvider": "Unknown sign-in provider",
|
||||
"contactSupport": "Please contact support.",
|
||||
"signInFailed": "Sign-in failed",
|
||||
"mfaCancelled": "Two-factor authentication was cancelled.",
|
||||
"requestNotVerified": "The sign-in request could not be verified.",
|
||||
"tryAgain": "Please try again.",
|
||||
"mfaSessionMissing": "The MFA session is missing. Please try again.",
|
||||
"twoFactor": "Two-factor authentication",
|
||||
"verifyToContinue": "Verify your login to continue.",
|
||||
"noToken": "No valid authentication token was returned.",
|
||||
"backToSignIn": "Back to sign in",
|
||||
"mfaFailed": "Two-factor authentication failed. Please try again."
|
||||
}
|
||||
}
|
||||
@@ -71,5 +71,11 @@
|
||||
"reset": "Reiniciar Temporizador",
|
||||
"delete": "Eliminar Sesión"
|
||||
}
|
||||
},
|
||||
"toolbar": {
|
||||
"defaultProject": "Default Project"
|
||||
},
|
||||
"sort": {
|
||||
"assignedToMe": "Assigned to me"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
"logout": "Cerrar Sesión",
|
||||
"version": "Versión",
|
||||
"navigation": {
|
||||
"search": "Buscar",
|
||||
"allTasks": "Todas las Tareas",
|
||||
"archived": "Archivadas",
|
||||
"things": "Cosas",
|
||||
@@ -28,6 +29,123 @@
|
||||
"filters": "Filtros",
|
||||
"activities": "Actividades",
|
||||
"points": "Puntos",
|
||||
"settings": "Configuración"
|
||||
"settings": "Configuración",
|
||||
"reportBug": "Report a Bug"
|
||||
},
|
||||
"search": {
|
||||
"title": "Buscar",
|
||||
"placeholder": "Buscar en Donetick",
|
||||
"inputAriaLabel": "Buscar tareas, historial, proyectos, etiquetas y configuración",
|
||||
"deviceNote": "Se busca en el contenido disponible en este dispositivo",
|
||||
"escape": "Esc",
|
||||
"recent": "Recientes",
|
||||
"empty": {
|
||||
"title": "Sin coincidencias directas",
|
||||
"subtitle": "Aún puedes filtrar la lista de tareas con esta búsqueda."
|
||||
},
|
||||
"groups": {
|
||||
"tasks": "Tareas",
|
||||
"history": "Notas",
|
||||
"projects": "Proyectos",
|
||||
"labels": "Etiquetas",
|
||||
"people": "Personas",
|
||||
"settings": "Configuración",
|
||||
"actions": "Acciones rápidas"
|
||||
},
|
||||
"actions": {
|
||||
"quickAction": "Acción rápida",
|
||||
"navigation": "Navegación",
|
||||
"createTask": "Crear una tarea",
|
||||
"viewAllTasks": "Ver todas las tareas",
|
||||
"viewArchivedTasks": "Ver tareas archivadas",
|
||||
"openSettings": "Abrir configuración",
|
||||
"filterTasks": "Mostrar tareas que coincidan con «{{query}}»",
|
||||
"filterTasksSubtitle": "Filtrar la lista de tareas"
|
||||
},
|
||||
"footer": {
|
||||
"navigate": "Navegar",
|
||||
"open": "Abrir",
|
||||
"results_one": "{{count}} resultado",
|
||||
"results_other": "{{count}} resultados",
|
||||
"typeToSearch": "Escribe para buscar"
|
||||
}
|
||||
},
|
||||
"feedback": {
|
||||
"later": "Maybe later",
|
||||
"sentiment": {
|
||||
"title": "How's Donetick working for you?",
|
||||
"subtitle": "Your answer helps us decide what to build next.",
|
||||
"options": {
|
||||
"love": "Love it",
|
||||
"okay": "It's okay",
|
||||
"issues": "Having issues"
|
||||
}
|
||||
},
|
||||
"categories": {
|
||||
"bugs": "Bugs",
|
||||
"missingFeature": "Missing feature",
|
||||
"tooComplicated": "Too complicated",
|
||||
"slow": "Slow",
|
||||
"notifications": "Notifications",
|
||||
"ai": "AI",
|
||||
"other": "Other"
|
||||
},
|
||||
"details": {
|
||||
"title": "What could we improve?",
|
||||
"messageLabel": "Tell us more",
|
||||
"messagePlaceholder": "What happened, or what would make this better?",
|
||||
"contextNote": "We'll include your app version, device and platform so we can reproduce issues.",
|
||||
"submit": "Send feedback",
|
||||
"contextNoteSelfHosted": "You're on a self-hosted instance, so nothing is sent from your server — we'll open a pre-filled GitHub issue you can review and edit first.",
|
||||
"submitSelfHosted": "Continue to GitHub"
|
||||
},
|
||||
"review": {
|
||||
"title": "Glad you're enjoying it!",
|
||||
"subtitle": "A rating or a star helps other people find Donetick.",
|
||||
"github": "Star on GitHub",
|
||||
"appStore": "Rate on the App Store",
|
||||
"playStore": "Rate on Google Play"
|
||||
},
|
||||
"thanks": {
|
||||
"title": "Thanks for the feedback",
|
||||
"subtitle": "We read every response and it shapes what we work on next."
|
||||
},
|
||||
"github": {
|
||||
"title": "Report it on GitHub",
|
||||
"subtitle": "We've filled in an issue with your notes and version details. Nothing has been sent yet — review it and post when you're ready.",
|
||||
"open": "Open the issue"
|
||||
}
|
||||
},
|
||||
"done": "Done",
|
||||
"clearAll": "Clear all",
|
||||
"upload": {
|
||||
"quotaTitle": "Storage Quota Exceeded",
|
||||
"quotaMessage": "You have exceeded your quota for uploading files.",
|
||||
"tooLargeTitle": "File Too Large",
|
||||
"tooLargeMessage": "The file you are trying to upload is too large.",
|
||||
"deniedTitle": "Permission Denied",
|
||||
"deniedMessage": "You do not have permission to upload files."
|
||||
},
|
||||
"getStarted": "Get Started!",
|
||||
"imageLoadFailed": "Failed to load image.",
|
||||
"typeHere": "Type in here…",
|
||||
"summaryOfChores": "This is a summary of your chores",
|
||||
"loadingOffline": "You are offline",
|
||||
"loadingOfflineSub": "This not available while offline. Please check your internet connection and try again.",
|
||||
"loadingSlow": "This is taking longer than usual. There might be an issue.",
|
||||
"navigateBack": "Navigate Back",
|
||||
"bottomNav": "Bottom Navigation",
|
||||
"profile": "Profile",
|
||||
"autocompletePlaceholder": "Type here...",
|
||||
"errorScreen": {
|
||||
"title": "Something went wrong",
|
||||
"fallback": "An unexpected error occurred. Try reloading — it usually fixes it.",
|
||||
"tryAgain": "Try again",
|
||||
"home": "Home",
|
||||
"login": "Login",
|
||||
"hideDetails": "Hide error details",
|
||||
"showDetails": "Show error details",
|
||||
"copyToClipboard": "Copy to clipboard",
|
||||
"copied": "Error details copied to clipboard"
|
||||
}
|
||||
}
|
||||
|
||||
17
public/locales/es/filters.json
Normal file
17
public/locales/es/filters.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"builder": {
|
||||
"errorName": "Please enter a filter name",
|
||||
"errorConditions": "Please configure at least one filter condition",
|
||||
"editTitle": "Edit Filter",
|
||||
"newTitle": "New Filter",
|
||||
"addConditions": "Add conditions to preview",
|
||||
"save": "Save Filter",
|
||||
"name": "Filter Name",
|
||||
"namePlaceholder": "e.g. Overdue tasks for Alice",
|
||||
"color": "Color"
|
||||
},
|
||||
"nameExists": "A filter with this name already exists",
|
||||
"tasks_one": "{{count}} task",
|
||||
"tasks_other": "{{count}} tasks",
|
||||
"overdue": "{{count}} overdue"
|
||||
}
|
||||
89
public/locales/es/history.json
Normal file
89
public/locales/es/history.json
Normal file
@@ -0,0 +1,89 @@
|
||||
{
|
||||
"edit": {
|
||||
"title": "Edit History",
|
||||
"completedDate": "Completed Date",
|
||||
"note": "Note",
|
||||
"additionalNotes": "Additional Notes",
|
||||
"deleteTitle": "Delete History",
|
||||
"deleteMessage": "Are you sure you want to delete this history?"
|
||||
},
|
||||
"status": {
|
||||
"inProgress": "In Progress",
|
||||
"completed": "Completed",
|
||||
"skipped": "Skipped",
|
||||
"pendingApproval": "Pending Approval",
|
||||
"rejected": "Rejected",
|
||||
"missed": "Missed",
|
||||
"rescheduled": "Rescheduled",
|
||||
"scheduled": "Scheduled"
|
||||
},
|
||||
"badge": {
|
||||
"onTime": "On Time",
|
||||
"onTimeLabel": "On time"
|
||||
},
|
||||
"detail": {
|
||||
"title": "Activity Detail",
|
||||
"openTask": "Open Task",
|
||||
"editEntry": "Edit Entry",
|
||||
"performedBy": "Performed by",
|
||||
"assignedTo": "Assigned to",
|
||||
"lastUpdated": "Last updated",
|
||||
"duration": "Duration",
|
||||
"pointsEarned": "Points earned",
|
||||
"points_one": "{{count}} pt",
|
||||
"points_other": "{{count}} pts",
|
||||
"note": "Note"
|
||||
},
|
||||
"charts": {
|
||||
"noData": "No data available",
|
||||
"noLabels": "No Labels",
|
||||
"unassigned": "Unassigned",
|
||||
"unknownTask": "Unknown Task",
|
||||
"late": "Late",
|
||||
"status": {
|
||||
"title": "Status",
|
||||
"description": "Completed tasks status"
|
||||
},
|
||||
"due": {
|
||||
"title": "Due Date",
|
||||
"description": "Current tasks due date"
|
||||
},
|
||||
"priority": {
|
||||
"title": "Priority",
|
||||
"description": "Tasks by priority"
|
||||
},
|
||||
"labels": {
|
||||
"title": "Labels",
|
||||
"description": "Tasks by labels"
|
||||
},
|
||||
"labelsDuration": {
|
||||
"title": "Labels (time)",
|
||||
"description": "Time spent by labels (hours)"
|
||||
},
|
||||
"tasksTime": {
|
||||
"title": "Tasks (time)",
|
||||
"description": "Time spent by individual tasks (hours)"
|
||||
},
|
||||
"assigneeBreakdown": {
|
||||
"title": "by Assignee",
|
||||
"description": "Tasks grouped by assignee"
|
||||
}
|
||||
},
|
||||
"filter": {
|
||||
"status": "Status",
|
||||
"pending": "Pending",
|
||||
"labels": "Labels",
|
||||
"hasNotes": "Has Notes",
|
||||
"hasPoints": "Has Points",
|
||||
"timePeriod": "Time Period",
|
||||
"user": "User"
|
||||
},
|
||||
"period": {
|
||||
"days_one": "{{count}} Day",
|
||||
"days_other": "{{count}} Days",
|
||||
"allTime": "All Time"
|
||||
},
|
||||
"activities": {
|
||||
"title": "Activities"
|
||||
}
|
||||
}
|
||||
9
public/locales/es/labels.json
Normal file
9
public/locales/es/labels.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"shared": "Shared",
|
||||
"delete": {
|
||||
"title": "Delete Label",
|
||||
"message": "Are you sure you want to delete this label? This will remove the label from all tasks."
|
||||
},
|
||||
"loadError": "Failed to load labels. Please try again.",
|
||||
"blurb": "Manage your labels and organize your tasks effectively. Labels will be automatically shared with your circle if they are used on a shared task."
|
||||
}
|
||||
74
public/locales/es/points.json
Normal file
74
public/locales/es/points.json
Normal file
@@ -0,0 +1,74 @@
|
||||
{
|
||||
"redeem": "Redeem Points",
|
||||
"redeemModal": {
|
||||
"redeemButton": "Redeem",
|
||||
"pointsAvailable": "{{count}} points available",
|
||||
"pointsToRedeem": "Points to Redeem",
|
||||
"placeholder": "Enter points...",
|
||||
"cannotExceed": "Cannot exceed available points",
|
||||
"quickAdd": "Quick Add:",
|
||||
"aboutToRedeem": "You are about to redeem",
|
||||
"amount": "{{count}} points",
|
||||
"remaining": "Remaining: {{count}} points"
|
||||
},
|
||||
"leaderboard": {
|
||||
"titlePoints": "Points Leaderboard",
|
||||
"titleTasks": "Tasks Leaderboard",
|
||||
"subtitlePoints": "Rankings based on points earned during the selected time period",
|
||||
"subtitleTasks": "Rankings based on tasks completed during the selected time period",
|
||||
"modePoints": "Points",
|
||||
"modeTasks": "Tasks",
|
||||
"you": "You",
|
||||
"tasksAndAvg": "{{tasks}} tasks • {{avg}} avg per task",
|
||||
"available": "{{count}} available",
|
||||
"points_one": "{{count}} point",
|
||||
"points_other": "{{count}} points"
|
||||
},
|
||||
"tabs": {
|
||||
"short7d": "7D",
|
||||
"short6m": "6M",
|
||||
"shortAll": "All",
|
||||
"days7": "7 Days",
|
||||
"months6": "6 Months",
|
||||
"allTime": "All Time"
|
||||
},
|
||||
"filter": {
|
||||
"analysisTitle": "Filter & Analysis",
|
||||
"title": "Filter Points",
|
||||
"showFor": "Show points for:",
|
||||
"timePeriod": "Time period:"
|
||||
},
|
||||
"cards": {
|
||||
"available": {
|
||||
"title": "Available",
|
||||
"subtext": "Ready to redeem"
|
||||
},
|
||||
"redeemed": {
|
||||
"title": "Redeemed",
|
||||
"subtext": "Previously used"
|
||||
},
|
||||
"total": {
|
||||
"title": "Total",
|
||||
"subtext": "All time earned"
|
||||
},
|
||||
"period": {
|
||||
"title": "Period Points",
|
||||
"allTime": "All time",
|
||||
"last6Months": "Last 6 months",
|
||||
"lastDays_one": "Last {{count}} day",
|
||||
"lastDays_other": "Last {{count}} days"
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"showingFor": "Showing points for",
|
||||
"unknownUser": "Unknown User",
|
||||
"overThe": "over the",
|
||||
"allTime": "All Time",
|
||||
"last6Months": "Last 6 Months",
|
||||
"lastDays_one": "Last {{count}} Day",
|
||||
"lastDays_other": "Last {{count}} Days"
|
||||
},
|
||||
"trend": {
|
||||
"title": "Points Trend"
|
||||
}
|
||||
}
|
||||
24
public/locales/es/projects.json
Normal file
24
public/locales/es/projects.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"iconPicker": {
|
||||
"chooseIcon": "Choose Project Icon",
|
||||
"availableIcons": "Available Icons"
|
||||
},
|
||||
"defaultChip": "Default",
|
||||
"tasks_one": "{{count}} task",
|
||||
"tasks_other": "{{count}} tasks",
|
||||
"shared": "Shared",
|
||||
"delete": {
|
||||
"title": "Delete Project",
|
||||
"message": "Are you sure you want to delete \"{{name}}\"? This will remove the project but keep all tasks (they'll move to the Default Project)."
|
||||
},
|
||||
"loadError": "Failed to load projects. Please try again.",
|
||||
"blurb": "Organize your tasks into projects. Create custom workspaces to keep your tasks organized and easily accessible.",
|
||||
"defaultDescription": "All tasks without a specific project",
|
||||
"selector": {
|
||||
"title": "Projects",
|
||||
"createNew": "Create New Project",
|
||||
"createNewDescription": "Add a custom project workspace",
|
||||
"manage": "Manage Projects",
|
||||
"manageDescription": "View, edit, and organize all projects"
|
||||
}
|
||||
}
|
||||
@@ -1,174 +1,567 @@
|
||||
{
|
||||
"title": "Configuración",
|
||||
"circleSettings": {
|
||||
"title": "Configuración del círculo",
|
||||
"description": "Tu cuenta se conecta automáticamente a un Círculo cuando creas o te unes a uno. Invita fácilmente a amigos compartiendo el código único del Círculo o el enlace a continuación.",
|
||||
"circleCode": "Código del Círculo",
|
||||
"copyCode": "Copiar Código",
|
||||
"copyLink": "Copiar Enlace",
|
||||
"codeCopied": "¡Código del círculo copiado!",
|
||||
"linkCopied": "¡Enlace copiado!",
|
||||
"joinCircle": "Unirse a un Círculo",
|
||||
"joinCirclePlaceholder": "Ingresa el Código del Círculo",
|
||||
"join": "Unirse",
|
||||
"leave": "Salir del Círculo",
|
||||
"leaveConfirmTitle": "Salir del Círculo",
|
||||
"leaveConfirmMessage": "¿Estás seguro de que quieres salir de este círculo?",
|
||||
"circleMembers": "Miembros del Círculo",
|
||||
"circleMemberRequests": "Solicitudes de Miembros del Círculo",
|
||||
"admin": "Administrador",
|
||||
"member": "Miembro",
|
||||
"pending": "Pendiente",
|
||||
"accept": "Aceptar",
|
||||
"reject": "Rechazar",
|
||||
"makeAdmin": "Hacer Administrador",
|
||||
"makeMember": "Hacer Miembro",
|
||||
"remove": "Eliminar",
|
||||
"webhookURL": "URL del Webhook",
|
||||
"webhookDescription": "Ingresa una URL de webhook para recibir notificaciones de eventos del círculo",
|
||||
"webhookPlaceholder": "https://tu-url-webhook.com"
|
||||
},
|
||||
"accountSettings": {
|
||||
"title": "Configuración de la Cuenta",
|
||||
"subscription": "Suscripción",
|
||||
"subscriptionStatus": "Plan Actual",
|
||||
"free": "Gratis",
|
||||
"plus": "Plus",
|
||||
"upgrade": "Actualizar",
|
||||
"cancel": "Cancelar",
|
||||
"changePassword": "Cambiar Contraseña",
|
||||
"password": "Contraseña",
|
||||
"dangerZone": "Zona de Peligro",
|
||||
"dangerZoneDescription": "Una vez que elimines tu cuenta, no hay vuelta atrás. Por favor, está seguro.",
|
||||
"deleteAccount": "Eliminar Cuenta"
|
||||
},
|
||||
"localization": {
|
||||
"title": "Localización",
|
||||
"description": "Personaliza el idioma, formato de fecha y preferencias regionales para tu cuenta.",
|
||||
"language": "Idioma",
|
||||
"languageDescription": "Selecciona tu idioma preferido",
|
||||
"dateFormat": "Formato de Fecha",
|
||||
"dateFormatDescription": "Elige cómo se deben mostrar las fechas en toda la aplicación",
|
||||
"timeFormat": "Formato de Hora",
|
||||
"timeFormatDescription": "Selecciona formato de 12 o 24 horas",
|
||||
"12hour": "12 horas (AM/PM)",
|
||||
"24hour": "24 horas",
|
||||
"firstDayOfWeek": "Primer Día de la Semana",
|
||||
"firstDayOfWeekDescription": "Selecciona qué día comienza tu semana",
|
||||
"sunday": "Domingo",
|
||||
"monday": "Lunes",
|
||||
"saturday": "Sábado",
|
||||
"formats": {
|
||||
"mdy": "MM/DD/AAAA (EE.UU.)",
|
||||
"dmy": "DD/MM/AAAA (Europa)",
|
||||
"ymd": "AAAA-MM-DD (ISO)",
|
||||
"long": "Formato largo (ej., 1 de enero de 2024)",
|
||||
"short": "Formato corto (ej., 1 ene 2024)"
|
||||
}
|
||||
},
|
||||
"sidepanel": {
|
||||
"title": "Personalización del Panel Lateral",
|
||||
"description": "Personaliza el diseño y la visibilidad de las tarjetas en el panel lateral. Esta sección solo está disponible en dispositivos de pantalla grande como tabletas y computadoras de escritorio."
|
||||
},
|
||||
"theme": {
|
||||
"title": "Preferencias de tema",
|
||||
"description": "Elige cómo se ve el sitio para ti. Selecciona un solo tema o sincronízalo con tu sistema y cambia automáticamente entre temas de día y noche.",
|
||||
"themeMode": "Modo de tema",
|
||||
"light": "Claro",
|
||||
"dark": "Oscuro",
|
||||
"system": "Sistema"
|
||||
},
|
||||
"notifications": {
|
||||
"settingsSaved": "Configuración guardada con éxito",
|
||||
"settingsSaveFailed": "Error al guardar la configuración",
|
||||
"invalidWebhook": "URL de webhook no válida"
|
||||
},
|
||||
"profile": {
|
||||
"title": "Configuración del Perfil",
|
||||
"description": "Actualiza tu nombre para mostrar y foto de perfil.",
|
||||
"photoUpdated": "Foto Actualizada",
|
||||
"photoUpdatedMessage": "¡Tu foto de perfil ha sido actualizada con éxito!",
|
||||
"uploadFailed": "Error al Subir",
|
||||
"uploadFailedMessage": "Error al subir tu foto. Por favor, inténtalo de nuevo.",
|
||||
"profileUpdated": "Perfil Actualizado",
|
||||
"profileUpdatedMessage": "¡Tu información de perfil ha sido guardada con éxito!",
|
||||
"updateFailed": "Error al Actualizar",
|
||||
"updateFailedMessage": "No se pudo actualizar tu perfil. Por favor, verifica tu conexión e inténtalo de nuevo.",
|
||||
"changePhoto": "Cambiar Foto",
|
||||
"displayName": "Nombre para Mostrar",
|
||||
"displayNamePlaceholder": "Ingresa tu nombre para mostrar",
|
||||
"timezone": "Zona Horaria",
|
||||
"timezonePlaceholder": "Selecciona tu zona horaria",
|
||||
"title": "Ajustes",
|
||||
"common": {
|
||||
"save": "Guardar",
|
||||
"cancel": "Cancelar"
|
||||
"cancel": "Cancelar",
|
||||
"confirm": "Confirmar",
|
||||
"remove": "Eliminar",
|
||||
"delete": "Borrar",
|
||||
"refresh": "Actualizar",
|
||||
"loading": "Cargando…",
|
||||
"on": "Sí",
|
||||
"off": "No",
|
||||
"error": "Error",
|
||||
"success": "Listo",
|
||||
"plusFeature": "Función Plus",
|
||||
"earlyAccess": "Acceso anticipado"
|
||||
},
|
||||
"overview": {
|
||||
"title": "Configuración",
|
||||
"subtitle": "Personaliza tu experiencia y administra las preferencias de tu cuenta",
|
||||
"title": "Ajustes",
|
||||
"subtitle": "Personaliza tu experiencia y gestiona las preferencias de tu cuenta",
|
||||
"upgrade": {
|
||||
"title": "Actualizar a Plus",
|
||||
"description": "Desbloquea funciones potentes para mejorar tu productividad",
|
||||
"button": "Actualizar Ahora",
|
||||
"title": "Mejora a Plus",
|
||||
"description": "Desbloquea funciones potentes para aumentar tu productividad",
|
||||
"button": "Mejorar ahora",
|
||||
"features": {
|
||||
"richText": "Descripciones en texto enriquecido",
|
||||
"richText": "Descripciones con texto enriquecido",
|
||||
"notifications": "Notificaciones de tareas",
|
||||
"apiIntegrations": "Integraciones API",
|
||||
"apiIntegrations": "Integraciones con API",
|
||||
"advancedAutomation": "Automatización avanzada"
|
||||
}
|
||||
},
|
||||
"sections": {
|
||||
"profile": {
|
||||
"title": "Configuración del Perfil",
|
||||
"description": "Actualiza tu información de perfil, foto, nombre para mostrar y preferencias de zona horaria."
|
||||
"title": "Ajustes de perfil",
|
||||
"description": "Actualiza tu información de perfil, foto, nombre visible y zona horaria."
|
||||
},
|
||||
"circle": {
|
||||
"title": "Configuración del Círculo",
|
||||
"description": "Administra tu círculo, invita miembros y gestiona solicitudes de unión."
|
||||
"title": "Ajustes del círculo",
|
||||
"description": "Gestiona tu círculo, invita miembros y atiende las solicitudes de acceso."
|
||||
},
|
||||
"account": {
|
||||
"title": "Configuración de la Cuenta",
|
||||
"description": "Administra tu suscripción, cambia la contraseña y opciones de eliminación de cuenta."
|
||||
"title": "Ajustes de cuenta",
|
||||
"description": "Gestiona tu suscripción, cambia la contraseña y elimina tu cuenta."
|
||||
},
|
||||
"subaccounts": {
|
||||
"title": "Cuentas Administradas",
|
||||
"description": "Crea y administra subcuentas para iniciar sesión y completar tareas asignadas."
|
||||
"title": "Cuentas gestionadas",
|
||||
"description": "Crea y gestiona subcuentas para que puedan iniciar sesión y completar las tareas asignadas."
|
||||
},
|
||||
"notifications": {
|
||||
"title": "Notificaciones",
|
||||
"description": "Configura notificaciones push, alertas por correo electrónico y destinos de notificación para tareas."
|
||||
"description": "Configura notificaciones push, avisos por correo y destinos de notificación para las tareas."
|
||||
},
|
||||
"mfa": {
|
||||
"title": "Autenticación Multifactor",
|
||||
"description": "Agrega una capa adicional de seguridad con MFA usando aplicaciones de autenticación."
|
||||
"title": "Autenticación multifactor",
|
||||
"description": "Añade una capa extra de seguridad con MFA usando apps de autenticación."
|
||||
},
|
||||
"apitokens": {
|
||||
"title": "Tokens API",
|
||||
"description": "Genera y administra tokens de acceso para integraciones de terceros y acceso a la API."
|
||||
"title": "Tokens de API",
|
||||
"description": "Genera y gestiona tokens de acceso para integraciones de terceros y acceso a la API."
|
||||
},
|
||||
"storage": {
|
||||
"title": "Configuración de Almacenamiento",
|
||||
"description": "Respalda y restaura tus datos, administra el almacenamiento local y las preferencias de sincronización."
|
||||
"title": "Ajustes de almacenamiento",
|
||||
"description": "Haz copias de seguridad y restaura tus datos, gestiona el almacenamiento local y la sincronización."
|
||||
},
|
||||
"sidepanel": {
|
||||
"title": "Personalización del Panel Lateral",
|
||||
"description": "Personaliza el diseño y la visibilidad de las tarjetas en la interfaz del panel lateral."
|
||||
"title": "Personalización del panel lateral",
|
||||
"description": "Personaliza la disposición y la visibilidad de las tarjetas del panel lateral."
|
||||
},
|
||||
"theme": {
|
||||
"title": "Preferencias de Tema",
|
||||
"description": "Elige tu tema preferido y configura los ajustes de modo oscuro/claro."
|
||||
"title": "Preferencias de tema",
|
||||
"description": "Elige tu tema preferido y configura el modo claro/oscuro."
|
||||
},
|
||||
"localization": {
|
||||
"title": "Localización",
|
||||
"description": "Personaliza el idioma, formato de fecha, formato de hora y preferencias regionales."
|
||||
"description": "Personaliza el idioma, el formato de fecha y hora y las preferencias regionales."
|
||||
},
|
||||
"advanced": {
|
||||
"title": "Configuración Avanzada",
|
||||
"description": "Configura webhooks, actualizaciones en tiempo real y otras funciones avanzadas para mejorar la productividad."
|
||||
"title": "Ajustes avanzados",
|
||||
"description": "Configura webhooks, actualizaciones en tiempo real y otras funciones avanzadas."
|
||||
},
|
||||
"developer": {
|
||||
"title": "Configuración de Desarrollador",
|
||||
"description": "Ver información técnica sobre tokens de autenticación, conexiones SSE y datos de depuración."
|
||||
"title": "Ajustes de desarrollador",
|
||||
"description": "Consulta información técnica sobre tokens de autenticación, conexiones SSE y datos de depuración."
|
||||
},
|
||||
"feedback": {
|
||||
"title": "Enviar comentarios",
|
||||
"description": "Cuéntanos qué tal te funciona Donetick o pide una función."
|
||||
},
|
||||
"bugReport": {
|
||||
"title": "Informar de un error",
|
||||
"description": "¿Algo no funciona bien? Envíanos los detalles junto con una instantánea técnica."
|
||||
}
|
||||
}
|
||||
},
|
||||
"profile": {
|
||||
"title": "Ajustes de perfil",
|
||||
"description": "Actualiza tu nombre visible y tu foto de perfil.",
|
||||
"photoUpdated": "Foto actualizada",
|
||||
"photoUpdatedMessage": "¡Tu foto de perfil se ha actualizado correctamente!",
|
||||
"uploadFailed": "Error al subir",
|
||||
"uploadFailedMessage": "No se pudo subir tu foto. Inténtalo de nuevo.",
|
||||
"profileUpdated": "Perfil actualizado",
|
||||
"profileUpdatedMessage": "¡La información de tu perfil se ha guardado correctamente!",
|
||||
"updateFailed": "Error al actualizar",
|
||||
"updateFailedMessage": "No se pudo actualizar tu perfil. Comprueba tu conexión e inténtalo de nuevo.",
|
||||
"changePhoto": "Cambiar foto",
|
||||
"editPhoto": "Editar foto de perfil",
|
||||
"displayName": "Nombre visible",
|
||||
"displayNamePlaceholder": "Escribe tu nombre visible",
|
||||
"timezone": "Zona horaria",
|
||||
"timezonePlaceholder": "Selecciona tu zona horaria",
|
||||
"save": "Guardar",
|
||||
"cancel": "Cancelar"
|
||||
},
|
||||
"circleSettings": {
|
||||
"title": "Ajustes del círculo",
|
||||
"description": "Tu cuenta se conecta automáticamente a un círculo cuando creas uno o te unes. Invita a tus amigos compartiendo el código o el enlace del círculo que aparece abajo. Recibirás un aviso aquí cuando alguien pida unirse a tu círculo.",
|
||||
"memberOf": "Formas parte de {{name}}",
|
||||
"yourCircleCode": "Tu código de círculo es:",
|
||||
"copyCode": "Copiar código",
|
||||
"shareInvite": "Compartir invitación",
|
||||
"codeCopied": "Código copiado al portapapeles",
|
||||
"linkCopied": "Enlace de invitación copiado al portapapeles",
|
||||
"myCircle": "mi círculo",
|
||||
"shareTitle": "Únete a {{name}} en Donetick",
|
||||
"shareText": "Me gustaría invitarte a unirte a {{name}} en Donetick.",
|
||||
"shareDialogTitle": "Compartir invitación al círculo",
|
||||
"leave": "Salir del círculo",
|
||||
"leaveConfirmTitle": "Salir del círculo",
|
||||
"leaveConfirmMessage": "¿Seguro que quieres salir de tu círculo?",
|
||||
"leaveConfirmButton": "Salir",
|
||||
"leftCircle": "Has salido del círculo correctamente",
|
||||
"leaveFailed": "No se pudo salir del círculo",
|
||||
"circleMembers": "Miembros del círculo",
|
||||
"you": "(Tú)",
|
||||
"pendingApproval": "Pendiente de aprobación",
|
||||
"joinedOn": "Se unió el {{date}}",
|
||||
"requestedToJoin": "Solicitud de acceso {{date}}",
|
||||
"roles": {
|
||||
"member": "Miembro",
|
||||
"memberDescription": "Un miembro normal del círculo",
|
||||
"manager": "Gestor",
|
||||
"managerDescription": "Puede suplantar a otras personas y actuar en su nombre",
|
||||
"admin": "Administrador",
|
||||
"adminDescription": "Acceso total al círculo"
|
||||
},
|
||||
"roleUpdateFailed": "No se pudo actualizar el rol",
|
||||
"removeMemberTitle": "Eliminar miembro",
|
||||
"removeMemberMessage": "¿Seguro que quieres eliminar a {{name}} de tu círculo?",
|
||||
"memberRemoved": "Miembro eliminado correctamente",
|
||||
"circleMemberRequests": "Solicitudes de acceso al círculo",
|
||||
"lastUpdated": "Última actualización: {{time}}",
|
||||
"refreshing": "Actualizando…",
|
||||
"refreshFailed": "No se pudieron actualizar las solicitudes de acceso",
|
||||
"wantsToJoin": "{{name}} quiere unirse a tu círculo.",
|
||||
"accept": "Aceptar",
|
||||
"acceptRequestTitle": "Aceptar solicitud de acceso",
|
||||
"acceptRequestMessage": "¿Seguro que quieres aceptar a {{name}} (usuario: {{username}}) en tu círculo?",
|
||||
"requestAccepted": "Solicitud aceptada correctamente",
|
||||
"or": "o",
|
||||
"joinOtherDescription": "¿Quieres unirte al círculo de otra persona? Pídele su código de círculo o su enlace de invitación. Escribe el código abajo para unirte.",
|
||||
"enterCircleCode": "Introduce el código del círculo:",
|
||||
"enterCodePlaceholder": "Introduce el código",
|
||||
"joinCircle": "Unirse al círculo",
|
||||
"joinedPending": "Te has unido al círculo correctamente; espera a que la persona propietaria acepte tu solicitud.",
|
||||
"alreadyMember": "Ya eres miembro de este círculo",
|
||||
"joinFailed": "No se pudo unir al círculo"
|
||||
},
|
||||
"accountSettings": {
|
||||
"title": "Ajustes de cuenta",
|
||||
"description": "Cambia los ajustes de tu cuenta, el tipo de plan o tu contraseña",
|
||||
"accountType": "Tipo de cuenta: {{type}}",
|
||||
"free": "Gratis",
|
||||
"plus": "Plus",
|
||||
"plusUntil": "Plus (hasta el {{date}})",
|
||||
"activeDescription": "Actualmente tienes el plan Plus. Tu suscripción se renovará el {{date}}.",
|
||||
"cancelledDescription": "Has cancelado tu suscripción. Tu cuenta pasará al plan Gratis el {{date}}.",
|
||||
"freeDescription": "Actualmente tienes el plan Gratis. Mejora a Plus para desbloquear más funciones.",
|
||||
"upgrade": "Mejorar",
|
||||
"cancel": "Cancelar",
|
||||
"password": "Contraseña:",
|
||||
"changePassword": "Cambiar contraseña",
|
||||
"passwordChanged": "Contraseña cambiada correctamente",
|
||||
"passwordChangeFailed": "No se pudo cambiar la contraseña",
|
||||
"dangerZone": "Zona de peligro",
|
||||
"dangerZoneDescription": "Una vez que elimines tu cuenta, no hay vuelta atrás. Asegúrate antes de continuar.",
|
||||
"deleteAccount": "Eliminar cuenta",
|
||||
"accountDeleted": "Cuenta eliminada correctamente",
|
||||
"subscriptionCancelled": "Suscripción cancelada",
|
||||
"subscriptionCancelFailed": "No se pudo cancelar la suscripción",
|
||||
"purchase": {
|
||||
"success": "¡Compra realizada! Reinicia la app para acceder a las funciones Plus.",
|
||||
"storeConnection": "Problema de conexión con la tienda. Comprueba tu red e inténtalo de nuevo.",
|
||||
"notAllowed": "Las compras no están permitidas en este dispositivo. Revisa las restricciones de tu dispositivo.",
|
||||
"unavailable": "Esta suscripción no está disponible. Inténtalo más tarde.",
|
||||
"alreadyProcessed": "Esta compra ya se ha procesado. Si crees que es un error, ponte en contacto con el soporte.",
|
||||
"receiptMissing": "Falta el recibo de compra. Intenta comprar de nuevo.",
|
||||
"networkError": "Error de red. Comprueba tu conexión e inténtalo de nuevo.",
|
||||
"invalidReceipt": "Recibo de compra no válido. Ponte en contacto con el soporte si el problema persiste.",
|
||||
"pending": "El pago está pendiente de aprobación. Tendrás acceso en cuanto se apruebe.",
|
||||
"failed": "La compra ha fallado: {{error}}. Inténtalo de nuevo o contacta con el soporte.",
|
||||
"unknownError": "Error desconocido"
|
||||
}
|
||||
},
|
||||
"subaccounts": {
|
||||
"title": "Cuentas gestionadas",
|
||||
"description": "Gestiona las subcuentas. Sus usuarios pueden iniciar sesión y completar las tareas asignadas.",
|
||||
"notParentTitle": "Gestión de subcuentas",
|
||||
"notParentMessage": "Solo las cuentas principales pueden gestionar subcuentas.",
|
||||
"freePlanNotice": "El plan Gratis permite 1 subcuenta. Mejora a Plus para tener hasta 5 subcuentas.",
|
||||
"count": "Subcuentas ({{count}})",
|
||||
"add": "Añadir subcuenta",
|
||||
"loading": "Cargando subcuentas…",
|
||||
"emptyTitle": "No hay subcuentas",
|
||||
"emptyDescription": "Crea subcuentas para que los miembros del equipo puedan iniciar sesión y completar sus tareas.",
|
||||
"addFirst": "Añade tu primera subcuenta",
|
||||
"username": "Usuario: {{username}}",
|
||||
"created": "Creada: {{date}}",
|
||||
"changePassword": "Cambiar contraseña",
|
||||
"deleteAccount": "Eliminar cuenta",
|
||||
"createdSuccess": "¡La subcuenta «{{name}}» se ha creado correctamente!",
|
||||
"createFailed": "No se pudo crear la subcuenta: {{error}}",
|
||||
"createFailedGeneric": "No se pudo crear la subcuenta",
|
||||
"passwordUpdated": "Contraseña de la subcuenta actualizada correctamente",
|
||||
"passwordUpdateFailed": "No se pudo actualizar la contraseña: {{error}}",
|
||||
"passwordUpdateFailedGeneric": "No se pudo actualizar la contraseña",
|
||||
"deleteConfirmTitle": "Eliminar subcuenta",
|
||||
"deleteConfirmMessage": "¿Seguro que quieres eliminar la subcuenta «{{name}}»? Esta acción no se puede deshacer.",
|
||||
"deleted": "Subcuenta «{{name}}» eliminada correctamente",
|
||||
"deleteFailed": "No se pudo eliminar la subcuenta: {{error}}",
|
||||
"deleteFailedGeneric": "No se pudo eliminar la subcuenta",
|
||||
"howItWorksTitle": "Cómo funcionan las cuentas gestionadas",
|
||||
"howItWorks1": "Las cuentas gestionadas las crea la cuenta principal; son para personas cuya cuenta quieres poder eliminar y cuya contraseña quieres poder restablecer.",
|
||||
"howItWorks2": "Las subcuentas pueden iniciar sesión con su propio usuario y contraseña.",
|
||||
"howItWorks3": "Las cuentas gestionadas pueden completar tareas, pero tienen permisos administrativos limitados",
|
||||
"howItWorks4": "Las cuentas gestionadas se añaden automáticamente a tu círculo"
|
||||
},
|
||||
"notifications": {
|
||||
"title": "Ajustes de notificaciones",
|
||||
"deviceSection": "Notificaciones del dispositivo",
|
||||
"deviceSectionDescription": "Gestiona las notificaciones de tu dispositivo",
|
||||
"deviceLabel": "Notificación del dispositivo",
|
||||
"deviceHelper": "Recibe una notificación en tu dispositivo cuando venza una tarea",
|
||||
"mobileOnly": "Esta función solo está disponible en dispositivos móviles",
|
||||
"testNotification": "Notificación de prueba",
|
||||
"testNotificationBody": "Tienes una tarea que vence pronto",
|
||||
"dueTitle": "Notificación de vencimiento",
|
||||
"dueLabel": "Notificación cuando la tarea vence",
|
||||
"preDueTitle": "Notificación previa al vencimiento",
|
||||
"preDueLabel": "Notificación unas horas antes de que venza la tarea",
|
||||
"overdueTitle": "Notificación de retraso",
|
||||
"overdueLabel": "Notificación cuando la tarea está vencida",
|
||||
"pushLabel": "Notificaciones push",
|
||||
"pushHelper": "Recibe recordatorios, anuncios y asignaciones de tareas por notificación push",
|
||||
"registeredDevices": "Dispositivos registrados ({{count}}/5)",
|
||||
"registeredDevicesDescription": "Dispositivos registrados para recibir notificaciones push de tu cuenta",
|
||||
"currentDevice": "Dispositivo actual: {{platform}} {{model}}",
|
||||
"currentDeviceNotRegistered": "Este dispositivo no está registrado para notificaciones push",
|
||||
"limitReached": "Límite alcanzado",
|
||||
"registerDevice": "Registrar dispositivo",
|
||||
"unknownDevice": "Dispositivo desconocido",
|
||||
"deviceCreatedAt": "Creado el: {{date}}",
|
||||
"noDevices": "No hay dispositivos registrados para notificaciones push",
|
||||
"customSection": "Notificación personalizada",
|
||||
"customSectionDescription": "Notificaciones a través de otras plataformas como Telegram o Pushover",
|
||||
"customLabel": "Notificación personalizada",
|
||||
"customHelper": "Recibe notificaciones en otra plataforma",
|
||||
"targetNone": "Ninguna",
|
||||
"targetTelegram": "Telegram",
|
||||
"targetPushover": "Pushover",
|
||||
"targetWebhooks": "Webhooks",
|
||||
"telegramBotHelpBefore": "Debes escribir primero al bot para que funcionen las notificaciones de Telegram",
|
||||
"telegramBotHelpAfter": "para iniciar un chat",
|
||||
"clickHere": "Haz clic aquí",
|
||||
"chatId": "ID de chat",
|
||||
"chatIdPlaceholder": "ID de usuario / ID de chat",
|
||||
"telegramChatIdHelpBefore": "Si no conoces tu ID de chat, inicia un chat con userinfobot y te lo enviará.",
|
||||
"telegramChatIdHelpAfter": "para iniciar un chat con userinfobot",
|
||||
"userKey": "Clave de usuario",
|
||||
"userKeyPlaceholder": "ID de usuario",
|
||||
"chatIdRequired": "El ID de chat es obligatorio",
|
||||
"chatIdInvalid": "ID de chat no válido",
|
||||
"userKeyRequired": "La clave de usuario es obligatoria",
|
||||
"targetUpdated": "Destino de notificación actualizado",
|
||||
"targetUpdateFailed": "Error al actualizar el destino de notificación: {{error}}",
|
||||
"deviceRegistered": "Dispositivo registrado correctamente para notificaciones push.",
|
||||
"deviceLimitTitle": "Límite de dispositivos alcanzado",
|
||||
"deviceLimitMessage": "Has alcanzado el máximo de 5 dispositivos registrados. Elimina uno antes de registrar este.",
|
||||
"registrationFailedTitle": "Error de registro",
|
||||
"registrationFailedMessage": "No se pudo registrar el dispositivo automáticamente. Inténtalo de nuevo.",
|
||||
"permissionRequiredTitle": "Permiso necesario",
|
||||
"permissionRequiredMessage": "Se necesita permiso de notificaciones push para registrar este dispositivo.",
|
||||
"registrationInitiatedTitle": "Registro iniciado",
|
||||
"registrationInitiatedMessage": "Se ha iniciado el registro de notificaciones push. El dispositivo se registrará automáticamente.",
|
||||
"registerDeviceFailed": "No se pudo registrar el dispositivo. Inténtalo de nuevo.",
|
||||
"permissionDeniedTitle": "Permiso de notificaciones denegado",
|
||||
"permissionDeniedMessage": "Has denegado los permisos de notificación. Puedes activarlos más tarde en los ajustes de tu dispositivo.",
|
||||
"pushPermissionDeniedTitle": "Permiso de notificaciones push denegado",
|
||||
"pushPermissionDeniedMessage": "Se han desactivado las notificaciones push. Puedes activarlas en los ajustes de tu dispositivo si lo necesitas.",
|
||||
"unregisterFailed": "No se pudo dar de baja el dispositivo"
|
||||
},
|
||||
"mfa": {
|
||||
"title": "Autenticación multifactor",
|
||||
"description": "Añade una capa extra de seguridad a tu cuenta con la autenticación multifactor (MFA). Cuando está activada, al iniciar sesión tendrás que introducir un código de verificación de tu app de autenticación además de tu contraseña.",
|
||||
"twoFactor": "Autenticación en dos pasos",
|
||||
"enabledSubtitle": "Tu cuenta está protegida con 2FA",
|
||||
"disabledSubtitle": "Protege tu cuenta con una app de autenticación",
|
||||
"enable": "Activar",
|
||||
"disable": "Desactivar",
|
||||
"enabledSuccess": "¡La MFA se ha activado correctamente!",
|
||||
"disabledSuccess": "¡La MFA se ha desactivado correctamente!",
|
||||
"errors": {
|
||||
"qrGenerationFailed": "No se pudo generar el código QR",
|
||||
"invalidResponse": "Respuesta del servidor no válida. Falta el código QR o la clave.",
|
||||
"notFound": "No se encontró el endpoint de configuración de MFA. Puede que esta función aún no esté disponible.",
|
||||
"unauthorized": "No autorizado. Inicia sesión de nuevo.",
|
||||
"serverError": "Error del servidor. Inténtalo más tarde.",
|
||||
"setupFailed": "No se pudo configurar la MFA ({{status}}). Inténtalo de nuevo.",
|
||||
"networkError": "Error de red. Comprueba tu conexión e inténtalo de nuevo.",
|
||||
"invalidCode": "Código de verificación no válido. Inténtalo de nuevo.",
|
||||
"confirmFailed": "No se pudo confirmar la MFA. Inténtalo de nuevo.",
|
||||
"disableFailed": "No se pudo desactivar la MFA. Inténtalo de nuevo."
|
||||
},
|
||||
"setup": {
|
||||
"title": "Configurar la autenticación multifactor",
|
||||
"addedAccount": "Ya he añadido la cuenta",
|
||||
"back": "Atrás",
|
||||
"verifyAndEnable": "Verificar y activar",
|
||||
"savedBackupCodes": "He guardado mis códigos de respaldo",
|
||||
"step1Label": "Paso 1:",
|
||||
"step1": "Escanea el código QR de abajo con tu app de autenticación (Google Authenticator, Authy, etc.)",
|
||||
"qrAlt": "Código QR de MFA",
|
||||
"qrFailed": "No se pudo generar el código QR. Inténtalo de nuevo o usa la clave manual de abajo.",
|
||||
"manualKey": "Clave de introducción manual:",
|
||||
"step2Label": "Paso 2:",
|
||||
"step2": "Introduce el código de verificación de 6 dígitos de tu app de autenticación",
|
||||
"codePlaceholder": "Introduce el código de 6 dígitos",
|
||||
"successTitle": "¡MFA activada correctamente!",
|
||||
"backupCodesTitle": "Guarda estos códigos de respaldo en un lugar seguro",
|
||||
"backupCodesDescription": "Puedes usar estos códigos para acceder a tu cuenta si pierdes tu dispositivo de autenticación. Cada código solo se puede usar una vez."
|
||||
},
|
||||
"disableModal": {
|
||||
"title": "Desactivar la autenticación multifactor",
|
||||
"warning": "Desactivar la MFA hará que tu cuenta sea menos segura. ¿Seguro que quieres continuar?",
|
||||
"prompt": "Introduce un código de verificación de tu app de autenticación para confirmar:",
|
||||
"confirm": "Desactivar MFA"
|
||||
},
|
||||
"backupCodesModal": {
|
||||
"title": "Nuevos códigos de respaldo",
|
||||
"warning": "Tus códigos de respaldo anteriores ya no son válidos. Guarda estos nuevos códigos en un lugar seguro. Cada código solo se puede usar una vez."
|
||||
}
|
||||
},
|
||||
"apiTokens": {
|
||||
"title": "Tokens de API",
|
||||
"accessToken": "Token de acceso",
|
||||
"description": "Crea un token para usar con la API y actualizar cosas que activan tareas",
|
||||
"plusNotice": "Los tokens de API no están disponibles en el plan Básico. Mejora a Plus para generar tokens de API e integrarte con sistemas externos y automatizar tus tareas.",
|
||||
"showToken": "Mostrar token",
|
||||
"hideToken": "Ocultar token",
|
||||
"removeTitle": "Eliminar token",
|
||||
"removeMessage": "¿Seguro que quieres eliminar {{name}}?",
|
||||
"removedTitle": "Eliminado",
|
||||
"removedMessage": "El token de API se ha eliminado",
|
||||
"tokenCopied": "Token copiado al portapapeles",
|
||||
"generateNew": "Generar nuevo token",
|
||||
"nameModalTitle": "Dale un nombre a tu nuevo token, algo con lo que lo reconozcas.",
|
||||
"generateToken": "Generar token"
|
||||
},
|
||||
"storage": {
|
||||
"title": "Ajustes de almacenamiento",
|
||||
"serverTitle": "Uso del almacenamiento en el servidor",
|
||||
"serverDescription": "Este es el almacenamiento que usa tu cuenta en nuestros servidores (por ejemplo, archivos, imágenes y datos que has subido).",
|
||||
"usagePlaceholder": "-- MB usados / -- MB en total (--)",
|
||||
"usage": "{{used}} MB usados / {{total}} MB en total ({{percent}} %)",
|
||||
"basicPlanNotice": "El almacenamiento en el servidor no está disponible en el plan Básico. Mejora a Plus para consultar tu uso.",
|
||||
"localTitleApp": "Almacenamiento local y caché de la app",
|
||||
"localTitleBrowser": "Almacenamiento local y caché del navegador",
|
||||
"localDescription": "Son datos guardados localmente en tu navegador para un acceso más rápido. Borrarlos no afectará a tus datos del servidor, pero puede cerrar tu sesión.",
|
||||
"clearLocal": "Borrar todo el almacenamiento local y la caché",
|
||||
"clearLocalTitle": "Borrar todo el almacenamiento local",
|
||||
"clearLocalMessage": "¿Seguro que quieres borrar tu almacenamiento local y la caché? Se eliminarán todos tus datos de este navegador y tendrás que iniciar sesión de nuevo.",
|
||||
"clearAll": "Borrar todo",
|
||||
"appPreferences": "Preferencias de la app",
|
||||
"deviceOnly": "Solo en el dispositivo",
|
||||
"appPreferencesDescription": "Son preferencias y ajustes que la app guarda localmente en tu dispositivo. Al borrarlos se restablecerán los ajustes de la app y puede que se cierre tu sesión, pero no afectará a tus datos del servidor.",
|
||||
"clearPreferences": "Borrar preferencias de la app",
|
||||
"clearPreferencesTitle": "Borrar preferencias de la app",
|
||||
"clearPreferencesMessage": "¿Seguro que quieres borrar todas las preferencias de la app? Se restablecerán tus ajustes y puede que tengas que iniciar sesión de nuevo."
|
||||
},
|
||||
"sidepanel": {
|
||||
"title": "Personalización del panel lateral",
|
||||
"heading": "Ajustes del panel lateral",
|
||||
"description": "Elige qué tarjetas aparecen en el panel lateral y en qué orden. Arrastra y suelta para reordenarlas o cambia su visibilidad.",
|
||||
"resetToDefaults": "Restablecer valores predeterminados",
|
||||
"resetHelper": "Se restablecerán la visibilidad y el orden predeterminados de todas las tarjetas.",
|
||||
"cards": {
|
||||
"welcome": {
|
||||
"name": "Cambio de usuario",
|
||||
"description": "Permite a administradores y gestores ver las tareas como otras personas"
|
||||
},
|
||||
"smartInsights": {
|
||||
"name": "Ideas inteligentes",
|
||||
"description": "Acciones rápidas basadas en tus tareas"
|
||||
},
|
||||
"assignees": {
|
||||
"name": "Tareas por responsable",
|
||||
"description": "Agrupa las tareas según a quién estén asignadas"
|
||||
},
|
||||
"calendar": {
|
||||
"name": "Vista de calendario",
|
||||
"description": "Muestra las tareas en formato de calendario"
|
||||
},
|
||||
"activities": {
|
||||
"name": "Actividad reciente",
|
||||
"description": "Muestra las tareas completadas y la actividad reciente"
|
||||
},
|
||||
"weeklyGoals": {
|
||||
"name": "Objetivos semanales",
|
||||
"description": "Muestra el progreso semanal y las estadísticas de la familia"
|
||||
}
|
||||
}
|
||||
},
|
||||
"theme": {
|
||||
"title": "Preferencias de tema",
|
||||
"description": "Elige cómo se ve la aplicación. Selecciona un tema fijo o sincronízalo con tu sistema para cambiar automáticamente entre el modo claro y oscuro.",
|
||||
"themeMode": "Modo de tema",
|
||||
"light": "Claro",
|
||||
"dark": "Oscuro",
|
||||
"system": "Sistema"
|
||||
},
|
||||
"localization": {
|
||||
"title": "Localización",
|
||||
"description": "Personaliza el idioma, el formato de fecha y las preferencias regionales de tu cuenta.",
|
||||
"language": "Idioma",
|
||||
"languageDescription": "Selecciona tu idioma preferido",
|
||||
"rtlNotice": "Este idioma se escribe de derecha a izquierda (RTL)",
|
||||
"dateFormat": "Formato de fecha",
|
||||
"dateFormatDescription": "Elige cómo se muestran las fechas en toda la aplicación",
|
||||
"timeFormat": "Formato de hora",
|
||||
"timeFormatDescription": "Selecciona el formato de 12 o 24 horas",
|
||||
"preview": "Vista previa: {{value}}",
|
||||
"12hour": "12 horas (a. m./p. m.)",
|
||||
"24hour": "24 horas",
|
||||
"firstDayOfWeek": "Primer día de la semana",
|
||||
"firstDayOfWeekDescription": "Elige con qué día empieza tu semana",
|
||||
"sunday": "Domingo",
|
||||
"monday": "Lunes",
|
||||
"saturday": "Sábado",
|
||||
"formats": {
|
||||
"mdy": "MM/DD/AAAA (EE. UU.)",
|
||||
"dmy": "DD/MM/AAAA (Europa)",
|
||||
"ymd": "AAAA-MM-DD (ISO)",
|
||||
"long": "Formato largo (p. ej., 1 de enero de 2024)",
|
||||
"short": "Formato corto (p. ej., 1 ene 2024)"
|
||||
}
|
||||
},
|
||||
"advanced": {
|
||||
"title": "Ajustes avanzados",
|
||||
"description": "Configura funciones avanzadas como webhooks y actualizaciones en tiempo real para mejorar tu productividad.",
|
||||
"offlineTitle": "Modo sin conexión",
|
||||
"offlineDescription": "Sigue usando Donetick sin conexión en este dispositivo o navegador. Tus cambios se guardan localmente y se sincronizan cuando vuelvas a estar en línea.",
|
||||
"offlineToggle": "Activar el modo sin conexión",
|
||||
"offlineHelper": "Al desactivarlo se eliminan los cambios sin conexión no sincronizados y los datos guardados en este dispositivo o navegador.",
|
||||
"offlineEnabled": "Modo sin conexión activado en este dispositivo o navegador",
|
||||
"offlineDisabled": "Modo sin conexión desactivado y datos locales borrados",
|
||||
"offlineDisabledPartial": "Se desactivó el modo sin conexión, pero puede que aún queden algunos datos locales guardados",
|
||||
"offlineDisableTitle": "Desactivar el modo sin conexión",
|
||||
"offlineDisableMessage": "Al desactivar el modo sin conexión se eliminarán los cambios sin sincronizar y los datos guardados en este dispositivo o navegador. ¿Quieres continuar?",
|
||||
"offlineDisableConfirm": "Desactivar y borrar datos",
|
||||
"webhookTitle": "Integración con webhooks",
|
||||
"webhookDescription": "Los webhooks te permiten enviar notificaciones en tiempo real a otros servicios cuando ocurre algo en tu círculo. Configura una URL de webhook para recibir actualizaciones en tiempo real.",
|
||||
"webhookPlusNotice": "Las notificaciones por webhook no están disponibles en el plan Básico. Mejora a Plus para recibir actualizaciones en tiempo real por webhook.",
|
||||
"webhookToggle": "Activar webhook",
|
||||
"webhookHelper": "Activa las notificaciones por webhook para las actualizaciones de tareas y cosas.",
|
||||
"webhookURL": "URL del webhook",
|
||||
"webhookUpdated": "URL del webhook actualizada correctamente",
|
||||
"webhookUpdateFailed": "No se pudo actualizar la URL del webhook",
|
||||
"realtimeTitle": "Actualizaciones en tiempo real",
|
||||
"realtimeDescription": "Configura cómo recibes actualizaciones en vivo cuando cambian las tareas y actividades de tu círculo.",
|
||||
"realtime": {
|
||||
"toggleLabel": "Activar actualizaciones en tiempo real",
|
||||
"title": "Actualizaciones en tiempo real",
|
||||
"subtitle": "Recibe notificaciones al instante cuando se actualicen las tareas",
|
||||
"statusLabel": "Estado:",
|
||||
"basicPlan": "Las actualizaciones en tiempo real no están disponibles en el plan Básico. Mejora a Plus para recibir notificaciones instantáneas cuando se actualicen las tareas.",
|
||||
"disabled": "Las actualizaciones en tiempo real están desactivadas. Actívalas para ver los cambios en vivo cuando tú u otros miembros del círculo completéis, omitáis o modifiquéis tareas.",
|
||||
"connected": "Las actualizaciones en tiempo real funcionan. Verás los cambios en vivo cuando tú u otros miembros del círculo completéis, omitáis o modifiquéis tareas.",
|
||||
"connecting": "Conectando a las actualizaciones en tiempo real…",
|
||||
"errored": "Las actualizaciones en tiempo real están activadas pero no funcionan: {{error}}",
|
||||
"notConnected": "Las actualizaciones en tiempo real están activadas pero ahora mismo no hay conexión.",
|
||||
"basicPlanNotice": "Las actualizaciones en tiempo real no están disponibles en el plan Básico. Mejora a Plus para recibir notificaciones instantáneas cuando tú u otros miembros del círculo completéis, omitáis o modifiquéis tareas."
|
||||
}
|
||||
},
|
||||
"subscription": {
|
||||
"sessionFailed": "Failed to create subscription session",
|
||||
"errorTitle": "Subscription Error",
|
||||
"errorMessage": "Failed to start subscription process. Please try again.",
|
||||
"subscribe": "Subscribe",
|
||||
"cancelAnytime": "Cancel anytime. No hidden fees. Secure payment powered by Stripe."
|
||||
},
|
||||
"childUsers": {
|
||||
"errNameRequired": "Sub account name is required",
|
||||
"errNameMin": "Sub account name must be at least 2 characters",
|
||||
"errNameMax": "Sub account name must be less than 20 characters",
|
||||
"errNameChars": "Sub account name can only contain lowercase letters, dot and dash",
|
||||
"errPasswordRequired": "Password is required",
|
||||
"errPasswordLength": "Password must be between 8 and 64 characters",
|
||||
"errPasswordMatch": "Passwords do not match",
|
||||
"errDisplayNameMax": "Display name must be less than 50 characters",
|
||||
"createTitle": "Create Sub Account",
|
||||
"createButton": "Create Account",
|
||||
"nameLabel": "Sub Account Name *",
|
||||
"namePlaceholder": "Enter sub account name (e.g., sarah)",
|
||||
"displayNameLabel": "Display Name",
|
||||
"displayNamePlaceholder": "Display name (optional, defaults to sub account name)",
|
||||
"passwordLabel": "Password *",
|
||||
"passwordPlaceholder": "Enter password (8-64 characters)",
|
||||
"confirmPasswordLabel": "Confirm Password *",
|
||||
"confirmPasswordPlaceholder": "Confirm password"
|
||||
},
|
||||
"passwordChange": {
|
||||
"minLength": "Password must be at least 8 characters",
|
||||
"maxLength": "Password must be less than 64 characters"
|
||||
},
|
||||
"payment": {
|
||||
"cancelledTitle": "Payment has been cancelled",
|
||||
"cancelledRedirect": "You will be redirected to the main page shortly.",
|
||||
"successTitle": "Payment Successful!",
|
||||
"successRedirect": "You will be redirected to the settings page shortly."
|
||||
},
|
||||
"developer": {
|
||||
"tokenRefreshed": "Token refreshed successfully",
|
||||
"endpointCalled": "Refresh token endpoint called successfully",
|
||||
"clearDbCleared": "Local offline database cleared. Starting full sync...",
|
||||
"clearDbDone": "Full sync completed from the beginning",
|
||||
"intro": "View technical information about your authentication tokens and session",
|
||||
"refreshCookieNote": "Refresh tokens are managed via HTTP-only cookies on web platform",
|
||||
"noReconnectInfo": "No reconnection information available",
|
||||
"noTimeoutInfo": "No timeout information available",
|
||||
"noDebugInfo": "No debug information available"
|
||||
},
|
||||
"backup": {
|
||||
"keyRequired": "Encryption key is required",
|
||||
"created": "Backup created and downloaded successfully",
|
||||
"createFailed": "Failed to create backup",
|
||||
"selectFile": "Please select a backup file",
|
||||
"restored": "Backup restored successfully. Please refresh the page.",
|
||||
"restoreFailed": "Failed to restore backup",
|
||||
"readFailed": "Failed to read backup file",
|
||||
"createIntro": "Create an encrypted backup of your data. This backup will include all your chores, history, settings, and optionally your uploaded files.",
|
||||
"keyPlaceholder": "Enter a strong encryption key",
|
||||
"includeAssets": "Include uploaded files and assets",
|
||||
"warningLabel": "Warning:",
|
||||
"restoreWarning": "Restoring a backup will replace all your current data. This action cannot be undone.",
|
||||
"restoreKeyPlaceholder": "Enter the encryption key used for this backup"
|
||||
},
|
||||
"deletion": {
|
||||
"passwordRequired": "Please enter your password to continue",
|
||||
"passwordAndDelete": "Please enter your password and type DELETE to confirm",
|
||||
"failed": "Failed to delete account",
|
||||
"passwordPlaceholder": "Enter your password",
|
||||
"transferIntro": "You own circles that require ownership transfer before deletion. Please select new owners:",
|
||||
"selectOwner": "Select new owner",
|
||||
"confirmPrompt": "Please enter your password and type DELETE to confirm",
|
||||
"typeDelete": "DELETE"
|
||||
}
|
||||
}
|
||||
|
||||
18
public/locales/es/things.json
Normal file
18
public/locales/es/things.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"errName": "Name is required",
|
||||
"errStateNumber": "State must be a number",
|
||||
"errStateBool": "State must be true or false",
|
||||
"errStateRequired": "State is required",
|
||||
"name": "Name",
|
||||
"namePlaceholder": "Thing name",
|
||||
"value": "Value",
|
||||
"valuePlaceholder": "Thing value",
|
||||
"updateState": "Update state",
|
||||
"update": "Update",
|
||||
"history": {
|
||||
"overview": "Things Overview",
|
||||
"visualization": "Data Visualization",
|
||||
"changeHistory": "Change History",
|
||||
"updated": "Updated"
|
||||
}
|
||||
}
|
||||
29
public/locales/es/timer.json
Normal file
29
public/locales/es/timer.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"toast": {
|
||||
"sessionUpdatedTitle": "Session updated",
|
||||
"sessionUpdatedMessage": "Timer session has been updated successfully.",
|
||||
"sessionUpdateFailTitle": "Failed to update session",
|
||||
"tryAgain": "Please try again.",
|
||||
"sessionUpdateErrorTitle": "Error updating session",
|
||||
"sessionDeletedTitle": "Session deleted",
|
||||
"sessionDeletedMessage": "Timer session has been deleted successfully.",
|
||||
"sessionDeleteErrorTitle": "Error deleting session",
|
||||
"deleteConfirmTitle": "Delete Timer Session",
|
||||
"deleteConfirmMessage": "Are you sure you want to delete this timer session?"
|
||||
},
|
||||
"loading": "Loading timer data...",
|
||||
"noData": "No timer data found for this chore.",
|
||||
"activeWork": "Active Work",
|
||||
"breakTime": "Break Time",
|
||||
"workSessions": "Work Sessions",
|
||||
"totalTime": "Total Time",
|
||||
"distribution": "Work vs Break Distribution",
|
||||
"noActiveTime": "No active time yet",
|
||||
"sessionBreakdown": "Session Breakdown",
|
||||
"sessions": "Sessions",
|
||||
"addSession": "Add Session",
|
||||
"startTime": "Start Time",
|
||||
"endTime": "End Time",
|
||||
"leaveEmpty": "Leave empty if session is ongoing",
|
||||
"noSessionForChore": "No timer session found for this chore."
|
||||
}
|
||||
@@ -20,6 +20,7 @@
|
||||
"logout": "Déconnexion",
|
||||
"version": "Version",
|
||||
"navigation": {
|
||||
"search": "Recherche",
|
||||
"allTasks": "Toutes les Tâches",
|
||||
"archived": "Archivées",
|
||||
"things": "Objets",
|
||||
@@ -29,5 +30,43 @@
|
||||
"activities": "Activités",
|
||||
"points": "Points",
|
||||
"settings": "Paramètres"
|
||||
},
|
||||
"search": {
|
||||
"title": "Recherche",
|
||||
"placeholder": "Rechercher dans Donetick",
|
||||
"inputAriaLabel": "Rechercher des tâches, l’historique, des projets, des étiquettes et des paramètres",
|
||||
"deviceNote": "Recherche dans le contenu disponible sur cet appareil",
|
||||
"escape": "Échap",
|
||||
"recent": "Récents",
|
||||
"empty": {
|
||||
"title": "Aucune correspondance directe",
|
||||
"subtitle": "Vous pouvez tout de même filtrer la liste des tâches avec cette recherche."
|
||||
},
|
||||
"groups": {
|
||||
"tasks": "Tâches",
|
||||
"history": "Notes",
|
||||
"projects": "Projets",
|
||||
"labels": "Étiquettes",
|
||||
"people": "Personnes",
|
||||
"settings": "Paramètres",
|
||||
"actions": "Actions rapides"
|
||||
},
|
||||
"actions": {
|
||||
"quickAction": "Action rapide",
|
||||
"navigation": "Navigation",
|
||||
"createTask": "Créer une tâche",
|
||||
"viewAllTasks": "Voir toutes les tâches",
|
||||
"viewArchivedTasks": "Voir les tâches archivées",
|
||||
"openSettings": "Ouvrir les paramètres",
|
||||
"filterTasks": "Afficher les tâches correspondant à « {{query}} »",
|
||||
"filterTasksSubtitle": "Filtrer la liste des tâches"
|
||||
},
|
||||
"footer": {
|
||||
"navigate": "Naviguer",
|
||||
"open": "Ouvrir",
|
||||
"results_one": "{{count}} résultat",
|
||||
"results_other": "{{count}} résultats",
|
||||
"typeToSearch": "Saisissez du texte pour rechercher"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,114 +1,27 @@
|
||||
{
|
||||
"title": "Paramètres",
|
||||
"circleSettings": {
|
||||
"title": "Paramètres du cercle",
|
||||
"description": "Votre compte est automatiquement connecté à un Cercle lorsque vous en créez un ou en rejoignez un. Invitez facilement des amis en partageant le code unique du Cercle ou le lien ci-dessous.",
|
||||
"circleCode": "Code du Cercle",
|
||||
"copyCode": "Copier le Code",
|
||||
"copyLink": "Copier le Lien",
|
||||
"codeCopied": "Code du cercle copié !",
|
||||
"linkCopied": "Lien copié !",
|
||||
"joinCircle": "Rejoindre un Cercle",
|
||||
"joinCirclePlaceholder": "Entrer le Code du Cercle",
|
||||
"join": "Rejoindre",
|
||||
"leave": "Quitter le Cercle",
|
||||
"leaveConfirmTitle": "Quitter le Cercle",
|
||||
"leaveConfirmMessage": "Êtes-vous sûr de vouloir quitter ce cercle ?",
|
||||
"circleMembers": "Membres du Cercle",
|
||||
"circleMemberRequests": "Demandes de Membres du Cercle",
|
||||
"admin": "Administrateur",
|
||||
"member": "Membre",
|
||||
"pending": "En attente",
|
||||
"accept": "Accepter",
|
||||
"reject": "Rejeter",
|
||||
"makeAdmin": "Nommer Administrateur",
|
||||
"makeMember": "Nommer Membre",
|
||||
"remove": "Supprimer",
|
||||
"webhookURL": "URL du Webhook",
|
||||
"webhookDescription": "Entrez une URL de webhook pour recevoir des notifications pour les événements du cercle",
|
||||
"webhookPlaceholder": "https://votre-url-webhook.com"
|
||||
},
|
||||
"accountSettings": {
|
||||
"title": "Paramètres du Compte",
|
||||
"subscription": "Abonnement",
|
||||
"subscriptionStatus": "Plan Actuel",
|
||||
"free": "Gratuit",
|
||||
"plus": "Plus",
|
||||
"upgrade": "Mettre à Niveau",
|
||||
"cancel": "Annuler",
|
||||
"changePassword": "Changer le Mot de Passe",
|
||||
"password": "Mot de passe",
|
||||
"dangerZone": "Zone Dangereuse",
|
||||
"dangerZoneDescription": "Une fois votre compte supprimé, il n'y a pas de retour en arrière. Veuillez être certain.",
|
||||
"deleteAccount": "Supprimer le Compte"
|
||||
},
|
||||
"localization": {
|
||||
"title": "Localisation",
|
||||
"description": "Personnalisez la langue, le format de date et les préférences régionales pour votre compte.",
|
||||
"language": "Langue",
|
||||
"languageDescription": "Sélectionnez votre langue préférée",
|
||||
"dateFormat": "Format de Date",
|
||||
"dateFormatDescription": "Choisissez comment les dates doivent être affichées dans l'application",
|
||||
"timeFormat": "Format de l'Heure",
|
||||
"timeFormatDescription": "Sélectionnez le format 12 heures ou 24 heures",
|
||||
"12hour": "12 heures (AM/PM)",
|
||||
"24hour": "24 heures",
|
||||
"firstDayOfWeek": "Premier Jour de la Semaine",
|
||||
"firstDayOfWeekDescription": "Sélectionnez quel jour commence votre semaine",
|
||||
"sunday": "Dimanche",
|
||||
"monday": "Lundi",
|
||||
"saturday": "Samedi",
|
||||
"formats": {
|
||||
"mdy": "MM/JJ/AAAA (États-Unis)",
|
||||
"dmy": "JJ/MM/AAAA (Europe)",
|
||||
"ymd": "AAAA-MM-JJ (ISO)",
|
||||
"long": "Format long (ex., 1 janvier 2024)",
|
||||
"short": "Format court (ex., 1 janv. 2024)"
|
||||
}
|
||||
},
|
||||
"sidepanel": {
|
||||
"title": "Personnalisation du Panneau Latéral",
|
||||
"description": "Personnalisez la disposition et la visibilité des cartes dans le panneau latéral. Cette section n'est disponible que sur les grands écrans comme les tablettes et les ordinateurs de bureau."
|
||||
},
|
||||
"theme": {
|
||||
"title": "Préférences de thème",
|
||||
"description": "Choisissez comment le site vous apparaît. Sélectionnez un thème unique ou synchronisez avec votre système pour basculer automatiquement entre les thèmes jour et nuit.",
|
||||
"themeMode": "Mode de thème",
|
||||
"light": "Clair",
|
||||
"dark": "Sombre",
|
||||
"system": "Système"
|
||||
},
|
||||
"notifications": {
|
||||
"settingsSaved": "Paramètres enregistrés avec succès",
|
||||
"settingsSaveFailed": "Échec de l'enregistrement des paramètres",
|
||||
"invalidWebhook": "URL de webhook invalide"
|
||||
},
|
||||
"profile": {
|
||||
"title": "Paramètres du Profil",
|
||||
"description": "Mettez à jour votre nom d'affichage et votre photo de profil.",
|
||||
"photoUpdated": "Photo Mise à Jour",
|
||||
"photoUpdatedMessage": "Votre photo de profil a été mise à jour avec succès !",
|
||||
"uploadFailed": "Échec du Téléchargement",
|
||||
"uploadFailedMessage": "Échec du téléchargement de votre photo. Veuillez réessayer.",
|
||||
"profileUpdated": "Profil Mis à Jour",
|
||||
"profileUpdatedMessage": "Vos informations de profil ont été enregistrées avec succès !",
|
||||
"updateFailed": "Échec de la Mise à Jour",
|
||||
"updateFailedMessage": "Impossible de mettre à jour votre profil. Veuillez vérifier votre connexion et réessayer.",
|
||||
"changePhoto": "Changer la Photo",
|
||||
"displayName": "Nom d'Affichage",
|
||||
"displayNamePlaceholder": "Entrez votre nom d'affichage",
|
||||
"timezone": "Fuseau Horaire",
|
||||
"timezonePlaceholder": "Sélectionnez votre fuseau horaire",
|
||||
"common": {
|
||||
"save": "Enregistrer",
|
||||
"cancel": "Annuler"
|
||||
"cancel": "Annuler",
|
||||
"confirm": "Confirmer",
|
||||
"remove": "Retirer",
|
||||
"delete": "Supprimer",
|
||||
"refresh": "Actualiser",
|
||||
"loading": "Chargement…",
|
||||
"on": "Activé",
|
||||
"off": "Désactivé",
|
||||
"error": "Erreur",
|
||||
"success": "Succès",
|
||||
"plusFeature": "Fonctionnalité Plus",
|
||||
"earlyAccess": "Accès anticipé"
|
||||
},
|
||||
"overview": {
|
||||
"title": "Paramètres",
|
||||
"subtitle": "Personnalisez votre expérience et gérez les préférences de votre compte",
|
||||
"upgrade": {
|
||||
"title": "Passer à Plus",
|
||||
"description": "Débloquez des fonctionnalités puissantes pour améliorer votre productivité",
|
||||
"button": "Mettre à Niveau Maintenant",
|
||||
"description": "Débloquez des fonctionnalités puissantes pour gagner en productivité",
|
||||
"button": "Passer à Plus",
|
||||
"features": {
|
||||
"richText": "Descriptions en texte enrichi",
|
||||
"notifications": "Notifications de tâches",
|
||||
@@ -118,57 +31,464 @@
|
||||
},
|
||||
"sections": {
|
||||
"profile": {
|
||||
"title": "Paramètres du Profil",
|
||||
"description": "Mettez à jour vos informations de profil, photo, nom d'affichage et préférences de fuseau horaire."
|
||||
"title": "Paramètres du profil",
|
||||
"description": "Mettez à jour vos informations de profil, votre photo, votre nom affiché et votre fuseau horaire."
|
||||
},
|
||||
"circle": {
|
||||
"title": "Paramètres du Cercle",
|
||||
"description": "Gérez votre cercle, invitez des membres et gérez les demandes d'adhésion."
|
||||
"title": "Paramètres du cercle",
|
||||
"description": "Gérez votre cercle, invitez des membres et traitez les demandes d'adhésion."
|
||||
},
|
||||
"account": {
|
||||
"title": "Paramètres du Compte",
|
||||
"description": "Gérez votre abonnement, changez le mot de passe et les options de suppression de compte."
|
||||
"title": "Paramètres du compte",
|
||||
"description": "Gérez votre abonnement, changez votre mot de passe et supprimez votre compte."
|
||||
},
|
||||
"subaccounts": {
|
||||
"title": "Comptes Gérés",
|
||||
"description": "Créez et gérez des sous-comptes pour vous connecter et accomplir les tâches assignées."
|
||||
"title": "Comptes gérés",
|
||||
"description": "Créez et gérez des sous-comptes pouvant se connecter et accomplir les tâches assignées."
|
||||
},
|
||||
"notifications": {
|
||||
"title": "Notifications",
|
||||
"description": "Configurez les notifications push, les alertes par e-mail et les cibles de notification pour les tâches."
|
||||
"description": "Configurez les notifications push, les alertes par e-mail et les destinations de notification des tâches."
|
||||
},
|
||||
"mfa": {
|
||||
"title": "Authentification Multi-Facteurs",
|
||||
"description": "Ajoutez une couche de sécurité supplémentaire avec MFA en utilisant des applications d'authentification."
|
||||
"title": "Authentification multifacteur",
|
||||
"description": "Ajoutez une couche de sécurité supplémentaire avec la MFA via une application d'authentification."
|
||||
},
|
||||
"apitokens": {
|
||||
"title": "Jetons API",
|
||||
"title": "Jetons d'API",
|
||||
"description": "Générez et gérez des jetons d'accès pour les intégrations tierces et l'accès à l'API."
|
||||
},
|
||||
"storage": {
|
||||
"title": "Paramètres de Stockage",
|
||||
"description": "Sauvegardez et restaurez vos données, gérez le stockage local et les préférences de synchronisation."
|
||||
"title": "Paramètres de stockage",
|
||||
"description": "Sauvegardez et restaurez vos données, gérez le stockage local et la synchronisation."
|
||||
},
|
||||
"sidepanel": {
|
||||
"title": "Personnalisation du Panneau Latéral",
|
||||
"description": "Personnalisez la disposition et la visibilité des cartes dans l'interface du panneau latéral."
|
||||
"title": "Personnalisation du panneau latéral",
|
||||
"description": "Personnalisez la disposition et la visibilité des cartes du panneau latéral."
|
||||
},
|
||||
"theme": {
|
||||
"title": "Préférences de Thème",
|
||||
"description": "Choisissez votre thème préféré et configurez les paramètres de mode sombre/clair."
|
||||
"title": "Préférences de thème",
|
||||
"description": "Choisissez votre thème préféré et configurez le mode clair/sombre."
|
||||
},
|
||||
"localization": {
|
||||
"title": "Localisation",
|
||||
"description": "Personnalisez la langue, le format de date, le format de l'heure et les préférences régionales."
|
||||
"description": "Personnalisez la langue, le format de date et d'heure et les préférences régionales."
|
||||
},
|
||||
"advanced": {
|
||||
"title": "Paramètres Avancés",
|
||||
"description": "Configurez les webhooks, les mises à jour en temps réel et d'autres fonctionnalités avancées pour améliorer la productivité."
|
||||
"title": "Paramètres avancés",
|
||||
"description": "Configurez les webhooks, les mises à jour en temps réel et d'autres fonctionnalités avancées."
|
||||
},
|
||||
"developer": {
|
||||
"title": "Paramètres Développeur",
|
||||
"title": "Paramètres développeur",
|
||||
"description": "Consultez les informations techniques sur les jetons d'authentification, les connexions SSE et les données de débogage."
|
||||
},
|
||||
"feedback": {
|
||||
"title": "Envoyer un retour",
|
||||
"description": "Dites-nous ce que vous pensez de Donetick ou demandez une fonctionnalité."
|
||||
},
|
||||
"bugReport": {
|
||||
"title": "Signaler un bug",
|
||||
"description": "Quelque chose ne fonctionne pas ? Envoyez-nous les détails avec un instantané technique."
|
||||
}
|
||||
}
|
||||
},
|
||||
"profile": {
|
||||
"title": "Paramètres du profil",
|
||||
"description": "Mettez à jour votre nom affiché et votre photo de profil.",
|
||||
"photoUpdated": "Photo mise à jour",
|
||||
"photoUpdatedMessage": "Votre photo de profil a été mise à jour avec succès !",
|
||||
"uploadFailed": "Échec de l'envoi",
|
||||
"uploadFailedMessage": "Impossible d'envoyer votre photo. Veuillez réessayer.",
|
||||
"profileUpdated": "Profil mis à jour",
|
||||
"profileUpdatedMessage": "Les informations de votre profil ont été enregistrées avec succès !",
|
||||
"updateFailed": "Échec de la mise à jour",
|
||||
"updateFailedMessage": "Impossible de mettre à jour votre profil. Vérifiez votre connexion et réessayez.",
|
||||
"changePhoto": "Changer de photo",
|
||||
"editPhoto": "Modifier la photo de profil",
|
||||
"displayName": "Nom affiché",
|
||||
"displayNamePlaceholder": "Saisissez votre nom affiché",
|
||||
"timezone": "Fuseau horaire",
|
||||
"timezonePlaceholder": "Sélectionnez votre fuseau horaire",
|
||||
"save": "Enregistrer",
|
||||
"cancel": "Annuler"
|
||||
},
|
||||
"circleSettings": {
|
||||
"title": "Paramètres du cercle",
|
||||
"description": "Votre compte est automatiquement rattaché à un cercle lorsque vous en créez un ou que vous en rejoignez un. Invitez facilement vos proches en partageant le code ou le lien du cercle ci-dessous. Vous recevrez une notification ici lorsque quelqu'un demandera à rejoindre votre cercle.",
|
||||
"memberOf": "Vous faites partie de {{name}}",
|
||||
"yourCircleCode": "Votre code de cercle est :",
|
||||
"copyCode": "Copier le code",
|
||||
"shareInvite": "Partager l'invitation",
|
||||
"codeCopied": "Code copié dans le presse-papiers",
|
||||
"linkCopied": "Lien d'invitation copié dans le presse-papiers",
|
||||
"myCircle": "mon cercle",
|
||||
"shareTitle": "Rejoignez {{name}} sur Donetick",
|
||||
"shareText": "J'aimerais vous inviter à rejoindre {{name}} sur Donetick.",
|
||||
"shareDialogTitle": "Partager l'invitation au cercle",
|
||||
"leave": "Quitter le cercle",
|
||||
"leaveConfirmTitle": "Quitter le cercle",
|
||||
"leaveConfirmMessage": "Voulez-vous vraiment quitter votre cercle ?",
|
||||
"leaveConfirmButton": "Quitter",
|
||||
"leftCircle": "Vous avez quitté le cercle",
|
||||
"leaveFailed": "Impossible de quitter le cercle",
|
||||
"circleMembers": "Membres du cercle",
|
||||
"you": "(Vous)",
|
||||
"pendingApproval": "En attente d'approbation",
|
||||
"joinedOn": "A rejoint le {{date}}",
|
||||
"requestedToJoin": "Demande d'adhésion {{date}}",
|
||||
"roles": {
|
||||
"member": "Membre",
|
||||
"memberDescription": "Un membre ordinaire du cercle",
|
||||
"manager": "Gestionnaire",
|
||||
"managerDescription": "Peut se faire passer pour d'autres personnes et agir en leur nom",
|
||||
"admin": "Administrateur",
|
||||
"adminDescription": "Accès complet au cercle"
|
||||
},
|
||||
"roleUpdateFailed": "Impossible de mettre à jour le rôle",
|
||||
"removeMemberTitle": "Retirer le membre",
|
||||
"removeMemberMessage": "Voulez-vous vraiment retirer {{name}} de votre cercle ?",
|
||||
"memberRemoved": "Membre retiré avec succès",
|
||||
"circleMemberRequests": "Demandes d'adhésion au cercle",
|
||||
"lastUpdated": "Dernière mise à jour : {{time}}",
|
||||
"refreshing": "Actualisation…",
|
||||
"refreshFailed": "Impossible d'actualiser les demandes d'adhésion",
|
||||
"wantsToJoin": "{{name}} souhaite rejoindre votre cercle.",
|
||||
"accept": "Accepter",
|
||||
"acceptRequestTitle": "Accepter la demande d'adhésion",
|
||||
"acceptRequestMessage": "Voulez-vous vraiment accepter {{name}} (identifiant : {{username}}) dans votre cercle ?",
|
||||
"requestAccepted": "Demande acceptée avec succès",
|
||||
"or": "ou",
|
||||
"joinOtherDescription": "Vous souhaitez rejoindre le cercle de quelqu'un d'autre ? Demandez-lui son code de cercle ou son lien d'invitation. Saisissez le code ci-dessous pour le rejoindre.",
|
||||
"enterCircleCode": "Saisissez le code du cercle :",
|
||||
"enterCodePlaceholder": "Saisir le code",
|
||||
"joinCircle": "Rejoindre le cercle",
|
||||
"joinedPending": "Cercle rejoint avec succès, attendez que la personne propriétaire accepte votre demande.",
|
||||
"alreadyMember": "Vous êtes déjà membre de ce cercle",
|
||||
"joinFailed": "Impossible de rejoindre le cercle"
|
||||
},
|
||||
"accountSettings": {
|
||||
"title": "Paramètres du compte",
|
||||
"description": "Modifiez les paramètres de votre compte, votre formule ou votre mot de passe",
|
||||
"accountType": "Type de compte : {{type}}",
|
||||
"free": "Gratuit",
|
||||
"plus": "Plus",
|
||||
"plusUntil": "Plus (jusqu'au {{date}})",
|
||||
"activeDescription": "Vous êtes actuellement abonné à la formule Plus. Votre abonnement sera renouvelé le {{date}}.",
|
||||
"cancelledDescription": "Vous avez résilié votre abonnement. Votre compte repassera à la formule Gratuite le {{date}}.",
|
||||
"freeDescription": "Vous utilisez actuellement la formule Gratuite. Passez à Plus pour débloquer plus de fonctionnalités.",
|
||||
"upgrade": "Passer à Plus",
|
||||
"cancel": "Résilier",
|
||||
"password": "Mot de passe :",
|
||||
"changePassword": "Changer le mot de passe",
|
||||
"passwordChanged": "Mot de passe modifié avec succès",
|
||||
"passwordChangeFailed": "Échec du changement de mot de passe",
|
||||
"dangerZone": "Zone sensible",
|
||||
"dangerZoneDescription": "Une fois votre compte supprimé, il n'y a pas de retour en arrière. Soyez-en bien sûr.",
|
||||
"deleteAccount": "Supprimer le compte",
|
||||
"accountDeleted": "Compte supprimé avec succès",
|
||||
"subscriptionCancelled": "Abonnement résilié",
|
||||
"subscriptionCancelFailed": "Impossible de résilier l'abonnement",
|
||||
"purchase": {
|
||||
"success": "Achat réussi ! Redémarrez l'application pour accéder aux fonctionnalités Plus.",
|
||||
"storeConnection": "Problème de connexion au store. Vérifiez votre réseau et réessayez.",
|
||||
"notAllowed": "Les achats ne sont pas autorisés sur cet appareil. Vérifiez les restrictions de votre appareil.",
|
||||
"unavailable": "Cet abonnement n'est pas disponible. Veuillez réessayer plus tard.",
|
||||
"alreadyProcessed": "Cet achat a déjà été traité. Si vous pensez qu'il s'agit d'une erreur, contactez le support.",
|
||||
"receiptMissing": "Reçu d'achat manquant. Veuillez réessayer l'achat.",
|
||||
"networkError": "Erreur réseau. Vérifiez votre connexion et réessayez.",
|
||||
"invalidReceipt": "Reçu d'achat invalide. Contactez le support si le problème persiste.",
|
||||
"pending": "Le paiement est en attente d'approbation. Vous aurez accès dès qu'il sera approuvé.",
|
||||
"failed": "Échec de l'achat : {{error}}. Réessayez ou contactez le support.",
|
||||
"unknownError": "Erreur inconnue"
|
||||
}
|
||||
},
|
||||
"subaccounts": {
|
||||
"title": "Comptes gérés",
|
||||
"description": "Gérez les sous-comptes. Leurs utilisateurs peuvent se connecter et accomplir les tâches qui leur sont assignées.",
|
||||
"notParentTitle": "Gestion des sous-comptes",
|
||||
"notParentMessage": "Seuls les comptes principaux peuvent gérer des sous-comptes.",
|
||||
"freePlanNotice": "La formule Gratuite permet 1 sous-compte. Passez à Plus pour en avoir jusqu'à 5.",
|
||||
"count": "Sous-comptes ({{count}})",
|
||||
"add": "Ajouter un sous-compte",
|
||||
"loading": "Chargement des sous-comptes…",
|
||||
"emptyTitle": "Aucun sous-compte",
|
||||
"emptyDescription": "Créez des sous-comptes pour que les membres de l'équipe puissent se connecter et accomplir leurs tâches.",
|
||||
"addFirst": "Ajouter votre premier sous-compte",
|
||||
"username": "Identifiant : {{username}}",
|
||||
"created": "Créé le : {{date}}",
|
||||
"changePassword": "Changer le mot de passe",
|
||||
"deleteAccount": "Supprimer le compte",
|
||||
"createdSuccess": "Le sous-compte « {{name}} » a été créé avec succès !",
|
||||
"createFailed": "Impossible de créer le sous-compte : {{error}}",
|
||||
"createFailedGeneric": "Impossible de créer le sous-compte",
|
||||
"passwordUpdated": "Mot de passe du sous-compte mis à jour avec succès",
|
||||
"passwordUpdateFailed": "Impossible de mettre à jour le mot de passe : {{error}}",
|
||||
"passwordUpdateFailedGeneric": "Impossible de mettre à jour le mot de passe",
|
||||
"deleteConfirmTitle": "Supprimer le sous-compte",
|
||||
"deleteConfirmMessage": "Voulez-vous vraiment supprimer le sous-compte « {{name}} » ? Cette action est irréversible.",
|
||||
"deleted": "Sous-compte « {{name}} » supprimé avec succès",
|
||||
"deleteFailed": "Impossible de supprimer le sous-compte : {{error}}",
|
||||
"deleteFailedGeneric": "Impossible de supprimer le sous-compte",
|
||||
"howItWorksTitle": "Comment fonctionnent les comptes gérés",
|
||||
"howItWorks1": "Les comptes gérés sont créés par le compte principal ; ils sont destinés aux personnes dont vous voulez pouvoir supprimer le compte et réinitialiser le mot de passe.",
|
||||
"howItWorks2": "Les sous-comptes peuvent se connecter avec leur propre identifiant et mot de passe.",
|
||||
"howItWorks3": "Les comptes gérés peuvent accomplir des tâches mais disposent de permissions administratives limitées",
|
||||
"howItWorks4": "Les comptes gérés sont automatiquement ajoutés à votre cercle"
|
||||
},
|
||||
"notifications": {
|
||||
"title": "Paramètres de notification",
|
||||
"deviceSection": "Notifications de l'appareil",
|
||||
"deviceSectionDescription": "Gérez les notifications de votre appareil",
|
||||
"deviceLabel": "Notification de l'appareil",
|
||||
"deviceHelper": "Recevez une notification sur votre appareil lorsqu'une tâche arrive à échéance",
|
||||
"mobileOnly": "Cette fonctionnalité n'est disponible que sur mobile",
|
||||
"testNotification": "Notification de test",
|
||||
"testNotificationBody": "Une tâche arrive bientôt à échéance",
|
||||
"dueTitle": "Notification d'échéance",
|
||||
"dueLabel": "Notification lorsque la tâche arrive à échéance",
|
||||
"preDueTitle": "Notification avant échéance",
|
||||
"preDueLabel": "Notification quelques heures avant l'échéance de la tâche",
|
||||
"overdueTitle": "Notification de retard",
|
||||
"overdueLabel": "Notification lorsque la tâche est en retard",
|
||||
"pushLabel": "Notifications push",
|
||||
"pushHelper": "Recevez les rappels, annonces et attributions de tâches par notification push",
|
||||
"registeredDevices": "Appareils enregistrés ({{count}}/5)",
|
||||
"registeredDevicesDescription": "Appareils enregistrés pour recevoir les notifications push de votre compte",
|
||||
"currentDevice": "Appareil actuel : {{platform}} {{model}}",
|
||||
"currentDeviceNotRegistered": "Cet appareil n'est pas enregistré pour les notifications push",
|
||||
"limitReached": "Limite atteinte",
|
||||
"registerDevice": "Enregistrer l'appareil",
|
||||
"unknownDevice": "Appareil inconnu",
|
||||
"deviceCreatedAt": "Créé le : {{date}}",
|
||||
"noDevices": "Aucun appareil enregistré pour les notifications push",
|
||||
"customSection": "Notification personnalisée",
|
||||
"customSectionDescription": "Notification via une autre plateforme comme Telegram ou Pushover",
|
||||
"customLabel": "Notification personnalisée",
|
||||
"customHelper": "Recevoir les notifications sur une autre plateforme",
|
||||
"targetNone": "Aucune",
|
||||
"targetTelegram": "Telegram",
|
||||
"targetPushover": "Pushover",
|
||||
"targetWebhooks": "Webhooks",
|
||||
"telegramBotHelpBefore": "Vous devez d'abord envoyer un message au bot pour que les notifications Telegram fonctionnent",
|
||||
"telegramBotHelpAfter": "pour démarrer une conversation",
|
||||
"clickHere": "Cliquez ici",
|
||||
"chatId": "ID de discussion",
|
||||
"chatIdPlaceholder": "ID utilisateur / ID de discussion",
|
||||
"telegramChatIdHelpBefore": "Si vous ne connaissez pas votre ID de discussion, démarrez une conversation avec userinfobot : il vous l'enverra.",
|
||||
"telegramChatIdHelpAfter": "pour démarrer une conversation avec userinfobot",
|
||||
"userKey": "Clé utilisateur",
|
||||
"userKeyPlaceholder": "ID utilisateur",
|
||||
"chatIdRequired": "L'ID de discussion est obligatoire",
|
||||
"chatIdInvalid": "ID de discussion invalide",
|
||||
"userKeyRequired": "La clé utilisateur est obligatoire",
|
||||
"targetUpdated": "Destination de notification mise à jour",
|
||||
"targetUpdateFailed": "Erreur lors de la mise à jour de la destination de notification : {{error}}",
|
||||
"deviceRegistered": "Appareil enregistré avec succès pour les notifications push.",
|
||||
"deviceLimitTitle": "Limite d'appareils atteinte",
|
||||
"deviceLimitMessage": "Vous avez atteint la limite de 5 appareils enregistrés. Retirez un appareil avant d'enregistrer celui-ci.",
|
||||
"registrationFailedTitle": "Échec de l'enregistrement",
|
||||
"registrationFailedMessage": "Impossible d'enregistrer l'appareil automatiquement. Veuillez réessayer.",
|
||||
"permissionRequiredTitle": "Autorisation requise",
|
||||
"permissionRequiredMessage": "L'autorisation de notifications push est nécessaire pour enregistrer cet appareil.",
|
||||
"registrationInitiatedTitle": "Enregistrement lancé",
|
||||
"registrationInitiatedMessage": "L'enregistrement des notifications push a été lancé. L'appareil sera enregistré automatiquement.",
|
||||
"registerDeviceFailed": "Impossible d'enregistrer l'appareil. Veuillez réessayer.",
|
||||
"permissionDeniedTitle": "Autorisation de notification refusée",
|
||||
"permissionDeniedMessage": "Vous avez refusé les autorisations de notification. Vous pourrez les activer plus tard dans les réglages de votre appareil.",
|
||||
"pushPermissionDeniedTitle": "Autorisation de notifications push refusée",
|
||||
"pushPermissionDeniedMessage": "Les notifications push ont été désactivées. Vous pouvez les activer dans les réglages de votre appareil si besoin.",
|
||||
"unregisterFailed": "Impossible de désenregistrer l'appareil"
|
||||
},
|
||||
"mfa": {
|
||||
"title": "Authentification multifacteur",
|
||||
"description": "Renforcez la sécurité de votre compte avec l'authentification multifacteur (MFA). Une fois activée, vous devrez saisir un code de vérification de votre application d'authentification en plus de votre mot de passe lors de la connexion.",
|
||||
"twoFactor": "Authentification à deux facteurs",
|
||||
"enabledSubtitle": "Votre compte est protégé par la 2FA",
|
||||
"disabledSubtitle": "Sécurisez votre compte avec une application d'authentification",
|
||||
"enable": "Activer",
|
||||
"disable": "Désactiver",
|
||||
"enabledSuccess": "La MFA a été activée avec succès !",
|
||||
"disabledSuccess": "La MFA a été désactivée avec succès !",
|
||||
"errors": {
|
||||
"qrGenerationFailed": "Impossible de générer le code QR",
|
||||
"invalidResponse": "Réponse invalide du serveur. Code QR ou clé secrète manquant.",
|
||||
"notFound": "Point de terminaison de configuration MFA introuvable. Cette fonctionnalité n'est peut-être pas encore disponible.",
|
||||
"unauthorized": "Non autorisé. Veuillez vous reconnecter.",
|
||||
"serverError": "Erreur serveur. Veuillez réessayer plus tard.",
|
||||
"setupFailed": "Échec de la configuration de la MFA ({{status}}). Veuillez réessayer.",
|
||||
"networkError": "Erreur réseau. Vérifiez votre connexion et réessayez.",
|
||||
"invalidCode": "Code de vérification invalide. Veuillez réessayer.",
|
||||
"confirmFailed": "Impossible de confirmer la MFA. Veuillez réessayer.",
|
||||
"disableFailed": "Impossible de désactiver la MFA. Veuillez réessayer."
|
||||
},
|
||||
"setup": {
|
||||
"title": "Configurer l'authentification multifacteur",
|
||||
"addedAccount": "J'ai ajouté le compte",
|
||||
"back": "Retour",
|
||||
"verifyAndEnable": "Vérifier et activer",
|
||||
"savedBackupCodes": "J'ai enregistré mes codes de secours",
|
||||
"step1Label": "Étape 1 :",
|
||||
"step1": "Scannez le code QR ci-dessous avec votre application d'authentification (Google Authenticator, Authy, etc.)",
|
||||
"qrAlt": "Code QR MFA",
|
||||
"qrFailed": "Le code QR n'a pas pu être généré. Réessayez ou utilisez la clé de saisie manuelle ci-dessous.",
|
||||
"manualKey": "Clé de saisie manuelle :",
|
||||
"step2Label": "Étape 2 :",
|
||||
"step2": "Saisissez le code de vérification à 6 chiffres de votre application d'authentification",
|
||||
"codePlaceholder": "Saisir le code à 6 chiffres",
|
||||
"successTitle": "MFA activée avec succès !",
|
||||
"backupCodesTitle": "Conservez ces codes de secours en lieu sûr",
|
||||
"backupCodesDescription": "Ces codes vous permettent d'accéder à votre compte si vous perdez votre appareil d'authentification. Chaque code ne peut être utilisé qu'une seule fois."
|
||||
},
|
||||
"disableModal": {
|
||||
"title": "Désactiver l'authentification multifacteur",
|
||||
"warning": "Désactiver la MFA rendra votre compte moins sûr. Voulez-vous vraiment continuer ?",
|
||||
"prompt": "Saisissez un code de vérification de votre application d'authentification pour confirmer :",
|
||||
"confirm": "Désactiver la MFA"
|
||||
},
|
||||
"backupCodesModal": {
|
||||
"title": "Nouveaux codes de secours",
|
||||
"warning": "Vos anciens codes de secours ne sont plus valides. Conservez ces nouveaux codes en lieu sûr. Chaque code ne peut être utilisé qu'une seule fois."
|
||||
}
|
||||
},
|
||||
"apiTokens": {
|
||||
"title": "Jetons d'API",
|
||||
"accessToken": "Jeton d'accès",
|
||||
"description": "Créez un jeton à utiliser avec l'API pour mettre à jour les éléments qui déclenchent des tâches",
|
||||
"plusNotice": "Les jetons d'API ne sont pas disponibles dans la formule de base. Passez à Plus pour générer des jetons d'API, vous intégrer à des systèmes externes et automatiser vos tâches.",
|
||||
"showToken": "Afficher le jeton",
|
||||
"hideToken": "Masquer le jeton",
|
||||
"removeTitle": "Retirer le jeton",
|
||||
"removeMessage": "Voulez-vous vraiment retirer {{name}} ?",
|
||||
"removedTitle": "Retiré",
|
||||
"removedMessage": "Le jeton d'API a été retiré",
|
||||
"tokenCopied": "Jeton copié dans le presse-papiers",
|
||||
"generateNew": "Générer un nouveau jeton",
|
||||
"nameModalTitle": "Donnez un nom à votre nouveau jeton, quelque chose qui vous permettra de le reconnaître.",
|
||||
"generateToken": "Générer le jeton"
|
||||
},
|
||||
"storage": {
|
||||
"title": "Paramètres de stockage",
|
||||
"serverTitle": "Utilisation du stockage serveur",
|
||||
"serverDescription": "Il s'agit de l'espace occupé par votre compte sur nos serveurs (fichiers, images et données que vous avez envoyés).",
|
||||
"usagePlaceholder": "-- Mo utilisés / -- Mo au total (--)",
|
||||
"usage": "{{used}} Mo utilisés / {{total}} Mo au total ({{percent}} %)",
|
||||
"basicPlanNotice": "Le stockage serveur n'est pas disponible dans la formule de base. Passez à Plus pour suivre votre utilisation.",
|
||||
"localTitleApp": "Stockage local et cache de l'application",
|
||||
"localTitleBrowser": "Stockage local et cache du navigateur",
|
||||
"localDescription": "Ce sont les données enregistrées localement dans votre navigateur pour un accès plus rapide. Les effacer n'affectera pas vos données serveur, mais pourra vous déconnecter.",
|
||||
"clearLocal": "Effacer tout le stockage local et le cache",
|
||||
"clearLocalTitle": "Effacer tout le stockage local",
|
||||
"clearLocalMessage": "Voulez-vous vraiment effacer votre stockage local et le cache ? Toutes vos données seront supprimées de ce navigateur et vous devrez vous reconnecter.",
|
||||
"clearAll": "Tout effacer",
|
||||
"appPreferences": "Préférences de l'application",
|
||||
"deviceOnly": "Appareil uniquement",
|
||||
"appPreferencesDescription": "Ce sont les préférences et réglages enregistrés localement sur votre appareil par l'application. Les effacer réinitialisera les réglages de l'application et pourra vous déconnecter, sans affecter vos données serveur.",
|
||||
"clearPreferences": "Effacer les préférences de l'application",
|
||||
"clearPreferencesTitle": "Effacer les préférences de l'application",
|
||||
"clearPreferencesMessage": "Voulez-vous vraiment effacer toutes les préférences de l'application ? Vos réglages seront réinitialisés et vous devrez peut-être vous reconnecter."
|
||||
},
|
||||
"sidepanel": {
|
||||
"title": "Personnalisation du panneau latéral",
|
||||
"heading": "Paramètres du panneau latéral",
|
||||
"description": "Choisissez les cartes qui apparaissent dans le panneau latéral et leur ordre. Faites-les glisser pour les réorganiser ou modifiez leur visibilité.",
|
||||
"resetToDefaults": "Réinitialiser par défaut",
|
||||
"resetHelper": "La visibilité et l'ordre par défaut de toutes les cartes seront rétablis.",
|
||||
"cards": {
|
||||
"welcome": {
|
||||
"name": "Changement d'utilisateur",
|
||||
"description": "Permet aux administrateurs et gestionnaires de voir les tâches d'autres personnes"
|
||||
},
|
||||
"smartInsights": {
|
||||
"name": "Aperçus intelligents",
|
||||
"description": "Actions rapides basées sur vos tâches"
|
||||
},
|
||||
"assignees": {
|
||||
"name": "Tâches par personne assignée",
|
||||
"description": "Regroupe les tâches selon la personne à qui elles sont assignées"
|
||||
},
|
||||
"calendar": {
|
||||
"name": "Vue calendrier",
|
||||
"description": "Affiche les tâches au format calendrier"
|
||||
},
|
||||
"activities": {
|
||||
"name": "Activités récentes",
|
||||
"description": "Affiche les tâches récemment terminées et les activités"
|
||||
},
|
||||
"weeklyGoals": {
|
||||
"name": "Objectifs hebdomadaires",
|
||||
"description": "Affiche la progression hebdomadaire et les statistiques de la famille"
|
||||
}
|
||||
}
|
||||
},
|
||||
"theme": {
|
||||
"title": "Préférences de thème",
|
||||
"description": "Choisissez l'apparence du site. Sélectionnez un thème fixe ou synchronisez-le avec votre système pour basculer automatiquement entre thème clair et sombre.",
|
||||
"themeMode": "Mode de thème",
|
||||
"light": "Clair",
|
||||
"dark": "Sombre",
|
||||
"system": "Système"
|
||||
},
|
||||
"localization": {
|
||||
"title": "Localisation",
|
||||
"description": "Personnalisez la langue, le format de date et les préférences régionales de votre compte.",
|
||||
"language": "Langue",
|
||||
"languageDescription": "Sélectionnez votre langue préférée",
|
||||
"rtlNotice": "Cette langue s'écrit de droite à gauche (RTL)",
|
||||
"dateFormat": "Format de date",
|
||||
"dateFormatDescription": "Choisissez comment les dates s'affichent dans toute l'application",
|
||||
"timeFormat": "Format d'heure",
|
||||
"timeFormatDescription": "Sélectionnez le format 12 ou 24 heures",
|
||||
"preview": "Aperçu : {{value}}",
|
||||
"12hour": "12 heures (AM/PM)",
|
||||
"24hour": "24 heures",
|
||||
"firstDayOfWeek": "Premier jour de la semaine",
|
||||
"firstDayOfWeekDescription": "Choisissez le jour qui commence votre semaine",
|
||||
"sunday": "Dimanche",
|
||||
"monday": "Lundi",
|
||||
"saturday": "Samedi",
|
||||
"formats": {
|
||||
"mdy": "MM/JJ/AAAA (États-Unis)",
|
||||
"dmy": "JJ/MM/AAAA (Europe)",
|
||||
"ymd": "AAAA-MM-JJ (ISO)",
|
||||
"long": "Format long (ex. : 1 janvier 2024)",
|
||||
"short": "Format court (ex. : 1 janv. 2024)"
|
||||
}
|
||||
},
|
||||
"advanced": {
|
||||
"title": "Paramètres avancés",
|
||||
"description": "Configurez des fonctionnalités avancées comme les webhooks et les mises à jour en temps réel pour gagner en productivité.",
|
||||
"offlineTitle": "Mode hors ligne",
|
||||
"offlineDescription": "Continuez à utiliser Donetick hors ligne sur cet appareil ou navigateur. Vos modifications sont enregistrées localement et synchronisées dès votre retour en ligne.",
|
||||
"offlineToggle": "Activer le mode hors ligne",
|
||||
"offlineHelper": "Le désactiver supprime les modifications hors ligne non synchronisées et les données enregistrées sur cet appareil ou navigateur.",
|
||||
"offlineEnabled": "Mode hors ligne activé pour cet appareil/navigateur",
|
||||
"offlineDisabled": "Mode hors ligne désactivé et données locales effacées",
|
||||
"offlineDisabledPartial": "Le mode hors ligne a été désactivé, mais certaines données locales peuvent subsister",
|
||||
"offlineDisableTitle": "Désactiver le mode hors ligne",
|
||||
"offlineDisableMessage": "Désactiver le mode hors ligne supprimera les modifications non synchronisées et les données hors ligne enregistrées sur cet appareil ou navigateur. Voulez-vous continuer ?",
|
||||
"offlineDisableConfirm": "Désactiver et effacer les données",
|
||||
"webhookTitle": "Intégration webhook",
|
||||
"webhookDescription": "Les webhooks vous permettent d'envoyer des notifications en temps réel à d'autres services lorsqu'un événement survient dans votre cercle. Configurez une URL de webhook pour recevoir des mises à jour en temps réel.",
|
||||
"webhookPlusNotice": "Les notifications par webhook ne sont pas disponibles dans la formule de base. Passez à Plus pour recevoir des mises à jour en temps réel via webhooks.",
|
||||
"webhookToggle": "Activer le webhook",
|
||||
"webhookHelper": "Activez les notifications webhook pour les mises à jour des tâches et des éléments.",
|
||||
"webhookURL": "URL du webhook",
|
||||
"webhookUpdated": "URL du webhook mise à jour avec succès",
|
||||
"webhookUpdateFailed": "Impossible de mettre à jour l'URL du webhook",
|
||||
"realtimeTitle": "Mises à jour en temps réel",
|
||||
"realtimeDescription": "Configurez la façon dont vous recevez les mises à jour en direct lorsque les tâches et activités changent dans votre cercle.",
|
||||
"realtime": {
|
||||
"toggleLabel": "Activer les mises à jour en temps réel",
|
||||
"title": "Mises à jour en temps réel",
|
||||
"subtitle": "Recevez des notifications instantanées lorsque les tâches sont mises à jour",
|
||||
"statusLabel": "Statut :",
|
||||
"basicPlan": "Les mises à jour en temps réel ne sont pas disponibles dans la formule de base. Passez à Plus pour recevoir des notifications instantanées lorsque les tâches sont mises à jour.",
|
||||
"disabled": "Les mises à jour en temps réel sont désactivées. Activez-les pour voir les changements en direct lorsque vous ou d'autres membres du cercle terminez, passez ou modifiez des tâches.",
|
||||
"connected": "Les mises à jour en temps réel fonctionnent. Vous verrez les changements en direct lorsque vous ou d'autres membres du cercle terminez, passez ou modifiez des tâches.",
|
||||
"connecting": "Connexion aux mises à jour en temps réel…",
|
||||
"errored": "Les mises à jour en temps réel sont activées mais ne fonctionnent pas : {{error}}",
|
||||
"notConnected": "Les mises à jour en temps réel sont activées mais non connectées actuellement.",
|
||||
"basicPlanNotice": "Les mises à jour en temps réel ne sont pas disponibles dans la formule de base. Passez à Plus pour recevoir des notifications instantanées lorsque vous ou d'autres membres du cercle terminez, passez ou modifiez des tâches."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
111
public/locales/fr/auth.json
Normal file
111
public/locales/fr/auth.json
Normal file
@@ -0,0 +1,111 @@
|
||||
{
|
||||
"validationError": "Validation Error",
|
||||
"primaryUsernameRequired": "Primary username is required for sub account login",
|
||||
"subNameRequired": "Sub account name is required for sub account login",
|
||||
"usernameRequired": "Username is required",
|
||||
"passwordRequired": "Password is required",
|
||||
"loginFailed": "Login Failed",
|
||||
"genericError": "An error occurred, please try again",
|
||||
"providerLoginFailed": "{{provider}} Login Failed",
|
||||
"providerLoginFailedMsg": "Couldn't log in with {{provider}}, please try again",
|
||||
"providerLoginError": "{{provider}} Login Error",
|
||||
"networkError": "Network error occurred, please try again",
|
||||
"mfaFailed": "Two-Factor Authentication Failed",
|
||||
"oauthError": "OAuth Error",
|
||||
"oauthBrowserFailed": "Failed to open authentication browser",
|
||||
"primaryAccount": "Primary Account",
|
||||
"subAccount": "Sub Account",
|
||||
"username": "Username",
|
||||
"primaryUsernamePlaceholder": "Enter primary account username",
|
||||
"subNamePlaceholder": "Enter sub account name",
|
||||
"forgotPassword": "Forgot password?",
|
||||
"or": "or",
|
||||
"email": "Email",
|
||||
"displayNamePlaceholder": "How others see your name",
|
||||
"signupFailed": "Signup Failed",
|
||||
"signupDisabled": "Signup disabled, please contact admin",
|
||||
"usernameMinLength": "Username must be at least 4 characters",
|
||||
"invalidEmail": "Invalid email address",
|
||||
"passwordLength": "Password must be between 8 and 64 characters",
|
||||
"displayNameRequired": "Display name is required",
|
||||
"displayNameChars": "Display name can only contain letters and numbers",
|
||||
"resetEmailSent": "Reset Email Sent",
|
||||
"resetEmailSentMsg": "Check your email for password reset instructions",
|
||||
"resetFailed": "Reset Failed",
|
||||
"resetFailedMsg": "Failed to send reset email, please try again later",
|
||||
"emailPlaceholder": "you@example.com",
|
||||
"passwordUpdated": "Password Updated",
|
||||
"passwordUpdatedMsg": "Your password has been updated successfully. Redirecting to login...",
|
||||
"passwordUpdateFailed": "Password Update Failed",
|
||||
"passwordUpdateFailedMsg": "Failed to update password, please try again later",
|
||||
"savePassword": "Save password",
|
||||
"server": {
|
||||
"url": "Server URL",
|
||||
"dnsFailed": "Hostname could not be resolved. Check the URL for typos or verify DNS.",
|
||||
"unreachable": "Unable to reach the server. Check the URL, port, and network connection.",
|
||||
"invalidUrl": "Invalid URL format. Include the protocol (http:// or https://) and port if needed."
|
||||
},
|
||||
"mfaModal": {
|
||||
"title": "Two-factor authentication",
|
||||
"codeRequired": "Please enter a verification code",
|
||||
"verifyFailed": "Failed to verify code. Please try again.",
|
||||
"backupHint": "Enter one of the backup codes you saved when setting up two-factor authentication.",
|
||||
"codeHint": "Enter the 6-digit code from your authenticator app.",
|
||||
"verify": "Verify & Sign In",
|
||||
"backupLabel": "Backup code",
|
||||
"codeLabel": "Verification code",
|
||||
"backupPlaceholder": "Enter backup code",
|
||||
"useAuthenticator": "Use authenticator app instead",
|
||||
"useBackup": "Use a backup code instead",
|
||||
"backupOnce": "Each backup code can only be used once.",
|
||||
"invalidCode": "Invalid verification code. Please try again."
|
||||
},
|
||||
"appleLoginFailed": "Apple Login Failed",
|
||||
"googleLoginFailed": "Google Login Failed",
|
||||
"createOne": "Create one",
|
||||
"primaryAccountUsernameLabel": "Primary account username",
|
||||
"subAccountNameLabel": "Sub account name",
|
||||
"serverSettings": "Server settings",
|
||||
"useDifferentAccount": "Use a different account",
|
||||
"yourUsername": "Your username",
|
||||
"backToSignIn": "Back to sign in",
|
||||
"confirmNewPassword": "Confirm new password",
|
||||
"newPassword": "New password",
|
||||
"reenterPassword": "Re-enter your password",
|
||||
"requestNewLink": "Request a new link",
|
||||
"setNewPassword": "Set a new password",
|
||||
"linkInvalid": "This link is not valid",
|
||||
"createAccountButton": "Create account",
|
||||
"createYourAccount": "Create your account",
|
||||
"displayNameLabel": "Display name",
|
||||
"usernameHint": "lowercase letters, numbers, dot and dash",
|
||||
"termsShort": "By creating an account you agree to our Terms of Service and Privacy",
|
||||
"checkYourEmail": "Check your email",
|
||||
"resetYourPassword": "Reset your password",
|
||||
"serverChangeWarning": "Changing the server clears locally cached data on this device.",
|
||||
"serverConnected": "Connected. Taking you to sign in...",
|
||||
"passwordLabel": "Password",
|
||||
"showPassword": "Show password",
|
||||
"hidePassword": "Hide password",
|
||||
"loginPasswordPlaceholder": "Enter your password",
|
||||
"signupPasswordPlaceholder": "At least 8 characters",
|
||||
"signupPasswordHelper": "Use 8 to 64 characters.",
|
||||
"orContinueWith": "or continue with",
|
||||
"signupSignInFailed": "Your account was created, but signing in failed. Please sign in.",
|
||||
"authenticating": {
|
||||
"signingIn": "Signing you in",
|
||||
"signingInSub": "This will only take a moment.",
|
||||
"unknownProvider": "Unknown sign-in provider",
|
||||
"contactSupport": "Please contact support.",
|
||||
"signInFailed": "Sign-in failed",
|
||||
"mfaCancelled": "Two-factor authentication was cancelled.",
|
||||
"requestNotVerified": "The sign-in request could not be verified.",
|
||||
"tryAgain": "Please try again.",
|
||||
"mfaSessionMissing": "The MFA session is missing. Please try again.",
|
||||
"twoFactor": "Two-factor authentication",
|
||||
"verifyToContinue": "Verify your login to continue.",
|
||||
"noToken": "No valid authentication token was returned.",
|
||||
"backToSignIn": "Back to sign in",
|
||||
"mfaFailed": "Two-factor authentication failed. Please try again."
|
||||
}
|
||||
}
|
||||
@@ -71,5 +71,11 @@
|
||||
"reset": "Réinitialiser le Minuteur",
|
||||
"delete": "Supprimer la Session"
|
||||
}
|
||||
},
|
||||
"toolbar": {
|
||||
"defaultProject": "Default Project"
|
||||
},
|
||||
"sort": {
|
||||
"assignedToMe": "Assigned to me"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
"logout": "Déconnexion",
|
||||
"version": "Version",
|
||||
"navigation": {
|
||||
"search": "Recherche",
|
||||
"allTasks": "Toutes les Tâches",
|
||||
"archived": "Archivées",
|
||||
"things": "Objets",
|
||||
@@ -28,6 +29,123 @@
|
||||
"filters": "Filtres",
|
||||
"activities": "Activités",
|
||||
"points": "Points",
|
||||
"settings": "Paramètres"
|
||||
"settings": "Paramètres",
|
||||
"reportBug": "Report a Bug"
|
||||
},
|
||||
"search": {
|
||||
"title": "Recherche",
|
||||
"placeholder": "Rechercher dans Donetick",
|
||||
"inputAriaLabel": "Rechercher des tâches, l’historique, des projets, des étiquettes et des paramètres",
|
||||
"deviceNote": "Recherche dans le contenu disponible sur cet appareil",
|
||||
"escape": "Échap",
|
||||
"recent": "Récents",
|
||||
"empty": {
|
||||
"title": "Aucune correspondance directe",
|
||||
"subtitle": "Vous pouvez tout de même filtrer la liste des tâches avec cette recherche."
|
||||
},
|
||||
"groups": {
|
||||
"tasks": "Tâches",
|
||||
"history": "Remarques",
|
||||
"projects": "Projets",
|
||||
"labels": "Étiquettes",
|
||||
"people": "Personnes",
|
||||
"settings": "Paramètres",
|
||||
"actions": "Actions rapides"
|
||||
},
|
||||
"actions": {
|
||||
"quickAction": "Action rapide",
|
||||
"navigation": "Navigation",
|
||||
"createTask": "Créer une tâche",
|
||||
"viewAllTasks": "Voir toutes les tâches",
|
||||
"viewArchivedTasks": "Voir les tâches archivées",
|
||||
"openSettings": "Ouvrir les paramètres",
|
||||
"filterTasks": "Afficher les tâches correspondant à « {{query}} »",
|
||||
"filterTasksSubtitle": "Filtrer la liste des tâches"
|
||||
},
|
||||
"footer": {
|
||||
"navigate": "Naviguer",
|
||||
"open": "Ouvrir",
|
||||
"results_one": "{{count}} résultat",
|
||||
"results_other": "{{count}} résultats",
|
||||
"typeToSearch": "Saisissez du texte pour rechercher"
|
||||
}
|
||||
},
|
||||
"feedback": {
|
||||
"later": "Peut-être plus tard",
|
||||
"sentiment": {
|
||||
"title": "How's Donetick working for you?",
|
||||
"subtitle": "Votre réponse nous aide à décider de ce qu'il faut construire ensuite.",
|
||||
"options": {
|
||||
"love": "J'adore",
|
||||
"okay": "C'est ok",
|
||||
"issues": "Problèmes rencontrés"
|
||||
}
|
||||
},
|
||||
"categories": {
|
||||
"bugs": "Anomalies",
|
||||
"missingFeature": "Fonctionnalités manquantes",
|
||||
"tooComplicated": "Trop compliqué",
|
||||
"slow": "Lent",
|
||||
"notifications": "Notifications",
|
||||
"ai": "IA",
|
||||
"other": "Autres"
|
||||
},
|
||||
"details": {
|
||||
"title": "Que pouvons-nous améliorer ?",
|
||||
"messageLabel": "Dites-nous-en plus",
|
||||
"messagePlaceholder": "What happened, or what would make this better?",
|
||||
"contextNote": "We'll include your app version, device and platform so we can reproduce issues.",
|
||||
"submit": "Envoyer vos remarques",
|
||||
"contextNoteSelfHosted": "Vous êtes sur une instance autohébergée, donc rien n'est envoyé depuis votre serveur — nous allons ouvrir un problème GitHub prérempli que vous pouvez examiner et modifier si besoin.",
|
||||
"submitSelfHosted": "Continuer sur GitHub"
|
||||
},
|
||||
"review": {
|
||||
"title": "Nous sommes ravis que vous l'appréciez !",
|
||||
"subtitle": "A rating or a star helps other people find Donetick.",
|
||||
"github": "Mettez une étoile sur GitHub",
|
||||
"appStore": "Évaluer sur l'App Store",
|
||||
"playStore": "Évaluer sur Google Play"
|
||||
},
|
||||
"thanks": {
|
||||
"title": "Merci pour votre retour",
|
||||
"subtitle": "We read every response and it shapes what we work on next."
|
||||
},
|
||||
"github": {
|
||||
"title": "Signaler sur GitHub",
|
||||
"subtitle": "We've filled in an issue with your notes and version details. Nothing has been sent yet — review it and post when you're ready.",
|
||||
"open": "Ouvrir un ticket"
|
||||
}
|
||||
},
|
||||
"done": "Done",
|
||||
"clearAll": "Clear all",
|
||||
"upload": {
|
||||
"quotaTitle": "Storage Quota Exceeded",
|
||||
"quotaMessage": "You have exceeded your quota for uploading files.",
|
||||
"tooLargeTitle": "File Too Large",
|
||||
"tooLargeMessage": "The file you are trying to upload is too large.",
|
||||
"deniedTitle": "Permission Denied",
|
||||
"deniedMessage": "You do not have permission to upload files."
|
||||
},
|
||||
"getStarted": "Get Started!",
|
||||
"imageLoadFailed": "Failed to load image.",
|
||||
"typeHere": "Type in here…",
|
||||
"summaryOfChores": "This is a summary of your chores",
|
||||
"loadingOffline": "You are offline",
|
||||
"loadingOfflineSub": "This not available while offline. Please check your internet connection and try again.",
|
||||
"loadingSlow": "This is taking longer than usual. There might be an issue.",
|
||||
"navigateBack": "Navigate Back",
|
||||
"bottomNav": "Bottom Navigation",
|
||||
"profile": "Profile",
|
||||
"autocompletePlaceholder": "Type here...",
|
||||
"errorScreen": {
|
||||
"title": "Something went wrong",
|
||||
"fallback": "An unexpected error occurred. Try reloading — it usually fixes it.",
|
||||
"tryAgain": "Try again",
|
||||
"home": "Home",
|
||||
"login": "Login",
|
||||
"hideDetails": "Hide error details",
|
||||
"showDetails": "Show error details",
|
||||
"copyToClipboard": "Copy to clipboard",
|
||||
"copied": "Error details copied to clipboard"
|
||||
}
|
||||
}
|
||||
|
||||
17
public/locales/fr/filters.json
Normal file
17
public/locales/fr/filters.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"builder": {
|
||||
"errorName": "Please enter a filter name",
|
||||
"errorConditions": "Please configure at least one filter condition",
|
||||
"editTitle": "Edit Filter",
|
||||
"newTitle": "New Filter",
|
||||
"addConditions": "Add conditions to preview",
|
||||
"save": "Save Filter",
|
||||
"name": "Filter Name",
|
||||
"namePlaceholder": "e.g. Overdue tasks for Alice",
|
||||
"color": "Color"
|
||||
},
|
||||
"nameExists": "A filter with this name already exists",
|
||||
"tasks_one": "{{count}} task",
|
||||
"tasks_other": "{{count}} tasks",
|
||||
"overdue": "{{count}} overdue"
|
||||
}
|
||||
89
public/locales/fr/history.json
Normal file
89
public/locales/fr/history.json
Normal file
@@ -0,0 +1,89 @@
|
||||
{
|
||||
"edit": {
|
||||
"title": "Edit History",
|
||||
"completedDate": "Completed Date",
|
||||
"note": "Note",
|
||||
"additionalNotes": "Additional Notes",
|
||||
"deleteTitle": "Delete History",
|
||||
"deleteMessage": "Are you sure you want to delete this history?"
|
||||
},
|
||||
"status": {
|
||||
"inProgress": "In Progress",
|
||||
"completed": "Completed",
|
||||
"skipped": "Skipped",
|
||||
"pendingApproval": "Pending Approval",
|
||||
"rejected": "Rejected",
|
||||
"missed": "Missed",
|
||||
"rescheduled": "Rescheduled",
|
||||
"scheduled": "Scheduled"
|
||||
},
|
||||
"badge": {
|
||||
"onTime": "On Time",
|
||||
"onTimeLabel": "On time"
|
||||
},
|
||||
"detail": {
|
||||
"title": "Activity Detail",
|
||||
"openTask": "Open Task",
|
||||
"editEntry": "Edit Entry",
|
||||
"performedBy": "Performed by",
|
||||
"assignedTo": "Assigned to",
|
||||
"lastUpdated": "Last updated",
|
||||
"duration": "Duration",
|
||||
"pointsEarned": "Points earned",
|
||||
"points_one": "{{count}} pt",
|
||||
"points_other": "{{count}} pts",
|
||||
"note": "Note"
|
||||
},
|
||||
"charts": {
|
||||
"noData": "No data available",
|
||||
"noLabels": "No Labels",
|
||||
"unassigned": "Unassigned",
|
||||
"unknownTask": "Unknown Task",
|
||||
"late": "Late",
|
||||
"status": {
|
||||
"title": "Status",
|
||||
"description": "Completed tasks status"
|
||||
},
|
||||
"due": {
|
||||
"title": "Due Date",
|
||||
"description": "Current tasks due date"
|
||||
},
|
||||
"priority": {
|
||||
"title": "Priority",
|
||||
"description": "Tasks by priority"
|
||||
},
|
||||
"labels": {
|
||||
"title": "Labels",
|
||||
"description": "Tasks by labels"
|
||||
},
|
||||
"labelsDuration": {
|
||||
"title": "Labels (time)",
|
||||
"description": "Time spent by labels (hours)"
|
||||
},
|
||||
"tasksTime": {
|
||||
"title": "Tasks (time)",
|
||||
"description": "Time spent by individual tasks (hours)"
|
||||
},
|
||||
"assigneeBreakdown": {
|
||||
"title": "by Assignee",
|
||||
"description": "Tasks grouped by assignee"
|
||||
}
|
||||
},
|
||||
"filter": {
|
||||
"status": "Status",
|
||||
"pending": "Pending",
|
||||
"labels": "Labels",
|
||||
"hasNotes": "Has Notes",
|
||||
"hasPoints": "Has Points",
|
||||
"timePeriod": "Time Period",
|
||||
"user": "User"
|
||||
},
|
||||
"period": {
|
||||
"days_one": "{{count}} Day",
|
||||
"days_other": "{{count}} Days",
|
||||
"allTime": "All Time"
|
||||
},
|
||||
"activities": {
|
||||
"title": "Activities"
|
||||
}
|
||||
}
|
||||
9
public/locales/fr/labels.json
Normal file
9
public/locales/fr/labels.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"shared": "Shared",
|
||||
"delete": {
|
||||
"title": "Delete Label",
|
||||
"message": "Are you sure you want to delete this label? This will remove the label from all tasks."
|
||||
},
|
||||
"loadError": "Failed to load labels. Please try again.",
|
||||
"blurb": "Manage your labels and organize your tasks effectively. Labels will be automatically shared with your circle if they are used on a shared task."
|
||||
}
|
||||
74
public/locales/fr/points.json
Normal file
74
public/locales/fr/points.json
Normal file
@@ -0,0 +1,74 @@
|
||||
{
|
||||
"redeem": "Redeem Points",
|
||||
"redeemModal": {
|
||||
"redeemButton": "Redeem",
|
||||
"pointsAvailable": "{{count}} points available",
|
||||
"pointsToRedeem": "Points to Redeem",
|
||||
"placeholder": "Enter points...",
|
||||
"cannotExceed": "Cannot exceed available points",
|
||||
"quickAdd": "Quick Add:",
|
||||
"aboutToRedeem": "You are about to redeem",
|
||||
"amount": "{{count}} points",
|
||||
"remaining": "Remaining: {{count}} points"
|
||||
},
|
||||
"leaderboard": {
|
||||
"titlePoints": "Points Leaderboard",
|
||||
"titleTasks": "Tasks Leaderboard",
|
||||
"subtitlePoints": "Rankings based on points earned during the selected time period",
|
||||
"subtitleTasks": "Rankings based on tasks completed during the selected time period",
|
||||
"modePoints": "Points",
|
||||
"modeTasks": "Tasks",
|
||||
"you": "You",
|
||||
"tasksAndAvg": "{{tasks}} tasks • {{avg}} avg per task",
|
||||
"available": "{{count}} available",
|
||||
"points_one": "{{count}} point",
|
||||
"points_other": "{{count}} points"
|
||||
},
|
||||
"tabs": {
|
||||
"short7d": "7D",
|
||||
"short6m": "6M",
|
||||
"shortAll": "All",
|
||||
"days7": "7 Days",
|
||||
"months6": "6 Months",
|
||||
"allTime": "All Time"
|
||||
},
|
||||
"filter": {
|
||||
"analysisTitle": "Filter & Analysis",
|
||||
"title": "Filter Points",
|
||||
"showFor": "Show points for:",
|
||||
"timePeriod": "Time period:"
|
||||
},
|
||||
"cards": {
|
||||
"available": {
|
||||
"title": "Available",
|
||||
"subtext": "Ready to redeem"
|
||||
},
|
||||
"redeemed": {
|
||||
"title": "Redeemed",
|
||||
"subtext": "Previously used"
|
||||
},
|
||||
"total": {
|
||||
"title": "Total",
|
||||
"subtext": "All time earned"
|
||||
},
|
||||
"period": {
|
||||
"title": "Period Points",
|
||||
"allTime": "All time",
|
||||
"last6Months": "Last 6 months",
|
||||
"lastDays_one": "Last {{count}} day",
|
||||
"lastDays_other": "Last {{count}} days"
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"showingFor": "Showing points for",
|
||||
"unknownUser": "Unknown User",
|
||||
"overThe": "over the",
|
||||
"allTime": "All Time",
|
||||
"last6Months": "Last 6 Months",
|
||||
"lastDays_one": "Last {{count}} Day",
|
||||
"lastDays_other": "Last {{count}} Days"
|
||||
},
|
||||
"trend": {
|
||||
"title": "Points Trend"
|
||||
}
|
||||
}
|
||||
24
public/locales/fr/projects.json
Normal file
24
public/locales/fr/projects.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"iconPicker": {
|
||||
"chooseIcon": "Choose Project Icon",
|
||||
"availableIcons": "Available Icons"
|
||||
},
|
||||
"defaultChip": "Default",
|
||||
"tasks_one": "{{count}} task",
|
||||
"tasks_other": "{{count}} tasks",
|
||||
"shared": "Shared",
|
||||
"delete": {
|
||||
"title": "Delete Project",
|
||||
"message": "Are you sure you want to delete \"{{name}}\"? This will remove the project but keep all tasks (they'll move to the Default Project)."
|
||||
},
|
||||
"loadError": "Failed to load projects. Please try again.",
|
||||
"blurb": "Organize your tasks into projects. Create custom workspaces to keep your tasks organized and easily accessible.",
|
||||
"defaultDescription": "All tasks without a specific project",
|
||||
"selector": {
|
||||
"title": "Projects",
|
||||
"createNew": "Create New Project",
|
||||
"createNewDescription": "Add a custom project workspace",
|
||||
"manage": "Manage Projects",
|
||||
"manageDescription": "View, edit, and organize all projects"
|
||||
}
|
||||
}
|
||||
@@ -1,114 +1,27 @@
|
||||
{
|
||||
"title": "Paramètres",
|
||||
"circleSettings": {
|
||||
"title": "Paramètres du cercle",
|
||||
"description": "Votre compte est automatiquement connecté à un Cercle lorsque vous en créez un ou en rejoignez un. Invitez facilement des amis en partageant le code unique du Cercle ou le lien ci-dessous.",
|
||||
"circleCode": "Code du Cercle",
|
||||
"copyCode": "Copier le Code",
|
||||
"copyLink": "Copier le Lien",
|
||||
"codeCopied": "Code du cercle copié !",
|
||||
"linkCopied": "Lien copié !",
|
||||
"joinCircle": "Rejoindre un Cercle",
|
||||
"joinCirclePlaceholder": "Entrer le Code du Cercle",
|
||||
"join": "Rejoindre",
|
||||
"leave": "Quitter le Cercle",
|
||||
"leaveConfirmTitle": "Quitter le Cercle",
|
||||
"leaveConfirmMessage": "Êtes-vous sûr de vouloir quitter ce cercle ?",
|
||||
"circleMembers": "Membres du Cercle",
|
||||
"circleMemberRequests": "Demandes de Membres du Cercle",
|
||||
"admin": "Administrateur",
|
||||
"member": "Membre",
|
||||
"pending": "En attente",
|
||||
"accept": "Accepter",
|
||||
"reject": "Rejeter",
|
||||
"makeAdmin": "Nommer Administrateur",
|
||||
"makeMember": "Nommer Membre",
|
||||
"remove": "Supprimer",
|
||||
"webhookURL": "URL du Webhook",
|
||||
"webhookDescription": "Entrez une URL de Webhook pour recevoir des notifications pour les événements du cercle",
|
||||
"webhookPlaceholder": "https://votre-url-webhook.com"
|
||||
},
|
||||
"accountSettings": {
|
||||
"title": "Paramètres du Compte",
|
||||
"subscription": "Abonnement",
|
||||
"subscriptionStatus": "Plan Actuel",
|
||||
"free": "Gratuit",
|
||||
"plus": "Plus",
|
||||
"upgrade": "Mettre à Niveau",
|
||||
"cancel": "Annuler",
|
||||
"changePassword": "Changer le Mot de Passe",
|
||||
"password": "Mot de passe",
|
||||
"dangerZone": "Zone Dangereuse",
|
||||
"dangerZoneDescription": "Une fois votre compte supprimé, il n'y a pas de retour en arrière. Veuillez être certain.",
|
||||
"deleteAccount": "Supprimer le Compte"
|
||||
},
|
||||
"localization": {
|
||||
"title": "Localisation",
|
||||
"description": "Personnalisez la langue, le format de date et les préférences régionales pour votre compte.",
|
||||
"language": "Langue",
|
||||
"languageDescription": "Sélectionnez votre langue préférée",
|
||||
"dateFormat": "Format de Date",
|
||||
"dateFormatDescription": "Choisissez comment les dates doivent être affichées dans l'application",
|
||||
"timeFormat": "Format de l'Heure",
|
||||
"timeFormatDescription": "Sélectionnez le format 12 heures ou 24 heures",
|
||||
"12hour": "12 heures (AM/PM)",
|
||||
"24hour": "24 heures",
|
||||
"firstDayOfWeek": "Premier Jour de la Semaine",
|
||||
"firstDayOfWeekDescription": "Sélectionnez quel jour commence votre semaine",
|
||||
"sunday": "Dimanche",
|
||||
"monday": "Lundi",
|
||||
"saturday": "Samedi",
|
||||
"formats": {
|
||||
"mdy": "MM/JJ/AAAA (États-Unis)",
|
||||
"dmy": "JJ/MM/AAAA (Europe)",
|
||||
"ymd": "AAAA-MM-JJ (ISO)",
|
||||
"long": "Format long (ex., 1 janvier 2024)",
|
||||
"short": "Format court (ex., 1 janv. 2024)"
|
||||
}
|
||||
},
|
||||
"sidepanel": {
|
||||
"title": "Personnalisation du Panneau Latéral",
|
||||
"description": "Personnalisez la disposition et la visibilité des cartes dans le panneau latéral. Cette section n'est disponible que sur les grands écrans comme les tablettes et les ordinateurs de bureau."
|
||||
},
|
||||
"theme": {
|
||||
"title": "Préférences de thème",
|
||||
"description": "Choisissez comment le site vous apparaît. Sélectionnez un thème unique ou synchronisez avec votre système pour basculer automatiquement entre les thèmes jour et nuit.",
|
||||
"themeMode": "Mode de thème",
|
||||
"light": "Clair",
|
||||
"dark": "Sombre",
|
||||
"system": "Système"
|
||||
},
|
||||
"notifications": {
|
||||
"settingsSaved": "Paramètres enregistrés avec succès",
|
||||
"settingsSaveFailed": "Échec de l'enregistrement des paramètres",
|
||||
"invalidWebhook": "URL de webhook invalide"
|
||||
},
|
||||
"profile": {
|
||||
"title": "Paramètres du Profil",
|
||||
"description": "Mettez à jour votre nom d'affichage et votre photo de profil.",
|
||||
"photoUpdated": "Photo Mise à Jour",
|
||||
"photoUpdatedMessage": "Votre photo de profil a été mise à jour avec succès !",
|
||||
"uploadFailed": "Échec du Téléchargement",
|
||||
"uploadFailedMessage": "Échec du téléchargement de votre photo. Veuillez réessayer.",
|
||||
"profileUpdated": "Profil Mis à Jour",
|
||||
"profileUpdatedMessage": "Vos informations de profil ont été enregistrées avec succès !",
|
||||
"updateFailed": "Échec de la Mise à Jour",
|
||||
"updateFailedMessage": "Impossible de mettre à jour votre profil. Veuillez vérifier votre connexion et réessayer.",
|
||||
"changePhoto": "Changer la Photo",
|
||||
"displayName": "Nom d'Affichage",
|
||||
"displayNamePlaceholder": "Entrez votre nom d'affichage",
|
||||
"timezone": "Fuseau Horaire",
|
||||
"timezonePlaceholder": "Sélectionnez votre fuseau horaire",
|
||||
"common": {
|
||||
"save": "Enregistrer",
|
||||
"cancel": "Annuler"
|
||||
"cancel": "Annuler",
|
||||
"confirm": "Confirmer",
|
||||
"remove": "Retirer",
|
||||
"delete": "Supprimer",
|
||||
"refresh": "Actualiser",
|
||||
"loading": "Chargement…",
|
||||
"on": "Activé",
|
||||
"off": "Désactivé",
|
||||
"error": "Erreur",
|
||||
"success": "Succès",
|
||||
"plusFeature": "Fonctionnalité Plus",
|
||||
"earlyAccess": "Accès anticipé"
|
||||
},
|
||||
"overview": {
|
||||
"title": "Paramètres",
|
||||
"subtitle": "Personnalisez votre expérience et gérez les préférences de votre compte",
|
||||
"upgrade": {
|
||||
"title": "Passer à Plus",
|
||||
"description": "Débloquez des fonctionnalités puissantes pour améliorer votre productivité",
|
||||
"button": "Mettre à Niveau Maintenant",
|
||||
"description": "Débloquez des fonctionnalités puissantes pour gagner en productivité",
|
||||
"button": "Passer à Plus",
|
||||
"features": {
|
||||
"richText": "Descriptions en texte enrichi",
|
||||
"notifications": "Notifications de tâches",
|
||||
@@ -118,57 +31,537 @@
|
||||
},
|
||||
"sections": {
|
||||
"profile": {
|
||||
"title": "Paramètres du Profil",
|
||||
"description": "Mettez à jour vos informations de profil, photo, nom d'affichage et préférences de fuseau horaire."
|
||||
"title": "Paramètres du profil",
|
||||
"description": "Mettez à jour vos informations de profil, votre photo, votre nom affiché et votre fuseau horaire."
|
||||
},
|
||||
"circle": {
|
||||
"title": "Paramètres du Cercle",
|
||||
"description": "Gérez votre cercle, invitez des membres et gérez les demandes d'adhésion."
|
||||
"title": "Paramètres du cercle",
|
||||
"description": "Gérez votre cercle, invitez des membres et traitez les demandes d'adhésion."
|
||||
},
|
||||
"account": {
|
||||
"title": "Paramètres du Compte",
|
||||
"description": "Gérez votre abonnement, changez le mot de passe et les options de suppression de compte."
|
||||
"title": "Paramètres du compte",
|
||||
"description": "Gérez votre abonnement, changez votre mot de passe et supprimez votre compte."
|
||||
},
|
||||
"subaccounts": {
|
||||
"title": "Comptes Gérés",
|
||||
"description": "Créez et gérez des sous-comptes pour vous connecter et accomplir les tâches assignées."
|
||||
"title": "Comptes gérés",
|
||||
"description": "Créez et gérez des sous-comptes pouvant se connecter et accomplir les tâches assignées."
|
||||
},
|
||||
"notifications": {
|
||||
"title": "Notifications",
|
||||
"description": "Configurez les notifications push, les alertes par e-mail et les cibles de notification pour les tâches."
|
||||
"description": "Configurez les notifications push, les alertes par e-mail et les destinations de notification des tâches."
|
||||
},
|
||||
"mfa": {
|
||||
"title": "Authentification Multi-Facteurs",
|
||||
"description": "Ajoutez une couche de sécurité supplémentaire avec MFA en utilisant des applications d'authentification."
|
||||
"title": "Authentification multifacteur",
|
||||
"description": "Ajoutez une couche de sécurité supplémentaire avec la MFA via une application d'authentification."
|
||||
},
|
||||
"apitokens": {
|
||||
"title": "Jetons API",
|
||||
"title": "Jetons d'API",
|
||||
"description": "Générez et gérez des jetons d'accès pour les intégrations tierces et l'accès à l'API."
|
||||
},
|
||||
"storage": {
|
||||
"title": "Paramètres de Stockage",
|
||||
"description": "Sauvegardez et restaurez vos données, gérez le stockage local et les préférences de synchronisation."
|
||||
"title": "Paramètres de stockage",
|
||||
"description": "Sauvegardez et restaurez vos données, gérez le stockage local et la synchronisation."
|
||||
},
|
||||
"sidepanel": {
|
||||
"title": "Personnalisation du Panneau Latéral",
|
||||
"description": "Personnalisez la disposition et la visibilité des cartes dans l'interface du panneau latéral."
|
||||
"title": "Personnalisation du panneau latéral",
|
||||
"description": "Personnalisez la disposition et la visibilité des cartes du panneau latéral."
|
||||
},
|
||||
"theme": {
|
||||
"title": "Préférences de Thème",
|
||||
"description": "Choisissez votre thème préféré et configurez les paramètres de mode sombre/clair."
|
||||
"title": "Préférences de thème",
|
||||
"description": "Choisissez votre thème préféré et configurez le mode clair/sombre."
|
||||
},
|
||||
"localization": {
|
||||
"title": "Localisation",
|
||||
"description": "Personnalisez la langue, le format de date, le format de l'heure et les préférences régionales."
|
||||
"description": "Personnalisez la langue, le format de date et d'heure et les préférences régionales."
|
||||
},
|
||||
"advanced": {
|
||||
"title": "Paramètres Avancés",
|
||||
"description": "Configurez les webhooks, les mises à jour en temps réel et d'autres fonctionnalités avancées pour améliorer la productivité."
|
||||
"title": "Paramètres avancés",
|
||||
"description": "Configurez les webhooks, les mises à jour en temps réel et d'autres fonctionnalités avancées."
|
||||
},
|
||||
"developer": {
|
||||
"title": "Paramètres Développeur",
|
||||
"title": "Paramètres développeur",
|
||||
"description": "Consultez les informations techniques sur les jetons d'authentification, les connexions SSE et les données de débogage."
|
||||
},
|
||||
"feedback": {
|
||||
"title": "Envoyer un retour",
|
||||
"description": "Dites-nous ce que vous pensez de Donetick ou demandez une fonctionnalité."
|
||||
},
|
||||
"bugReport": {
|
||||
"title": "Signaler un bug",
|
||||
"description": "Quelque chose ne fonctionne pas ? Envoyez-nous les détails avec un instantané technique."
|
||||
}
|
||||
}
|
||||
},
|
||||
"profile": {
|
||||
"title": "Paramètres du profil",
|
||||
"description": "Mettez à jour votre nom affiché et votre photo de profil.",
|
||||
"photoUpdated": "Photo mise à jour",
|
||||
"photoUpdatedMessage": "Votre photo de profil a été mise à jour avec succès !",
|
||||
"uploadFailed": "Échec de l'envoi",
|
||||
"uploadFailedMessage": "Impossible d'envoyer votre photo. Veuillez réessayer.",
|
||||
"profileUpdated": "Profil mis à jour",
|
||||
"profileUpdatedMessage": "Les informations de votre profil ont été enregistrées avec succès !",
|
||||
"updateFailed": "Échec de la mise à jour",
|
||||
"updateFailedMessage": "Impossible de mettre à jour votre profil. Vérifiez votre connexion et réessayez.",
|
||||
"changePhoto": "Changer de photo",
|
||||
"editPhoto": "Modifier la photo de profil",
|
||||
"displayName": "Nom affiché",
|
||||
"displayNamePlaceholder": "Saisissez votre nom affiché",
|
||||
"timezone": "Fuseau horaire",
|
||||
"timezonePlaceholder": "Sélectionnez votre fuseau horaire",
|
||||
"save": "Enregistrer",
|
||||
"cancel": "Annuler"
|
||||
},
|
||||
"circleSettings": {
|
||||
"title": "Paramètres du cercle",
|
||||
"description": "Votre compte est automatiquement rattaché à un cercle lorsque vous en créez un ou que vous en rejoignez un. Invitez facilement vos proches en partageant le code ou le lien du cercle ci-dessous. Vous recevrez une notification ici lorsque quelqu'un demandera à rejoindre votre cercle.",
|
||||
"memberOf": "Vous faites partie de {{name}}",
|
||||
"yourCircleCode": "Votre code de cercle est :",
|
||||
"copyCode": "Copier le code",
|
||||
"shareInvite": "Partager l'invitation",
|
||||
"codeCopied": "Code copié dans le presse-papiers",
|
||||
"linkCopied": "Lien d'invitation copié dans le presse-papiers",
|
||||
"myCircle": "mon cercle",
|
||||
"shareTitle": "Rejoignez {{name}} sur Donetick",
|
||||
"shareText": "J'aimerais vous inviter à rejoindre {{name}} sur Donetick.",
|
||||
"shareDialogTitle": "Partager l'invitation au cercle",
|
||||
"leave": "Quitter le cercle",
|
||||
"leaveConfirmTitle": "Quitter le cercle",
|
||||
"leaveConfirmMessage": "Voulez-vous vraiment quitter votre cercle ?",
|
||||
"leaveConfirmButton": "Quitter",
|
||||
"leftCircle": "Vous avez quitté le cercle",
|
||||
"leaveFailed": "Impossible de quitter le cercle",
|
||||
"circleMembers": "Membres du cercle",
|
||||
"you": "(Vous)",
|
||||
"pendingApproval": "En attente d'approbation",
|
||||
"joinedOn": "A rejoint le {{date}}",
|
||||
"requestedToJoin": "Demande d'adhésion {{date}}",
|
||||
"roles": {
|
||||
"member": "Membre",
|
||||
"memberDescription": "Un membre ordinaire du cercle",
|
||||
"manager": "Gestionnaire",
|
||||
"managerDescription": "Peut se faire passer pour d'autres personnes et agir en leur nom",
|
||||
"admin": "Administrateur",
|
||||
"adminDescription": "Accès complet au cercle"
|
||||
},
|
||||
"roleUpdateFailed": "Impossible de mettre à jour le rôle",
|
||||
"removeMemberTitle": "Retirer le membre",
|
||||
"removeMemberMessage": "Voulez-vous vraiment retirer {{name}} de votre cercle ?",
|
||||
"memberRemoved": "Membre retiré avec succès",
|
||||
"circleMemberRequests": "Demandes d'adhésion au cercle",
|
||||
"lastUpdated": "Dernière mise à jour : {{time}}",
|
||||
"refreshing": "Actualisation…",
|
||||
"refreshFailed": "Impossible d'actualiser les demandes d'adhésion",
|
||||
"wantsToJoin": "{{name}} souhaite rejoindre votre cercle.",
|
||||
"accept": "Accepter",
|
||||
"acceptRequestTitle": "Accepter la demande d'adhésion",
|
||||
"acceptRequestMessage": "Voulez-vous vraiment accepter {{name}} (identifiant : {{username}}) dans votre cercle ?",
|
||||
"requestAccepted": "Demande acceptée avec succès",
|
||||
"or": "ou",
|
||||
"joinOtherDescription": "Vous souhaitez rejoindre le cercle de quelqu'un d'autre ? Demandez-lui son code de cercle ou son lien d'invitation. Saisissez le code ci-dessous pour le rejoindre.",
|
||||
"enterCircleCode": "Saisissez le code du cercle :",
|
||||
"enterCodePlaceholder": "Saisir le code",
|
||||
"joinCircle": "Rejoindre le cercle",
|
||||
"joinedPending": "Cercle rejoint avec succès, attendez que la personne propriétaire accepte votre demande.",
|
||||
"alreadyMember": "Vous êtes déjà membre de ce cercle",
|
||||
"joinFailed": "Impossible de rejoindre le cercle"
|
||||
},
|
||||
"accountSettings": {
|
||||
"title": "Paramètres du compte",
|
||||
"description": "Modifiez les paramètres de votre compte, votre formule ou votre mot de passe",
|
||||
"accountType": "Type de compte : {{type}}",
|
||||
"free": "Gratuit",
|
||||
"plus": "Plus",
|
||||
"plusUntil": "Plus (jusqu'au {{date}})",
|
||||
"activeDescription": "Vous êtes actuellement abonné à la formule Plus. Votre abonnement sera renouvelé le {{date}}.",
|
||||
"cancelledDescription": "Vous avez résilié votre abonnement. Votre compte repassera à la formule Gratuite le {{date}}.",
|
||||
"freeDescription": "Vous utilisez actuellement la formule Gratuite. Passez à Plus pour débloquer plus de fonctionnalités.",
|
||||
"upgrade": "Passer à Plus",
|
||||
"cancel": "Résilier",
|
||||
"password": "Mot de passe :",
|
||||
"changePassword": "Changer le mot de passe",
|
||||
"passwordChanged": "Mot de passe modifié avec succès",
|
||||
"passwordChangeFailed": "Échec du changement de mot de passe",
|
||||
"dangerZone": "Zone sensible",
|
||||
"dangerZoneDescription": "Une fois votre compte supprimé, il n'y a pas de retour en arrière. Soyez-en bien sûr.",
|
||||
"deleteAccount": "Supprimer le compte",
|
||||
"accountDeleted": "Compte supprimé avec succès",
|
||||
"subscriptionCancelled": "Abonnement résilié",
|
||||
"subscriptionCancelFailed": "Impossible de résilier l'abonnement",
|
||||
"purchase": {
|
||||
"success": "Achat réussi ! Redémarrez l'application pour accéder aux fonctionnalités Plus.",
|
||||
"storeConnection": "Problème de connexion au store. Vérifiez votre réseau et réessayez.",
|
||||
"notAllowed": "Les achats ne sont pas autorisés sur cet appareil. Vérifiez les restrictions de votre appareil.",
|
||||
"unavailable": "Cet abonnement n'est pas disponible. Veuillez réessayer plus tard.",
|
||||
"alreadyProcessed": "Cet achat a déjà été traité. Si vous pensez qu'il s'agit d'une erreur, contactez le support.",
|
||||
"receiptMissing": "Reçu d'achat manquant. Veuillez réessayer l'achat.",
|
||||
"networkError": "Erreur réseau. Vérifiez votre connexion et réessayez.",
|
||||
"invalidReceipt": "Reçu d'achat invalide. Contactez le support si le problème persiste.",
|
||||
"pending": "Le paiement est en attente d'approbation. Vous aurez accès dès qu'il sera approuvé.",
|
||||
"failed": "Échec de l'achat : {{error}}. Réessayez ou contactez le support.",
|
||||
"unknownError": "Erreur inconnue"
|
||||
}
|
||||
},
|
||||
"subaccounts": {
|
||||
"title": "Comptes gérés",
|
||||
"description": "Gérez les sous-comptes. Leurs utilisateurs peuvent se connecter et accomplir les tâches qui leur sont assignées.",
|
||||
"notParentTitle": "Gestion des sous-comptes",
|
||||
"notParentMessage": "Seuls les comptes principaux peuvent gérer des sous-comptes.",
|
||||
"freePlanNotice": "La formule Gratuite permet 1 sous-compte. Passez à Plus pour en avoir jusqu'à 5.",
|
||||
"count": "Sous-comptes ({{count}})",
|
||||
"add": "Ajouter un sous-compte",
|
||||
"loading": "Chargement des sous-comptes…",
|
||||
"emptyTitle": "Aucun sous-compte",
|
||||
"emptyDescription": "Créez des sous-comptes pour que les membres de l'équipe puissent se connecter et accomplir leurs tâches.",
|
||||
"addFirst": "Ajouter votre premier sous-compte",
|
||||
"username": "Identifiant : {{username}}",
|
||||
"created": "Créé le : {{date}}",
|
||||
"changePassword": "Changer le mot de passe",
|
||||
"deleteAccount": "Supprimer le compte",
|
||||
"createdSuccess": "Le sous-compte « {{name}} » a été créé avec succès !",
|
||||
"createFailed": "Impossible de créer le sous-compte : {{error}}",
|
||||
"createFailedGeneric": "Impossible de créer le sous-compte",
|
||||
"passwordUpdated": "Mot de passe du sous-compte mis à jour avec succès",
|
||||
"passwordUpdateFailed": "Impossible de mettre à jour le mot de passe : {{error}}",
|
||||
"passwordUpdateFailedGeneric": "Impossible de mettre à jour le mot de passe",
|
||||
"deleteConfirmTitle": "Supprimer le sous-compte",
|
||||
"deleteConfirmMessage": "Voulez-vous vraiment supprimer le sous-compte « {{name}} » ? Cette action est irréversible.",
|
||||
"deleted": "Sous-compte « {{name}} » supprimé avec succès",
|
||||
"deleteFailed": "Impossible de supprimer le sous-compte : {{error}}",
|
||||
"deleteFailedGeneric": "Impossible de supprimer le sous-compte",
|
||||
"howItWorksTitle": "Comment fonctionnent les comptes gérés",
|
||||
"howItWorks1": "Les comptes gérés sont créés par le compte principal ; ils sont destinés aux personnes dont vous voulez pouvoir supprimer le compte et réinitialiser le mot de passe.",
|
||||
"howItWorks2": "Les sous-comptes peuvent se connecter avec leur propre identifiant et mot de passe.",
|
||||
"howItWorks3": "Les comptes gérés peuvent accomplir des tâches mais disposent de permissions administratives limitées",
|
||||
"howItWorks4": "Les comptes gérés sont automatiquement ajoutés à votre cercle"
|
||||
},
|
||||
"notifications": {
|
||||
"title": "Paramètres de notification",
|
||||
"deviceSection": "Notifications de l'appareil",
|
||||
"deviceSectionDescription": "Gérez les notifications de votre appareil",
|
||||
"deviceLabel": "Notification de l'appareil",
|
||||
"deviceHelper": "Recevez une notification sur votre appareil lorsqu'une tâche arrive à échéance",
|
||||
"mobileOnly": "Cette fonctionnalité n'est disponible que sur mobile",
|
||||
"testNotification": "Notification de test",
|
||||
"testNotificationBody": "Une tâche arrive bientôt à échéance",
|
||||
"dueTitle": "Notification d'échéance",
|
||||
"dueLabel": "Notification lorsque la tâche arrive à échéance",
|
||||
"preDueTitle": "Notification avant échéance",
|
||||
"preDueLabel": "Notification quelques heures avant l'échéance de la tâche",
|
||||
"overdueTitle": "Notification de retard",
|
||||
"overdueLabel": "Notification lorsque la tâche est en retard",
|
||||
"pushLabel": "Notifications push",
|
||||
"pushHelper": "Recevez les rappels, annonces et attributions de tâches par notification push",
|
||||
"registeredDevices": "Appareils enregistrés ({{count}}/5)",
|
||||
"registeredDevicesDescription": "Appareils enregistrés pour recevoir les notifications push de votre compte",
|
||||
"currentDevice": "Appareil actuel : {{platform}} {{model}}",
|
||||
"currentDeviceNotRegistered": "Cet appareil n'est pas enregistré pour les notifications push",
|
||||
"limitReached": "Limite atteinte",
|
||||
"registerDevice": "Enregistrer l'appareil",
|
||||
"unknownDevice": "Appareil inconnu",
|
||||
"deviceCreatedAt": "Créé le : {{date}}",
|
||||
"noDevices": "Aucun appareil enregistré pour les notifications push",
|
||||
"customSection": "Notification personnalisée",
|
||||
"customSectionDescription": "Notification via une autre plateforme comme Telegram ou Pushover",
|
||||
"customLabel": "Notification personnalisée",
|
||||
"customHelper": "Recevoir les notifications sur une autre plateforme",
|
||||
"targetNone": "Aucune",
|
||||
"targetTelegram": "Telegram",
|
||||
"targetPushover": "Pushover",
|
||||
"targetWebhooks": "Webhooks",
|
||||
"telegramBotHelpBefore": "Vous devez d'abord envoyer un message au bot pour que les notifications Telegram fonctionnent",
|
||||
"telegramBotHelpAfter": "pour démarrer une conversation",
|
||||
"clickHere": "Cliquez ici",
|
||||
"chatId": "ID de discussion",
|
||||
"chatIdPlaceholder": "ID utilisateur / ID de discussion",
|
||||
"telegramChatIdHelpBefore": "Si vous ne connaissez pas votre ID de discussion, démarrez une conversation avec userinfobot : il vous l'enverra.",
|
||||
"telegramChatIdHelpAfter": "pour démarrer une conversation avec userinfobot",
|
||||
"userKey": "Clé utilisateur",
|
||||
"userKeyPlaceholder": "ID utilisateur",
|
||||
"chatIdRequired": "L'ID de discussion est obligatoire",
|
||||
"chatIdInvalid": "ID de discussion invalide",
|
||||
"userKeyRequired": "La clé utilisateur est obligatoire",
|
||||
"targetUpdated": "Destination de notification mise à jour",
|
||||
"targetUpdateFailed": "Erreur lors de la mise à jour de la destination de notification : {{error}}",
|
||||
"deviceRegistered": "Appareil enregistré avec succès pour les notifications push.",
|
||||
"deviceLimitTitle": "Limite d'appareils atteinte",
|
||||
"deviceLimitMessage": "Vous avez atteint la limite de 5 appareils enregistrés. Retirez un appareil avant d'enregistrer celui-ci.",
|
||||
"registrationFailedTitle": "Échec de l'enregistrement",
|
||||
"registrationFailedMessage": "Impossible d'enregistrer l'appareil automatiquement. Veuillez réessayer.",
|
||||
"permissionRequiredTitle": "Autorisation requise",
|
||||
"permissionRequiredMessage": "L'autorisation de notifications push est nécessaire pour enregistrer cet appareil.",
|
||||
"registrationInitiatedTitle": "Enregistrement lancé",
|
||||
"registrationInitiatedMessage": "L'enregistrement des notifications push a été lancé. L'appareil sera enregistré automatiquement.",
|
||||
"registerDeviceFailed": "Impossible d'enregistrer l'appareil. Veuillez réessayer.",
|
||||
"permissionDeniedTitle": "Autorisation de notification refusée",
|
||||
"permissionDeniedMessage": "Vous avez refusé les autorisations de notification. Vous pourrez les activer plus tard dans les réglages de votre appareil.",
|
||||
"pushPermissionDeniedTitle": "Autorisation de notifications push refusée",
|
||||
"pushPermissionDeniedMessage": "Les notifications push ont été désactivées. Vous pouvez les activer dans les réglages de votre appareil si besoin.",
|
||||
"unregisterFailed": "Impossible de désenregistrer l'appareil"
|
||||
},
|
||||
"mfa": {
|
||||
"title": "Authentification multifacteur",
|
||||
"description": "Renforcez la sécurité de votre compte avec l'authentification multifacteur (MFA). Une fois activée, vous devrez saisir un code de vérification de votre application d'authentification en plus de votre mot de passe lors de la connexion.",
|
||||
"twoFactor": "Authentification à deux facteurs",
|
||||
"enabledSubtitle": "Votre compte est protégé par la 2FA",
|
||||
"disabledSubtitle": "Sécurisez votre compte avec une application d'authentification",
|
||||
"enable": "Activer",
|
||||
"disable": "Désactiver",
|
||||
"enabledSuccess": "La MFA a été activée avec succès !",
|
||||
"disabledSuccess": "La MFA a été désactivée avec succès !",
|
||||
"errors": {
|
||||
"qrGenerationFailed": "Impossible de générer le code QR",
|
||||
"invalidResponse": "Réponse invalide du serveur. Code QR ou clé secrète manquant.",
|
||||
"notFound": "Point de terminaison de configuration MFA introuvable. Cette fonctionnalité n'est peut-être pas encore disponible.",
|
||||
"unauthorized": "Non autorisé. Veuillez vous reconnecter.",
|
||||
"serverError": "Erreur serveur. Veuillez réessayer plus tard.",
|
||||
"setupFailed": "Échec de la configuration de la MFA ({{status}}). Veuillez réessayer.",
|
||||
"networkError": "Erreur réseau. Vérifiez votre connexion et réessayez.",
|
||||
"invalidCode": "Code de vérification invalide. Veuillez réessayer.",
|
||||
"confirmFailed": "Impossible de confirmer la MFA. Veuillez réessayer.",
|
||||
"disableFailed": "Impossible de désactiver la MFA. Veuillez réessayer."
|
||||
},
|
||||
"setup": {
|
||||
"title": "Configurer l'authentification multifacteur",
|
||||
"addedAccount": "J'ai ajouté le compte",
|
||||
"back": "Retour",
|
||||
"verifyAndEnable": "Vérifier et activer",
|
||||
"savedBackupCodes": "J'ai enregistré mes codes de secours",
|
||||
"step1Label": "Étape 1 :",
|
||||
"step1": "Scannez le code QR ci-dessous avec votre application d'authentification (Google Authenticator, Authy, etc.)",
|
||||
"qrAlt": "Code QR MFA",
|
||||
"qrFailed": "Le code QR n'a pas pu être généré. Réessayez ou utilisez la clé de saisie manuelle ci-dessous.",
|
||||
"manualKey": "Clé de saisie manuelle :",
|
||||
"step2Label": "Étape 2 :",
|
||||
"step2": "Saisissez le code de vérification à 6 chiffres de votre application d'authentification",
|
||||
"codePlaceholder": "Saisir le code à 6 chiffres",
|
||||
"successTitle": "MFA activée avec succès !",
|
||||
"backupCodesTitle": "Conservez ces codes de secours en lieu sûr",
|
||||
"backupCodesDescription": "Ces codes vous permettent d'accéder à votre compte si vous perdez votre appareil d'authentification. Chaque code ne peut être utilisé qu'une seule fois."
|
||||
},
|
||||
"disableModal": {
|
||||
"title": "Désactiver l'authentification multifacteur",
|
||||
"warning": "Désactiver la MFA rendra votre compte moins sûr. Voulez-vous vraiment continuer ?",
|
||||
"prompt": "Saisissez un code de vérification de votre application d'authentification pour confirmer :",
|
||||
"confirm": "Désactiver la MFA"
|
||||
},
|
||||
"backupCodesModal": {
|
||||
"title": "Nouveaux codes de secours",
|
||||
"warning": "Vos anciens codes de secours ne sont plus valides. Conservez ces nouveaux codes en lieu sûr. Chaque code ne peut être utilisé qu'une seule fois."
|
||||
}
|
||||
},
|
||||
"apiTokens": {
|
||||
"title": "Jetons d'API",
|
||||
"accessToken": "Jeton d'accès",
|
||||
"description": "Créez un jeton à utiliser avec l'API pour mettre à jour les éléments qui déclenchent des tâches",
|
||||
"plusNotice": "Les jetons d'API ne sont pas disponibles dans la formule de base. Passez à Plus pour générer des jetons d'API, vous intégrer à des systèmes externes et automatiser vos tâches.",
|
||||
"showToken": "Afficher le jeton",
|
||||
"hideToken": "Masquer le jeton",
|
||||
"removeTitle": "Retirer le jeton",
|
||||
"removeMessage": "Voulez-vous vraiment retirer {{name}} ?",
|
||||
"removedTitle": "Retiré",
|
||||
"removedMessage": "Le jeton d'API a été retiré",
|
||||
"tokenCopied": "Jeton copié dans le presse-papiers",
|
||||
"generateNew": "Générer un nouveau jeton",
|
||||
"nameModalTitle": "Donnez un nom à votre nouveau jeton, quelque chose qui vous permettra de le reconnaître.",
|
||||
"generateToken": "Générer le jeton"
|
||||
},
|
||||
"storage": {
|
||||
"title": "Paramètres de stockage",
|
||||
"serverTitle": "Utilisation du stockage serveur",
|
||||
"serverDescription": "Il s'agit de l'espace occupé par votre compte sur nos serveurs (fichiers, images et données que vous avez envoyés).",
|
||||
"usagePlaceholder": "-- Mo utilisés / -- Mo au total (--)",
|
||||
"usage": "{{used}} Mo utilisés / {{total}} Mo au total ({{percent}} %)",
|
||||
"basicPlanNotice": "Le stockage serveur n'est pas disponible dans la formule de base. Passez à Plus pour suivre votre utilisation.",
|
||||
"localTitleApp": "Stockage local et cache de l'application",
|
||||
"localTitleBrowser": "Stockage local et cache du navigateur",
|
||||
"localDescription": "Ce sont les données enregistrées localement dans votre navigateur pour un accès plus rapide. Les effacer n'affectera pas vos données serveur, mais pourra vous déconnecter.",
|
||||
"clearLocal": "Effacer tout le stockage local et le cache",
|
||||
"clearLocalTitle": "Effacer tout le stockage local",
|
||||
"clearLocalMessage": "Voulez-vous vraiment effacer votre stockage local et le cache ? Toutes vos données seront supprimées de ce navigateur et vous devrez vous reconnecter.",
|
||||
"clearAll": "Tout effacer",
|
||||
"appPreferences": "Préférences de l'application",
|
||||
"deviceOnly": "Appareil uniquement",
|
||||
"appPreferencesDescription": "Ce sont les préférences et réglages enregistrés localement sur votre appareil par l'application. Les effacer réinitialisera les réglages de l'application et pourra vous déconnecter, sans affecter vos données serveur.",
|
||||
"clearPreferences": "Effacer les préférences de l'application",
|
||||
"clearPreferencesTitle": "Effacer les préférences de l'application",
|
||||
"clearPreferencesMessage": "Voulez-vous vraiment effacer toutes les préférences de l'application ? Vos réglages seront réinitialisés et vous devrez peut-être vous reconnecter."
|
||||
},
|
||||
"sidepanel": {
|
||||
"title": "Personnalisation du panneau latéral",
|
||||
"heading": "Paramètres du panneau latéral",
|
||||
"description": "Choisissez les cartes qui apparaissent dans le panneau latéral et leur ordre. Faites-les glisser pour les réorganiser ou modifiez leur visibilité.",
|
||||
"resetToDefaults": "Réinitialiser par défaut",
|
||||
"resetHelper": "La visibilité et l'ordre par défaut de toutes les cartes seront rétablis.",
|
||||
"cards": {
|
||||
"welcome": {
|
||||
"name": "Changement d'utilisateur",
|
||||
"description": "Permet aux administrateurs et gestionnaires de voir les tâches d'autres personnes"
|
||||
},
|
||||
"smartInsights": {
|
||||
"name": "Aperçus intelligents",
|
||||
"description": "Actions rapides basées sur vos tâches"
|
||||
},
|
||||
"assignees": {
|
||||
"name": "Tâches par personne assignée",
|
||||
"description": "Regroupe les tâches selon la personne à qui elles sont assignées"
|
||||
},
|
||||
"calendar": {
|
||||
"name": "Vue calendrier",
|
||||
"description": "Affiche les tâches au format calendrier"
|
||||
},
|
||||
"activities": {
|
||||
"name": "Activités récentes",
|
||||
"description": "Affiche les tâches récemment terminées et les activités"
|
||||
},
|
||||
"weeklyGoals": {
|
||||
"name": "Objectifs hebdomadaires",
|
||||
"description": "Affiche la progression hebdomadaire et les statistiques de la famille"
|
||||
}
|
||||
}
|
||||
},
|
||||
"theme": {
|
||||
"title": "Préférences de thème",
|
||||
"description": "Choisissez l'apparence du site. Sélectionnez un thème fixe ou synchronisez-le avec votre système pour basculer automatiquement entre thème clair et sombre.",
|
||||
"themeMode": "Mode de thème",
|
||||
"light": "Clair",
|
||||
"dark": "Sombre",
|
||||
"system": "Système"
|
||||
},
|
||||
"localization": {
|
||||
"title": "Localisation",
|
||||
"description": "Personnalisez la langue, le format de date et les préférences régionales de votre compte.",
|
||||
"language": "Langue",
|
||||
"languageDescription": "Sélectionnez votre langue préférée",
|
||||
"rtlNotice": "Cette langue s'écrit de droite à gauche (RTL)",
|
||||
"dateFormat": "Format de date",
|
||||
"dateFormatDescription": "Choisissez comment les dates s'affichent dans toute l'application",
|
||||
"timeFormat": "Format d'heure",
|
||||
"timeFormatDescription": "Sélectionnez le format 12 ou 24 heures",
|
||||
"preview": "Aperçu : {{value}}",
|
||||
"12hour": "12 heures (AM/PM)",
|
||||
"24hour": "24 heures",
|
||||
"firstDayOfWeek": "Premier jour de la semaine",
|
||||
"firstDayOfWeekDescription": "Choisissez le jour qui commence votre semaine",
|
||||
"sunday": "Dimanche",
|
||||
"monday": "Lundi",
|
||||
"saturday": "Samedi",
|
||||
"formats": {
|
||||
"mdy": "MM/JJ/AAAA (États-Unis)",
|
||||
"dmy": "JJ/MM/AAAA (Europe)",
|
||||
"ymd": "AAAA-MM-JJ (ISO)",
|
||||
"long": "Format long (ex. : 1 janvier 2024)",
|
||||
"short": "Format court (ex. : 1 janv. 2024)"
|
||||
}
|
||||
},
|
||||
"advanced": {
|
||||
"title": "Paramètres avancés",
|
||||
"description": "Configurez des fonctionnalités avancées comme les webhooks et les mises à jour en temps réel pour gagner en productivité.",
|
||||
"offlineTitle": "Mode hors ligne",
|
||||
"offlineDescription": "Continuez à utiliser Donetick hors ligne sur cet appareil ou navigateur. Vos modifications sont enregistrées localement et synchronisées dès votre retour en ligne.",
|
||||
"offlineToggle": "Activer le mode hors ligne",
|
||||
"offlineHelper": "Le désactiver supprime les modifications hors ligne non synchronisées et les données enregistrées sur cet appareil ou navigateur.",
|
||||
"offlineEnabled": "Mode hors ligne activé pour cet appareil/navigateur",
|
||||
"offlineDisabled": "Mode hors ligne désactivé et données locales effacées",
|
||||
"offlineDisabledPartial": "Le mode hors ligne a été désactivé, mais certaines données locales peuvent subsister",
|
||||
"offlineDisableTitle": "Désactiver le mode hors ligne",
|
||||
"offlineDisableMessage": "Désactiver le mode hors ligne supprimera les modifications non synchronisées et les données hors ligne enregistrées sur cet appareil ou navigateur. Voulez-vous continuer ?",
|
||||
"offlineDisableConfirm": "Désactiver et effacer les données",
|
||||
"webhookTitle": "Intégration webhook",
|
||||
"webhookDescription": "Les webhooks vous permettent d'envoyer des notifications en temps réel à d'autres services lorsqu'un événement survient dans votre cercle. Configurez une URL de webhook pour recevoir des mises à jour en temps réel.",
|
||||
"webhookPlusNotice": "Les notifications par webhook ne sont pas disponibles dans la formule de base. Passez à Plus pour recevoir des mises à jour en temps réel via webhooks.",
|
||||
"webhookToggle": "Activer le webhook",
|
||||
"webhookHelper": "Activez les notifications webhook pour les mises à jour des tâches et des éléments.",
|
||||
"webhookURL": "URL du webhook",
|
||||
"webhookUpdated": "URL du webhook mise à jour avec succès",
|
||||
"webhookUpdateFailed": "Impossible de mettre à jour l'URL du webhook",
|
||||
"realtimeTitle": "Mises à jour en temps réel",
|
||||
"realtimeDescription": "Configurez la façon dont vous recevez les mises à jour en direct lorsque les tâches et activités changent dans votre cercle.",
|
||||
"realtime": {
|
||||
"toggleLabel": "Activer les mises à jour en temps réel",
|
||||
"title": "Mises à jour en temps réel",
|
||||
"subtitle": "Recevez des notifications instantanées lorsque les tâches sont mises à jour",
|
||||
"statusLabel": "Statut :",
|
||||
"basicPlan": "Les mises à jour en temps réel ne sont pas disponibles dans la formule de base. Passez à Plus pour recevoir des notifications instantanées lorsque les tâches sont mises à jour.",
|
||||
"disabled": "Les mises à jour en temps réel sont désactivées. Activez-les pour voir les changements en direct lorsque vous ou d'autres membres du cercle terminez, passez ou modifiez des tâches.",
|
||||
"connected": "Les mises à jour en temps réel fonctionnent. Vous verrez les changements en direct lorsque vous ou d'autres membres du cercle terminez, passez ou modifiez des tâches.",
|
||||
"connecting": "Connexion aux mises à jour en temps réel…",
|
||||
"errored": "Les mises à jour en temps réel sont activées mais ne fonctionnent pas : {{error}}",
|
||||
"notConnected": "Les mises à jour en temps réel sont activées mais non connectées actuellement.",
|
||||
"basicPlanNotice": "Les mises à jour en temps réel ne sont pas disponibles dans la formule de base. Passez à Plus pour recevoir des notifications instantanées lorsque vous ou d'autres membres du cercle terminez, passez ou modifiez des tâches."
|
||||
}
|
||||
},
|
||||
"subscription": {
|
||||
"sessionFailed": "Failed to create subscription session",
|
||||
"errorTitle": "Subscription Error",
|
||||
"errorMessage": "Failed to start subscription process. Please try again.",
|
||||
"subscribe": "Subscribe",
|
||||
"cancelAnytime": "Cancel anytime. No hidden fees. Secure payment powered by Stripe."
|
||||
},
|
||||
"childUsers": {
|
||||
"errNameRequired": "Sub account name is required",
|
||||
"errNameMin": "Sub account name must be at least 2 characters",
|
||||
"errNameMax": "Sub account name must be less than 20 characters",
|
||||
"errNameChars": "Sub account name can only contain lowercase letters, dot and dash",
|
||||
"errPasswordRequired": "Password is required",
|
||||
"errPasswordLength": "Password must be between 8 and 64 characters",
|
||||
"errPasswordMatch": "Passwords do not match",
|
||||
"errDisplayNameMax": "Display name must be less than 50 characters",
|
||||
"createTitle": "Create Sub Account",
|
||||
"createButton": "Create Account",
|
||||
"nameLabel": "Sub Account Name *",
|
||||
"namePlaceholder": "Enter sub account name (e.g., sarah)",
|
||||
"displayNameLabel": "Display Name",
|
||||
"displayNamePlaceholder": "Display name (optional, defaults to sub account name)",
|
||||
"passwordLabel": "Password *",
|
||||
"passwordPlaceholder": "Enter password (8-64 characters)",
|
||||
"confirmPasswordLabel": "Confirm Password *",
|
||||
"confirmPasswordPlaceholder": "Confirm password"
|
||||
},
|
||||
"passwordChange": {
|
||||
"minLength": "Password must be at least 8 characters",
|
||||
"maxLength": "Password must be less than 64 characters"
|
||||
},
|
||||
"payment": {
|
||||
"cancelledTitle": "Payment has been cancelled",
|
||||
"cancelledRedirect": "You will be redirected to the main page shortly.",
|
||||
"successTitle": "Payment Successful!",
|
||||
"successRedirect": "You will be redirected to the settings page shortly."
|
||||
},
|
||||
"developer": {
|
||||
"tokenRefreshed": "Token refreshed successfully",
|
||||
"endpointCalled": "Refresh token endpoint called successfully",
|
||||
"clearDbCleared": "Local offline database cleared. Starting full sync...",
|
||||
"clearDbDone": "Full sync completed from the beginning",
|
||||
"intro": "View technical information about your authentication tokens and session",
|
||||
"refreshCookieNote": "Refresh tokens are managed via HTTP-only cookies on web platform",
|
||||
"noReconnectInfo": "No reconnection information available",
|
||||
"noTimeoutInfo": "No timeout information available",
|
||||
"noDebugInfo": "No debug information available"
|
||||
},
|
||||
"backup": {
|
||||
"keyRequired": "Encryption key is required",
|
||||
"created": "Backup created and downloaded successfully",
|
||||
"createFailed": "Failed to create backup",
|
||||
"selectFile": "Please select a backup file",
|
||||
"restored": "Backup restored successfully. Please refresh the page.",
|
||||
"restoreFailed": "Failed to restore backup",
|
||||
"readFailed": "Failed to read backup file",
|
||||
"createIntro": "Create an encrypted backup of your data. This backup will include all your chores, history, settings, and optionally your uploaded files.",
|
||||
"keyPlaceholder": "Enter a strong encryption key",
|
||||
"includeAssets": "Include uploaded files and assets",
|
||||
"warningLabel": "Warning:",
|
||||
"restoreWarning": "Restoring a backup will replace all your current data. This action cannot be undone.",
|
||||
"restoreKeyPlaceholder": "Enter the encryption key used for this backup"
|
||||
},
|
||||
"deletion": {
|
||||
"passwordRequired": "Please enter your password to continue",
|
||||
"passwordAndDelete": "Please enter your password and type DELETE to confirm",
|
||||
"failed": "Failed to delete account",
|
||||
"passwordPlaceholder": "Enter your password",
|
||||
"transferIntro": "You own circles that require ownership transfer before deletion. Please select new owners:",
|
||||
"selectOwner": "Select new owner",
|
||||
"confirmPrompt": "Please enter your password and type DELETE to confirm",
|
||||
"typeDelete": "DELETE"
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user