Merge branch 'develop' into i18n/regen
This commit is contained in:
@@ -13,8 +13,8 @@ android {
|
||||
applicationId "com.donetick.app"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 66
|
||||
versionName "1.2.45"
|
||||
versionCode 68
|
||||
versionName "1.2.47"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
aaptOptions {
|
||||
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
|
||||
|
||||
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>
|
||||
|
||||
@@ -462,12 +462,12 @@
|
||||
CODE_SIGN_ALLOW_ENTITLEMENTS_MODIFICATION = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = App/App.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 66;
|
||||
CURRENT_PROJECT_VERSION = 68;
|
||||
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.45;
|
||||
MARKETING_VERSION = 1.2.47;
|
||||
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 = 66;
|
||||
CURRENT_PROJECT_VERSION = 68;
|
||||
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.45;
|
||||
MARKETING_VERSION = 1.2.47;
|
||||
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 = 66;
|
||||
CURRENT_PROJECT_VERSION = 68;
|
||||
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.45;
|
||||
MARKETING_VERSION = 1.2.47;
|
||||
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 = 66;
|
||||
CURRENT_PROJECT_VERSION = 68;
|
||||
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.45;
|
||||
MARKETING_VERSION = 1.2.47;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.donetick.app.widget;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
|
||||
121
package-lock.json
generated
121
package-lock.json
generated
@@ -64,6 +64,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",
|
||||
@@ -2322,8 +2323,6 @@
|
||||
},
|
||||
"node_modules/@emotion/cache": {
|
||||
"version": "11.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz",
|
||||
"integrity": "sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@emotion/memoize": "^0.9.0",
|
||||
@@ -4586,6 +4585,31 @@
|
||||
"url": "https://opencollective.com/popperjs"
|
||||
}
|
||||
},
|
||||
"node_modules/@posthog/browser-common": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@posthog/browser-common/-/browser-common-0.5.0.tgz",
|
||||
"integrity": "sha512-8DaxVZS1bQPbA514RePurLNbYjei3P4jhnC206DwVv5XThmZM3QdlsXenI2ujE3pLbgQ79hYn9o1Kda8I3WK/Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@posthog/core": "^1.47.0",
|
||||
"@posthog/types": "^1.402.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@posthog/core": {
|
||||
"version": "1.47.0",
|
||||
"resolved": "https://registry.npmjs.org/@posthog/core/-/core-1.47.0.tgz",
|
||||
"integrity": "sha512-LW62V+9yx7G7mLd+EYpwW0PiaPZI8XRJ1tLuhw+9fXHpugLp8XQD5JuCQ2kIXvoUfyx1DpKfGQY3dUnzMOIn7Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@posthog/types": "^1.402.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@posthog/types": {
|
||||
"version": "1.402.3",
|
||||
"resolved": "https://registry.npmjs.org/@posthog/types/-/types-1.402.3.tgz",
|
||||
"integrity": "sha512-nnqKIGUqggeNbCZg6of/hYN+4shYZUoPFkILIIpYq0p9HDX8PgOrnrtBAUH8kr1MOmDh2nm+fY5Ceks7A5y6BQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@prettier/plugin-xml": {
|
||||
"version": "2.2.0",
|
||||
"dev": true,
|
||||
@@ -7391,6 +7415,20 @@
|
||||
"version": "1.9.0",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/core-js": {
|
||||
"version": "3.50.0",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.50.0.tgz",
|
||||
"integrity": "sha512-BRWgOLKkFeCgRudR6zrs8p9XJZcE14grzKMMssoYrk6krtuEZ7MTKPIY5RzOnqsEKIR9kst7wNzphttraT+Yqw==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/core-js"
|
||||
}
|
||||
},
|
||||
"node_modules/core-js-compat": {
|
||||
"version": "3.45.1",
|
||||
"license": "MIT",
|
||||
@@ -7932,6 +7970,15 @@
|
||||
"url": "https://github.com/fb55/domhandler?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/dompurify": {
|
||||
"version": "3.4.13",
|
||||
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.13.tgz",
|
||||
"integrity": "sha512-2vmYIoqjze2d+kakP8S/nS5shfsl587kzwEjcGlTdiksUVgFHnFCsLYDVj/JNqJVOQZGSYBTmuycv0PodwmnMQ==",
|
||||
"license": "(MPL-2.0 OR Apache-2.0)",
|
||||
"optionalDependencies": {
|
||||
"@types/trusted-types": "^2.0.7"
|
||||
}
|
||||
},
|
||||
"node_modules/domutils": {
|
||||
"version": "2.8.0",
|
||||
"dev": true,
|
||||
@@ -12018,6 +12065,48 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/posthog-js": {
|
||||
"version": "1.415.5",
|
||||
"resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.415.5.tgz",
|
||||
"integrity": "sha512-IUmPFtZjwDZYnRmttl+Xo5f/zDVdMdfWdZFxHqtAqq4wMwElr4dIpXmEUzh4nO8NtWT3zBmrL9+c7zZ3avzJZw==",
|
||||
"license": "(Apache-2.0 AND MIT)",
|
||||
"dependencies": {
|
||||
"@posthog/browser-common": "^0.5.0",
|
||||
"@posthog/core": "^1.47.0",
|
||||
"@posthog/types": "^1.402.3",
|
||||
"core-js": "^3.49.0",
|
||||
"dompurify": "^3.4.13",
|
||||
"fflate": "^0.4.8",
|
||||
"preact": "^10.29.3",
|
||||
"query-selector-shadow-dom": "^1.0.1",
|
||||
"web-vitals": "^5.3.0",
|
||||
"web-vitals-soft-navs": "npm:web-vitals@6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/posthog-js/node_modules/fflate": {
|
||||
"version": "0.4.9",
|
||||
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.4.9.tgz",
|
||||
"integrity": "sha512-zdxgIEddhfsyCaWpJ2SdXEP8ZMrKJ6+5jl4OupODcywU0IhRk6gdXuVGcPICyfx2H97hVK7xmJtRLPjkxAX8Vw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/preact": {
|
||||
"version": "10.29.8",
|
||||
"resolved": "https://registry.npmjs.org/preact/-/preact-10.29.8.tgz",
|
||||
"integrity": "sha512-ej2aVZ+vZ8WO7tvlQWRM9N63A0KzF9q4mWJfDUHgYaIofWY9hu74QdnQrjoPMmZi2/nZ5gN0bJCQF49xQqx09Q==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/preact"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"preact-render-to-string": ">=5"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"preact-render-to-string": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/prebuild-install": {
|
||||
"version": "7.1.3",
|
||||
"devOptional": true,
|
||||
@@ -12402,6 +12491,12 @@
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/query-selector-shadow-dom": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/query-selector-shadow-dom/-/query-selector-shadow-dom-1.0.1.tgz",
|
||||
"integrity": "sha512-lT5yCqEBgfoMYpf3F2xQRK7zEr1rhIIZuceDK6+xRkJQ4NMbHTwXqk4NkwDwQMNqXgG9r9fyHnzwNVs6zV5KRw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/queue-microtask": {
|
||||
"version": "1.2.3",
|
||||
"dev": true,
|
||||
@@ -12466,15 +12561,6 @@
|
||||
"regenerator-runtime": "^0.13.9"
|
||||
}
|
||||
},
|
||||
"node_modules/quilljs-markdown/node_modules/core-js": {
|
||||
"version": "3.45.1",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/core-js"
|
||||
}
|
||||
},
|
||||
"node_modules/raf-schd": {
|
||||
"version": "4.0.3",
|
||||
"license": "MIT"
|
||||
@@ -15262,6 +15348,19 @@
|
||||
"integrity": "sha512-zksaLKM2fVlnB5jQQDqKXXwYHLQUVH9es+5TOOHwGOVJOCeRBCiPjwSg+3tN2AdTCzjgli4jijCH290kXb/zWQ==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/web-vitals": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-5.3.0.tgz",
|
||||
"integrity": "sha512-q6LWsLatGYZp5VGBIOvbTj6JBV2nOmC8KvWztXBmwJcfFAzhwKwbOxhUH306XY3CcaZDUlSmSuNPBsCn0bFu+g==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/web-vitals-soft-navs": {
|
||||
"name": "web-vitals",
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-6.0.0.tgz",
|
||||
"integrity": "sha512-Guaibvy/+uNtL6Bsu4jmMJGzuSl91oeRH5iO9pPRbYftnFUr3yqT1TUNX/OE4o9HexuEMU3Kb/Wg7iKhlffZUA==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"license": "BSD-2-Clause"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "donetick",
|
||||
"private": true,
|
||||
"version": "1.2.45",
|
||||
"version": "1.2.47",
|
||||
"type": "module",
|
||||
"engines": {
|
||||
"node": ">=20.0.0",
|
||||
@@ -96,6 +96,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",
|
||||
|
||||
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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,8 @@
|
||||
"filters": "الفلاتر",
|
||||
"activities": "الأنشطة",
|
||||
"points": "النقاط",
|
||||
"settings": "الإعدادات"
|
||||
"settings": "الإعدادات",
|
||||
"reportBug": "Report a Bug"
|
||||
},
|
||||
"search": {
|
||||
"title": "بحث",
|
||||
@@ -64,11 +65,7 @@
|
||||
"footer": {
|
||||
"navigate": "تنقل",
|
||||
"open": "فتح",
|
||||
"results_zero": "لا توجد نتائج",
|
||||
"results_one": "نتيجة واحدة",
|
||||
"results_two": "نتيجتان",
|
||||
"results_few": "{{count}} نتائج",
|
||||
"results_many": "{{count}} نتيجة",
|
||||
"results_other": "{{count}} نتيجة",
|
||||
"typeToSearch": "اكتب للبحث"
|
||||
}
|
||||
@@ -118,5 +115,37 @@
|
||||
"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"
|
||||
}
|
||||
}
|
||||
@@ -171,7 +171,7 @@
|
||||
"description": "غيّر إعدادات حسابك أو نوع خطتك أو كلمة المرور",
|
||||
"accountType": "نوع الحساب: {{type}}",
|
||||
"free": "مجاني",
|
||||
"plus": "Plus",
|
||||
"plus": "بلس",
|
||||
"plusUntil": "Plus (حتى {{date}})",
|
||||
"activeDescription": "أنت مشترك حاليًا في خطة Plus. سيتجدد اشتراكك في {{date}}.",
|
||||
"cancelledDescription": "لقد ألغيت اشتراكك. سيتم خفض حسابك إلى الخطة المجانية في {{date}}.",
|
||||
@@ -490,5 +490,78 @@
|
||||
"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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,8 @@
|
||||
"filters": "Filter",
|
||||
"activities": "Aktivitäten",
|
||||
"points": "Punkte",
|
||||
"settings": "Einstellungen"
|
||||
"settings": "Einstellungen",
|
||||
"reportBug": "Report a Bug"
|
||||
},
|
||||
"search": {
|
||||
"title": "Suche",
|
||||
@@ -114,5 +115,37 @@
|
||||
"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"
|
||||
}
|
||||
}
|
||||
@@ -490,5 +490,78 @@
|
||||
"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."
|
||||
}
|
||||
@@ -72,7 +72,17 @@
|
||||
"delete": "Delete Session"
|
||||
},
|
||||
"unableUndo": "Failed to undo",
|
||||
"restoreFailed": "Failed to restore"
|
||||
"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",
|
||||
|
||||
@@ -70,6 +70,13 @@
|
||||
"typeToSearch": "Type to search"
|
||||
}
|
||||
},
|
||||
"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",
|
||||
"sentiment": {
|
||||
|
||||
@@ -78,6 +78,10 @@
|
||||
"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."
|
||||
@@ -348,7 +352,8 @@
|
||||
"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",
|
||||
@@ -491,6 +496,15 @@
|
||||
"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",
|
||||
|
||||
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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,8 @@
|
||||
"filters": "Filtros",
|
||||
"activities": "Actividades",
|
||||
"points": "Puntos",
|
||||
"settings": "Configuración"
|
||||
"settings": "Configuración",
|
||||
"reportBug": "Report a Bug"
|
||||
},
|
||||
"search": {
|
||||
"title": "Buscar",
|
||||
@@ -114,5 +115,37 @@
|
||||
"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"
|
||||
}
|
||||
}
|
||||
@@ -490,5 +490,78 @@
|
||||
"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."
|
||||
}
|
||||
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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,8 @@
|
||||
"filters": "Filtres",
|
||||
"activities": "Activités",
|
||||
"points": "Points",
|
||||
"settings": "Paramètres"
|
||||
"settings": "Paramètres",
|
||||
"reportBug": "Report a Bug"
|
||||
},
|
||||
"search": {
|
||||
"title": "Recherche",
|
||||
@@ -44,7 +45,7 @@
|
||||
},
|
||||
"groups": {
|
||||
"tasks": "Tâches",
|
||||
"history": "Notes",
|
||||
"history": "Remarques",
|
||||
"projects": "Projets",
|
||||
"labels": "Étiquettes",
|
||||
"people": "Personnes",
|
||||
@@ -70,49 +71,81 @@
|
||||
}
|
||||
},
|
||||
"feedback": {
|
||||
"later": "Maybe later",
|
||||
"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": "Love it",
|
||||
"okay": "It's okay",
|
||||
"issues": "Having issues"
|
||||
"love": "J'adore",
|
||||
"okay": "C'est ok",
|
||||
"issues": "Problèmes rencontrés"
|
||||
}
|
||||
},
|
||||
"categories": {
|
||||
"bugs": "Bugs",
|
||||
"missingFeature": "Missing feature",
|
||||
"tooComplicated": "Too complicated",
|
||||
"slow": "Slow",
|
||||
"bugs": "Anomalies",
|
||||
"missingFeature": "Fonctionnalités manquantes",
|
||||
"tooComplicated": "Trop compliqué",
|
||||
"slow": "Lent",
|
||||
"notifications": "Notifications",
|
||||
"ai": "AI",
|
||||
"other": "Other"
|
||||
"ai": "IA",
|
||||
"other": "Autres"
|
||||
},
|
||||
"details": {
|
||||
"title": "What could we improve?",
|
||||
"messageLabel": "Tell us more",
|
||||
"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": "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"
|
||||
"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": "Glad you're enjoying it!",
|
||||
"title": "Nous sommes ravis que vous l'appréciez !",
|
||||
"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"
|
||||
"github": "Mettez une étoile sur GitHub",
|
||||
"appStore": "Évaluer sur l'App Store",
|
||||
"playStore": "Évaluer sur Google Play"
|
||||
},
|
||||
"thanks": {
|
||||
"title": "Thanks for the feedback",
|
||||
"title": "Merci pour votre retour",
|
||||
"subtitle": "We read every response and it shapes what we work on next."
|
||||
},
|
||||
"github": {
|
||||
"title": "Report it on 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": "Open the issue"
|
||||
"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"
|
||||
}
|
||||
}
|
||||
@@ -490,5 +490,78 @@
|
||||
"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"
|
||||
}
|
||||
}
|
||||
|
||||
18
public/locales/fr/things.json
Normal file
18
public/locales/fr/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/fr/timer.json
Normal file
29
public/locales/fr/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/ja/auth.json
Normal file
111
public/locales/ja/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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,8 @@
|
||||
"filters": "フィルター",
|
||||
"activities": "アクティビティ",
|
||||
"points": "ポイント",
|
||||
"settings": "設定"
|
||||
"settings": "設定",
|
||||
"reportBug": "Report a Bug"
|
||||
},
|
||||
"search": {
|
||||
"title": "検索",
|
||||
@@ -64,6 +65,7 @@
|
||||
"footer": {
|
||||
"navigate": "移動",
|
||||
"open": "開く",
|
||||
"results_one": "{{count}} result",
|
||||
"results_other": "{{count}} 件の結果",
|
||||
"typeToSearch": "入力して検索"
|
||||
}
|
||||
@@ -113,5 +115,37 @@
|
||||
"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/ja/filters.json
Normal file
17
public/locales/ja/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/ja/history.json
Normal file
89
public/locales/ja/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/ja/labels.json
Normal file
9
public/locales/ja/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/ja/points.json
Normal file
74
public/locales/ja/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/ja/projects.json
Normal file
24
public/locales/ja/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"
|
||||
}
|
||||
}
|
||||
@@ -490,5 +490,78 @@
|
||||
"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/ja/things.json
Normal file
18
public/locales/ja/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/ja/timer.json
Normal file
29
public/locales/ja/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/nl/auth.json
Normal file
111
public/locales/nl/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 Resetten",
|
||||
"delete": "Sessie Verwijderen"
|
||||
}
|
||||
},
|
||||
"toolbar": {
|
||||
"defaultProject": "Default Project"
|
||||
},
|
||||
"sort": {
|
||||
"assignedToMe": "Assigned to me"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,8 @@
|
||||
"filters": "Filters",
|
||||
"activities": "Activiteiten",
|
||||
"points": "Punten",
|
||||
"settings": "Instellingen"
|
||||
"settings": "Instellingen",
|
||||
"reportBug": "Report a Bug"
|
||||
},
|
||||
"search": {
|
||||
"title": "Zoeken",
|
||||
@@ -114,5 +115,37 @@
|
||||
"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/nl/filters.json
Normal file
17
public/locales/nl/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/nl/history.json
Normal file
89
public/locales/nl/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/nl/labels.json
Normal file
9
public/locales/nl/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/nl/points.json
Normal file
74
public/locales/nl/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/nl/projects.json
Normal file
24
public/locales/nl/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"
|
||||
}
|
||||
}
|
||||
@@ -490,5 +490,78 @@
|
||||
"notConnected": "Realtime-updates staan aan maar er is momenteel geen verbinding.",
|
||||
"basicPlanNotice": "Realtime-updates zijn niet beschikbaar in het basisabonnement. Upgrade naar Plus om direct meldingen te ontvangen wanneer jij of andere circle-leden taken afronden, overslaan of wijzigen."
|
||||
}
|
||||
},
|
||||
"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/nl/things.json
Normal file
18
public/locales/nl/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/nl/timer.json
Normal file
29
public/locales/nl/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/pt/auth.json
Normal file
111
public/locales/pt/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 cronômetro",
|
||||
"delete": "Excluir sessão"
|
||||
}
|
||||
},
|
||||
"toolbar": {
|
||||
"defaultProject": "Default Project"
|
||||
},
|
||||
"sort": {
|
||||
"assignedToMe": "Assigned to me"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,8 @@
|
||||
"filters": "Filtros",
|
||||
"activities": "Atividades",
|
||||
"points": "Pontos",
|
||||
"settings": "Configurações"
|
||||
"settings": "Configurações",
|
||||
"reportBug": "Report a Bug"
|
||||
},
|
||||
"search": {
|
||||
"title": "Pesquisar",
|
||||
@@ -114,5 +115,37 @@
|
||||
"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/pt/filters.json
Normal file
17
public/locales/pt/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/pt/history.json
Normal file
89
public/locales/pt/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/pt/labels.json
Normal file
9
public/locales/pt/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/pt/points.json
Normal file
74
public/locales/pt/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/pt/projects.json
Normal file
24
public/locales/pt/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"
|
||||
}
|
||||
}
|
||||
@@ -490,5 +490,78 @@
|
||||
"notConnected": "As atualizações em tempo real estão ativadas, mas não há conexão no momento.",
|
||||
"basicPlanNotice": "As atualizações em tempo real não estão disponíveis no plano Básico. Mude para o Plus para receber notificações instantâneas quando você ou outros membros do círculo concluírem, pularem ou modificarem tarefas."
|
||||
}
|
||||
},
|
||||
"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/pt/things.json
Normal file
18
public/locales/pt/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/pt/timer.json
Normal file
29
public/locales/pt/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/zh/auth.json
Normal file
111
public/locales/zh/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": "Reset Timer",
|
||||
"delete": "Delete Session"
|
||||
}
|
||||
},
|
||||
"toolbar": {
|
||||
"defaultProject": "Default Project"
|
||||
},
|
||||
"sort": {
|
||||
"assignedToMe": "Assigned to me"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,8 @@
|
||||
"filters": "Filters",
|
||||
"activities": "Activities",
|
||||
"points": "Points",
|
||||
"settings": "Settings"
|
||||
"settings": "Settings",
|
||||
"reportBug": "Report a Bug"
|
||||
},
|
||||
"search": {
|
||||
"title": "搜索",
|
||||
@@ -114,5 +115,37 @@
|
||||
"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/zh/filters.json
Normal file
17
public/locales/zh/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/zh/history.json
Normal file
89
public/locales/zh/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/zh/labels.json
Normal file
9
public/locales/zh/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/zh/points.json
Normal file
74
public/locales/zh/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/zh/projects.json
Normal file
24
public/locales/zh/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"
|
||||
}
|
||||
}
|
||||
@@ -490,5 +490,78 @@
|
||||
"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/zh/things.json
Normal file
18
public/locales/zh/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/zh/timer.json
Normal file
29
public/locales/zh/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."
|
||||
}
|
||||
11
src/App.jsx
11
src/App.jsx
@@ -7,6 +7,11 @@ import { useRegisterSW } from 'virtual:pwa-register/react'
|
||||
|
||||
import NavBar from '@/views/components/NavBar'
|
||||
|
||||
import {
|
||||
initialize as initializeAnalytics,
|
||||
installGlobalErrorHandlers,
|
||||
} from './analytics'
|
||||
import useAnalyticsIdentity from './analytics/useAnalyticsIdentity'
|
||||
import { registerCapacitorListeners } from './CapacitorListener'
|
||||
import PageTransition from './components/animations/PageTransition'
|
||||
import { ImpersonateUserProvider } from './contexts/ImpersonateUserContext'
|
||||
@@ -36,6 +41,7 @@ const AppContent = () => {
|
||||
const { showNotification } = useNotification()
|
||||
const location = useLocation()
|
||||
useSyncOnReconnect()
|
||||
useAnalyticsIdentity()
|
||||
|
||||
// Every route renders through this Outlet, so one listener here gives crash
|
||||
// reports the trail that led to the failure.
|
||||
@@ -142,6 +148,11 @@ function App() {
|
||||
registerCapacitorListeners(navigate)
|
||||
}, [navigate])
|
||||
|
||||
useEffect(() => {
|
||||
initializeAnalytics()
|
||||
installGlobalErrorHandlers()
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div>
|
||||
<NetworkBanner />
|
||||
|
||||
@@ -23,6 +23,9 @@ const AppRedirect = () => {
|
||||
|
||||
const router = createBrowserRouter([
|
||||
{ path: '/', element: <Landing /> },
|
||||
// Mirrors the app router, where /welcome is the canonical Landing path —
|
||||
// without it this falls through to AppRedirect and bounces to /login.
|
||||
{ path: '/welcome', element: <Landing /> },
|
||||
{ path: '/privacy', element: <PrivacyPolicyView /> },
|
||||
{ path: '/terms', element: <TermsView /> },
|
||||
{ path: '*', element: <AppRedirect /> },
|
||||
@@ -50,17 +53,20 @@ const ThemeClass = () => {
|
||||
return null
|
||||
}
|
||||
|
||||
// Same ordering constraint as contexts/Contexts.jsx: ThemeContext reads the
|
||||
// active language via useLocalization() to pick the text direction, so
|
||||
// LocalizationProvider has to sit above it.
|
||||
const MarketingApp = () => (
|
||||
<ThemeContext>
|
||||
<ThemeClass />
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<LocalizationProvider>
|
||||
<LocalizationProvider>
|
||||
<ThemeContext>
|
||||
<ThemeClass />
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<ImpersonateUserProvider>
|
||||
<RouterProvider router={router} />
|
||||
</ImpersonateUserProvider>
|
||||
</LocalizationProvider>
|
||||
</QueryClientProvider>
|
||||
</ThemeContext>
|
||||
</QueryClientProvider>
|
||||
</ThemeContext>
|
||||
</LocalizationProvider>
|
||||
)
|
||||
|
||||
export default MarketingApp
|
||||
|
||||
107
src/analytics/consent.js
Normal file
107
src/analytics/consent.js
Normal file
@@ -0,0 +1,107 @@
|
||||
import { Preferences } from '@capacitor/preferences'
|
||||
|
||||
// Two independent consent axes, matching the existing onboarding UI
|
||||
// (HeardAboutView's PrivacyPreferences): "analytics" gates track(), "crash"
|
||||
// gates captureError(). A self-hosted user can opt into one without the other.
|
||||
const CONSENT_KEYS = {
|
||||
analytics: 'analytics_consent',
|
||||
crash: 'analytics_crash_consent',
|
||||
}
|
||||
|
||||
const ANON_ID_KEY = 'analytics_anon_id'
|
||||
const INSTALLATION_ID_KEY = 'analytics_installation_id'
|
||||
|
||||
const generateUUID = () => {
|
||||
if (typeof crypto !== 'undefined' && crypto.randomUUID) {
|
||||
return crypto.randomUUID()
|
||||
}
|
||||
// Fallback for webviews without crypto.randomUUID — not cryptographically
|
||||
// strong, but this identifier carries no user information either way.
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
|
||||
const r = (Math.random() * 16) | 0
|
||||
const v = c === 'x' ? r : (r & 0x3) | 0x8
|
||||
return v.toString(16)
|
||||
})
|
||||
}
|
||||
|
||||
const readPreference = async key => {
|
||||
try {
|
||||
const { value } = await Preferences.get({ key })
|
||||
return value ?? null
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
const writePreference = async (key, value) => {
|
||||
try {
|
||||
await Preferences.set({ key, value })
|
||||
} catch {
|
||||
// best-effort; consent falls back to 'unknown' on next read
|
||||
}
|
||||
}
|
||||
|
||||
const removePreference = async key => {
|
||||
try {
|
||||
await Preferences.remove({ key })
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
export const getStoredConsent = async kind => {
|
||||
const value = await readPreference(CONSENT_KEYS[kind])
|
||||
return value === 'enabled' || value === 'disabled' ? value : 'unknown'
|
||||
}
|
||||
|
||||
export const setStoredConsent = (kind, value) =>
|
||||
writePreference(CONSENT_KEYS[kind], value)
|
||||
|
||||
/**
|
||||
* Self-hosted `unknown` behaves as disabled (opt-in required); cloud
|
||||
* `unknown` behaves as enabled (opt-out available). Nothing is persisted by
|
||||
* this resolution alone — only an explicit setConsent() call writes a value.
|
||||
*/
|
||||
export const resolveEffectiveConsent = (stored, deploymentType) => {
|
||||
if (stored === 'enabled' || stored === 'disabled') return stored
|
||||
return deploymentType === 'cloud' ? 'enabled' : 'disabled'
|
||||
}
|
||||
|
||||
export const getOrCreateAnonId = async () => {
|
||||
const existing = await readPreference(ANON_ID_KEY)
|
||||
if (existing) return existing
|
||||
const created = generateUUID()
|
||||
await writePreference(ANON_ID_KEY, created)
|
||||
return created
|
||||
}
|
||||
|
||||
export const getOrCreateInstallationId = async () => {
|
||||
const existing = await readPreference(INSTALLATION_ID_KEY)
|
||||
if (existing) return existing
|
||||
const created = generateUUID()
|
||||
await writePreference(INSTALLATION_ID_KEY, created)
|
||||
return created
|
||||
}
|
||||
|
||||
/**
|
||||
* Cloud + known user -> identify by the Donetick user id. Self-hosted (or
|
||||
* cloud pre-login) -> a random id containing no user information, never
|
||||
* derived from email/username/database id.
|
||||
*/
|
||||
export const resolveIdentity = async ({ deploymentType, userId }) => {
|
||||
if (deploymentType === 'cloud' && userId) {
|
||||
return { distinctId: String(userId), installationId: null }
|
||||
}
|
||||
const [anonId, installationId] = await Promise.all([
|
||||
getOrCreateAnonId(),
|
||||
deploymentType === 'cloud' ? null : getOrCreateInstallationId(),
|
||||
])
|
||||
return { distinctId: anonId, installationId }
|
||||
}
|
||||
|
||||
export const clearAnonymousIdentity = async () => {
|
||||
await Promise.all([
|
||||
removePreference(ANON_ID_KEY),
|
||||
removePreference(INSTALLATION_ID_KEY),
|
||||
])
|
||||
}
|
||||
165
src/analytics/eventSchemas.js
Normal file
165
src/analytics/eventSchemas.js
Normal file
@@ -0,0 +1,165 @@
|
||||
// Every event has an explicit property allowlist. Unknown events are
|
||||
// dropped entirely; unknown or mistyped properties are dropped individually.
|
||||
// This is the mechanism (not just a convention) that keeps user-generated
|
||||
// content and PII out of PostHog — see spec.md sections 2, 14, 22.
|
||||
|
||||
// Attached to every event so cohort analysis (e.g. "do Plus accounts behave
|
||||
// differently") works without every call site having to pass them.
|
||||
const COMMON_PROPS = {
|
||||
is_plus_account: 'boolean',
|
||||
circle_member_count: 'number',
|
||||
}
|
||||
|
||||
const withCommon = props => ({ ...props, ...COMMON_PROPS })
|
||||
|
||||
export const EVENT_SCHEMAS = {
|
||||
onboarding_started: withCommon({}),
|
||||
onboarding_completed: withCommon({}),
|
||||
onboarding_skipped: withCommon({}),
|
||||
onboarding_option_selected: withCommon({
|
||||
option: 'string',
|
||||
step: 'string',
|
||||
}),
|
||||
|
||||
chore_created: withCommon({
|
||||
has_due_date: 'boolean',
|
||||
has_assignee: 'boolean',
|
||||
has_labels: 'boolean',
|
||||
has_description: 'boolean',
|
||||
has_recurrence: 'boolean',
|
||||
recurrence_type: 'string',
|
||||
priority: 'number',
|
||||
// quick_add/voice/scan = the AddTaskModal popup; full_page/clone = the
|
||||
// dedicated create page (ChoreEdit.jsx with no existing chore id).
|
||||
source: 'enum:quick_add,voice,scan,full_page,clone',
|
||||
}),
|
||||
chore_updated: withCommon({
|
||||
has_due_date: 'boolean',
|
||||
has_assignee: 'boolean',
|
||||
has_labels: 'boolean',
|
||||
has_description: 'boolean',
|
||||
has_recurrence: 'boolean',
|
||||
recurrence_type: 'string',
|
||||
priority: 'number',
|
||||
}),
|
||||
|
||||
thing_created: withCommon({}),
|
||||
project_created: withCommon({}),
|
||||
filter_created: withCommon({}),
|
||||
|
||||
localization_setting_changed: withCommon({
|
||||
setting: 'enum:language,date_format,time_format,first_day_of_week',
|
||||
value: 'string',
|
||||
}),
|
||||
|
||||
analytics_enabled: withCommon({
|
||||
source: 'enum:onboarding,settings',
|
||||
}),
|
||||
|
||||
feedback_prompt_shown: withCommon({
|
||||
source: 'enum:auto,settings',
|
||||
shown_count: 'number',
|
||||
}),
|
||||
feedback_prompt_dismissed: withCommon({
|
||||
source: 'enum:auto,settings',
|
||||
shown_count: 'number',
|
||||
}),
|
||||
feedback_sentiment_selected: withCommon({
|
||||
sentiment: 'enum:love,okay,issues',
|
||||
}),
|
||||
feedback_review_action: withCommon({
|
||||
action: 'enum:github,appStore,playStore',
|
||||
}),
|
||||
feedback_submitted: withCommon({
|
||||
category:
|
||||
'enum:bugs,missingFeature,tooComplicated,slow,notifications,ai,other',
|
||||
has_message: 'boolean',
|
||||
result: 'enum:sent,failed,unconfigured,misconfigured,self-hosted',
|
||||
}),
|
||||
}
|
||||
|
||||
export const ERROR_SCHEMAS = {
|
||||
api_error: {
|
||||
http_status: 'string',
|
||||
method: 'string',
|
||||
error_code: 'string',
|
||||
operation: 'string',
|
||||
},
|
||||
// No message/stack field here by design — those come from the real Error
|
||||
// object passed to posthog.captureException() itself, not from this
|
||||
// sanitized properties bag. This schema only classifies how it was caught.
|
||||
frontend_error: {
|
||||
source: 'enum:window_error,unhandled_rejection',
|
||||
},
|
||||
}
|
||||
|
||||
const MAX_STRING_LENGTH = 200
|
||||
// Defense in depth: operation/endpoint-like strings must never carry a query
|
||||
// string even though callers are expected to have already stripped one.
|
||||
const containsQueryOrDisallowedChars = value => /[?&=]/.test(value)
|
||||
|
||||
const isValidValue = (value, type) => {
|
||||
if (value === null || value === undefined) return false
|
||||
|
||||
if (type === 'boolean') return typeof value === 'boolean'
|
||||
if (type === 'number') return typeof value === 'number' && !isNaN(value)
|
||||
|
||||
if (type.startsWith('enum:')) {
|
||||
const allowed = type.slice('enum:'.length).split(',')
|
||||
return typeof value === 'string' && allowed.includes(value)
|
||||
}
|
||||
|
||||
if (type === 'string') {
|
||||
return (
|
||||
typeof value === 'string' &&
|
||||
value.length <= MAX_STRING_LENGTH &&
|
||||
!containsQueryOrDisallowedChars(value)
|
||||
)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops the whole event if its name isn't recognized, then drops any
|
||||
* property that isn't in the schema or fails its type/enum check. Never
|
||||
* throws — a malformed call site loses data, it never crashes the app.
|
||||
*/
|
||||
export const sanitizeProperties = (schemas, eventName, properties = {}) => {
|
||||
const schema = schemas[eventName]
|
||||
if (!schema) {
|
||||
if (import.meta.env.DEV) {
|
||||
console.warn(`analytics: unknown event "${eventName}", dropping`)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
const sanitized = {}
|
||||
for (const [key, value] of Object.entries(properties || {})) {
|
||||
const type = schema[key]
|
||||
if (!type) {
|
||||
if (import.meta.env.DEV) {
|
||||
console.warn(
|
||||
`analytics: dropping unknown property "${key}" on "${eventName}"`,
|
||||
)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if (!isValidValue(value, type)) {
|
||||
if (import.meta.env.DEV) {
|
||||
console.warn(
|
||||
`analytics: dropping invalid property "${key}" on "${eventName}"`,
|
||||
)
|
||||
}
|
||||
continue
|
||||
}
|
||||
sanitized[key] = value
|
||||
}
|
||||
return sanitized
|
||||
}
|
||||
|
||||
export const sanitizeEventProperties = (eventName, properties) =>
|
||||
sanitizeProperties(EVENT_SCHEMAS, eventName, properties)
|
||||
|
||||
export const sanitizeErrorProperties = (errorType, properties) =>
|
||||
sanitizeProperties(ERROR_SCHEMAS, errorType, properties)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user