mirror of
https://github.com/kyantech/Palmr.git
synced 2025-10-23 06:11:58 +00:00
feat: add initial project setup with config, models, and assets
This commit introduces the initial project setup including configuration files, API models, and necessary assets. The changes include: - Added Prettier and PostCSS configuration files - Included favicon and public assets like SVGs - Set up Next.js and theme provider configurations - Added TypeScript models for API endpoints and responses
This commit is contained in:
41
apps/app/.gitignore
vendored
Normal file
41
apps/app/.gitignore
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.*
|
||||
.yarn/*
|
||||
!.yarn/patches
|
||||
!.yarn/plugins
|
||||
!.yarn/releases
|
||||
!.yarn/versions
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# next.js
|
||||
/.next/
|
||||
/out/
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
*.pem
|
||||
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# env files (can opt-in for committing if needed)
|
||||
.env*
|
||||
|
||||
# vercel
|
||||
.vercel
|
||||
|
||||
# typescript
|
||||
*.tsbuildinfo
|
||||
next-env.d.ts
|
4
apps/app/.prettierignore
Normal file
4
apps/app/.prettierignore
Normal file
@@ -0,0 +1,4 @@
|
||||
/node_modules
|
||||
/.next
|
||||
/out
|
||||
/build
|
16
apps/app/.prettierrc.json
Normal file
16
apps/app/.prettierrc.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"printWidth": 120,
|
||||
"singleQuote": false,
|
||||
"tabWidth": 2,
|
||||
"trailingComma": "es5",
|
||||
"plugins": ["@ianvs/prettier-plugin-sort-imports", "prettier-plugin-sort-json"],
|
||||
"importOrder": [
|
||||
"^(react/(.*)$)|^(react$)",
|
||||
"^(next/(.*)$)|^(next$)",
|
||||
"<THIRD_PARTY_MODULES>",
|
||||
"",
|
||||
"^@/(.*)$",
|
||||
"^[./]"
|
||||
],
|
||||
"importOrderParserPlugins": ["typescript", "jsx", "decorators-legacy"]
|
||||
}
|
21
apps/app/components.json
Normal file
21
apps/app/components.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema.json",
|
||||
"style": "new-york",
|
||||
"rsc": true,
|
||||
"tsx": true,
|
||||
"tailwind": {
|
||||
"config": "",
|
||||
"css": "src/app/globals.css",
|
||||
"baseColor": "neutral",
|
||||
"cssVariables": true,
|
||||
"prefix": ""
|
||||
},
|
||||
"aliases": {
|
||||
"components": "@/components",
|
||||
"utils": "@/lib/utils",
|
||||
"ui": "@/components/ui",
|
||||
"lib": "@/lib",
|
||||
"hooks": "@/hooks"
|
||||
},
|
||||
"iconLibrary": "lucide"
|
||||
}
|
66
apps/app/eslint.config.mjs
Normal file
66
apps/app/eslint.config.mjs
Normal file
@@ -0,0 +1,66 @@
|
||||
/* eslint-disable import/no-anonymous-default-export */
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { FlatCompat } from "@eslint/eslintrc";
|
||||
import js from "@eslint/js";
|
||||
import typescriptEslintEslintPlugin from "@typescript-eslint/eslint-plugin";
|
||||
import tsParser from "@typescript-eslint/parser";
|
||||
import prettier from "eslint-plugin-prettier";
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
const compat = new FlatCompat({
|
||||
baseDirectory: __dirname,
|
||||
recommendedConfig: js.configs.recommended,
|
||||
allConfig: js.configs.all,
|
||||
});
|
||||
|
||||
export default [
|
||||
...compat.extends("next", "next/core-web-vitals", "prettier"),
|
||||
{
|
||||
plugins: {
|
||||
prettier,
|
||||
},
|
||||
rules: {
|
||||
"prettier/prettier": "error",
|
||||
camelcase: "off",
|
||||
"import/prefer-default-export": "off",
|
||||
"react/jsx-filename-extension": "off",
|
||||
"react/jsx-props-no-spreading": "off",
|
||||
"react/no-unused-prop-types": "off",
|
||||
"react/require-default-props": "off",
|
||||
"react/no-unescaped-entities": "off",
|
||||
"import/extensions": [
|
||||
"error",
|
||||
"ignorePackages",
|
||||
{
|
||||
ts: "never",
|
||||
tsx: "never",
|
||||
js: "never",
|
||||
jsx: "never",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
...compat.extends("plugin:@typescript-eslint/recommended", "prettier").map((config) => ({
|
||||
...config,
|
||||
files: ["**/*.+(ts|tsx)"],
|
||||
})),
|
||||
{
|
||||
files: ["**/*.+(ts|tsx)"],
|
||||
plugins: {
|
||||
"@typescript-eslint": typescriptEslintEslintPlugin,
|
||||
},
|
||||
languageOptions: {
|
||||
parser: tsParser,
|
||||
},
|
||||
rules: {
|
||||
"@typescript-eslint/explicit-function-return-type": "off",
|
||||
"@typescript-eslint/explicit-module-boundary-types": "off",
|
||||
"no-use-before-define": [0],
|
||||
"@typescript-eslint/no-use-before-define": [1],
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/no-var-requires": "off",
|
||||
},
|
||||
},
|
||||
];
|
638
apps/app/messages/ar-SA.json
Normal file
638
apps/app/messages/ar-SA.json
Normal file
@@ -0,0 +1,638 @@
|
||||
{
|
||||
"login": {
|
||||
"welcome": "مرحبا بك",
|
||||
"signInToContinue": "قم بتسجيل الدخول للمتابعة",
|
||||
"emailLabel": "البريد الإلكتروني",
|
||||
"emailPlaceholder": "أدخل بريدك الإلكتروني",
|
||||
"passwordLabel": "كلمة المرور",
|
||||
"passwordPlaceholder": "أدخل كلمة المرور",
|
||||
"signIn": "تسجيل الدخول",
|
||||
"signingIn": "جاري تسجيل الدخول...",
|
||||
"forgotPassword": "نسيت كلمة المرور؟",
|
||||
"pageTitle": "تسجيل الدخول"
|
||||
},
|
||||
"errors": {
|
||||
"invalidCredentials": "بريد إلكتروني أو كلمة مرور غير صحيحة",
|
||||
"userNotFound": "المستخدم غير موجود",
|
||||
"accountLocked": "تم قفل الحساب. يرجى المحاولة لاحقًا",
|
||||
"unexpectedError": "حدث خطأ غير متوقع. يرجى المحاولة مرة أخرى"
|
||||
},
|
||||
"validation": {
|
||||
"invalidEmail": "عنوان بريد إلكتروني غير صالح",
|
||||
"passwordMinLength": "يجب أن تحتوي كلمة المرور على 6 أحرف على الأقل",
|
||||
"firstNameRequired": "الاسم الأول مطلوب",
|
||||
"lastNameRequired": "اسم العائلة مطلوب",
|
||||
"usernameLength": "يجب أن يحتوي اسم المستخدم على 3 أحرف على الأقل",
|
||||
"usernameSpaces": "لا يمكن أن يحتوي اسم المستخدم على فراغات",
|
||||
"passwordLength": "يجب أن تحتوي كلمة المرور على 8 أحرف على الأقل",
|
||||
"passwordsMatch": "كلمتا المرور غير متطابقتين",
|
||||
"emailRequired": "البريد الإلكتروني مطلوب",
|
||||
"passwordRequired": "كلمة المرور مطلوبة"
|
||||
},
|
||||
"fileSelector": {
|
||||
"availableFiles": "الملفات المتاحة ({{count}})",
|
||||
"shareFiles": "مشاركة الملفات ({{count}})",
|
||||
"searchPlaceholder": "ابحث عن الملفات...",
|
||||
"noMatchingFiles": "لا توجد ملفات مطابقة",
|
||||
"noAvailableFiles": "لا توجد ملفات متاحة",
|
||||
"noFilesInShare": "لا توجد ملفات للمشاركة",
|
||||
"saveChanges": "احفظ التغييرات"
|
||||
},
|
||||
"recipientSelector": {
|
||||
"emailPlaceholder": "أدخل بريد المستلم الإلكتروني",
|
||||
"add": "أضف",
|
||||
"recipients": "المستلمون ({{count}})",
|
||||
"notifyAll": "أبلغ الجميع",
|
||||
"noRecipients": "لم يتم إضافة أي مستلمين بعد",
|
||||
"addSuccess": "تم إضافة المستلم بنجاح",
|
||||
"addError": "فشل في إضافة المستلم",
|
||||
"removeSuccess": "تم إزالة المستلم بنجاح",
|
||||
"removeError": "فشل في إزالة المستلم",
|
||||
"sendingNotifications": "جاري إرسال الإشعارات...",
|
||||
"notifySuccess": "تم إعلام المستلمين بنجاح",
|
||||
"notifyError": "فشل في إعلام المستلمين"
|
||||
},
|
||||
"navigation": {
|
||||
"dashboard": "لوحة التحكم"
|
||||
},
|
||||
"common": {
|
||||
"loading": "جاري التحميل، يرجى الانتظار...",
|
||||
"cancel": "إلغاء",
|
||||
"save": "حفظ",
|
||||
"delete": "حذف",
|
||||
"close": "إغلاق",
|
||||
"download": "تنزيل",
|
||||
"unexpectedError": "حدث خطأ غير متوقع. يرجى المحاولة مرة أخرى.",
|
||||
"yes": "نعم",
|
||||
"no": "لا",
|
||||
"dashboard": "لوحة التحكم"
|
||||
},
|
||||
"createShare": {
|
||||
"title": "إنشاء مشاركة",
|
||||
"nameLabel": "اسم المشاركة",
|
||||
"expirationLabel": "تاريخ الانتهاء",
|
||||
"expirationPlaceholder": "MM/DD/YYYY HH:MM",
|
||||
"maxViewsLabel": "أقصى عدد للمشاهدات",
|
||||
"maxViewsPlaceholder": "اتركه فارغاً للمحدودية غير المحدودة",
|
||||
"passwordProtection": "حماية بكلمة المرور",
|
||||
"passwordLabel": "كلمة المرور",
|
||||
"create": "إنشاء المشاركة",
|
||||
"success": "تم إنشاء المشاركة بنجاح",
|
||||
"error": "فشل في إنشاء المشاركة"
|
||||
},
|
||||
"fileActions": {
|
||||
"editFile": "تعديل الملف",
|
||||
"nameLabel": "الاسم",
|
||||
"namePlaceholder": "أدخل اسمًا جديدًا",
|
||||
"extension": "الامتداد",
|
||||
"descriptionLabel": "الوصف",
|
||||
"descriptionPlaceholder": "أدخل وصف الملف",
|
||||
"deleteFile": "حذف الملف",
|
||||
"deleteConfirmation": "هل أنت متأكد أنك تريد حذف \"{{fileName}}\"؟",
|
||||
"deleteWarning": "هذا الإجراء لا يمكن التراجع عنه."
|
||||
},
|
||||
"filePreview": {
|
||||
"loading": "جاري تحميل المعاينة...",
|
||||
"notAvailable": "المعاينة غير متوفرة",
|
||||
"downloadToView": "قم بتنزيل الملف لعرض المحتوى",
|
||||
"audioNotSupported": "المتصفح لا يدعم عنصر الصوت",
|
||||
"videoNotSupported": "المتصفح لا يدعم عنصر الفيديو",
|
||||
"loadError": "فشل في تحميل المعاينة",
|
||||
"downloadError": "فشل في تنزيل الملف"
|
||||
},
|
||||
"generateShareLink": {
|
||||
"generateTitle": "إنشاء رابط المشاركة",
|
||||
"updateTitle": "تحديث رابط المشاركة",
|
||||
"generateDescription": "أنشئ رابطاً لمشاركة ملفاتك",
|
||||
"updateDescription": "قم بتحديث اللقب لهذا الرابط",
|
||||
"aliasPlaceholder": "أدخل لقبًا",
|
||||
"linkReady": "رابط المشاركة جاهز:",
|
||||
"generateButton": "إنشاء الرابط",
|
||||
"updateButton": "تحديث الرابط",
|
||||
"copyButton": "نسخ الرابط",
|
||||
"success": "تم إنشاء الرابط بنجاح",
|
||||
"error": "فشل في إنشاء الرابط",
|
||||
"copied": "تم نسخ الرابط إلى الحافظة"
|
||||
},
|
||||
"shareActions": {
|
||||
"deleteTitle": "حذف المشاركة",
|
||||
"deleteConfirmation": "هل أنت متأكد من رغبتك في حذف هذه المشاركة؟ هذا الإجراء لا يمكن التراجع عنه.",
|
||||
"editTitle": "تعديل المشاركة",
|
||||
"nameLabel": "اسم المشاركة",
|
||||
"expirationLabel": "تاريخ الانتهاء",
|
||||
"expirationPlaceholder": "MM/DD/YYYY HH:MM",
|
||||
"maxViewsLabel": "أقصى عدد للمشاهدات",
|
||||
"maxViewsPlaceholder": "اتركه فارغاً للمحدودية غير المحدودة",
|
||||
"passwordProtection": "محمي بكلمة المرور",
|
||||
"passwordLabel": "كلمة المرور",
|
||||
"passwordPlaceholder": "أدخل كلمة المرور",
|
||||
"newPasswordLabel": "كلمة مرور جديدة (اتركه فارغاً للاحتفاظ بالحالي)",
|
||||
"newPasswordPlaceholder": "أدخل كلمة مرور جديدة",
|
||||
"manageFilesTitle": "إدارة الملفات",
|
||||
"manageRecipientsTitle": "إدارة المستلمين",
|
||||
"editSuccess": "تم تحديث المشاركة بنجاح",
|
||||
"editError": "فشل في تحديث المشاركة"
|
||||
},
|
||||
"shareDetails": {
|
||||
"title": "تفاصيل المشاركة",
|
||||
"subtitle": "معلومات مفصلة عن هذه المشاركة",
|
||||
"basicInfo": "المعلومات الأساسية",
|
||||
"name": "الاسم",
|
||||
"untitled": "بدون عنوان",
|
||||
"views": "المشاهدات",
|
||||
"dates": "التواريخ",
|
||||
"created": "تم الإنشاء",
|
||||
"expires": "تنتهي",
|
||||
"never": "أبدًا",
|
||||
"security": "الأمان",
|
||||
"passwordProtected": "محمي بكلمة المرور",
|
||||
"publicAccess": "الوصول العام",
|
||||
"maxViews": "أقصى عدد للمشاهدات: {{count}}",
|
||||
"files": "الملفات ({{count}})",
|
||||
"recipients": "المستلمون ({{count}})",
|
||||
"notAvailable": "غير متوفر",
|
||||
"invalidDate": "تاريخ غير صالح",
|
||||
"loadError": "فشل في تحميل تفاصيل المشاركة"
|
||||
},
|
||||
"uploadFile": {
|
||||
"title": "رفع الملف",
|
||||
"selectFile": "اضغط لاختيار ملف",
|
||||
"preview": "المعاينة",
|
||||
"uploadProgress": "تقدم الرفع",
|
||||
"upload": "رفع",
|
||||
"success": "تم رفع الملف بنجاح",
|
||||
"error": "فشل في رفع الملف"
|
||||
},
|
||||
"filesTable": {
|
||||
"ariaLabel": "جدول الملفات",
|
||||
"columns": {
|
||||
"name": "الاسم",
|
||||
"description": "الوصف",
|
||||
"size": "الحجم",
|
||||
"createdAt": "تاريخ الإنشاء",
|
||||
"updatedAt": "تاريخ التحديث",
|
||||
"actions": "الإجراءات"
|
||||
},
|
||||
"actions": {
|
||||
"menu": "قائمة إجراءات الملف",
|
||||
"preview": "المعاينة",
|
||||
"edit": "تعديل",
|
||||
"download": "تنزيل",
|
||||
"delete": "حذف"
|
||||
}
|
||||
},
|
||||
"sharesTable": {
|
||||
"ariaLabel": "جدول المشاركات",
|
||||
"never": "أبدًا",
|
||||
"columns": {
|
||||
"name": "الاسم",
|
||||
"createdAt": "تاريخ الإنشاء",
|
||||
"expiresAt": "تاريخ الانتهاء",
|
||||
"status": "الحالة",
|
||||
"security": "الأمان",
|
||||
"files": "الملفات",
|
||||
"recipients": "المستلمون",
|
||||
"actions": "الإجراءات"
|
||||
},
|
||||
"status": {
|
||||
"neverExpires": "لا تنتهي",
|
||||
"active": "نشطة",
|
||||
"expired": "منتهية"
|
||||
},
|
||||
"security": {
|
||||
"protected": "محمي",
|
||||
"public": "عام"
|
||||
},
|
||||
"filesCount": "{{count}} ملف",
|
||||
"recipientsCount": "{{count}} مستلم",
|
||||
"actions": {
|
||||
"menu": "قائمة إجراءات المشاركة",
|
||||
"edit": "تعديل",
|
||||
"manageFiles": "إدارة الملفات",
|
||||
"manageRecipients": "إدارة المستلمين",
|
||||
"viewDetails": "عرض التفاصيل",
|
||||
"generateLink": "إنشاء الرابط",
|
||||
"editLink": "تعديل الرابط",
|
||||
"copyLink": "نسخ الرابط",
|
||||
"notifyRecipients": "إعلام المستلمين",
|
||||
"delete": "حذف"
|
||||
}
|
||||
},
|
||||
"footer": {
|
||||
"poweredBy": "مدعوم من",
|
||||
"kyanHomepage": "الصفحة الرئيسية لـ Kyantech"
|
||||
},
|
||||
"fileManager": {
|
||||
"downloadError": "فشل في تنزيل الملف",
|
||||
"updateSuccess": "تم تحديث الملف بنجاح",
|
||||
"updateError": "فشل في تحديث الملف",
|
||||
"deleteSuccess": "تم حذف الملف بنجاح",
|
||||
"deleteError": "فشل في حذف الملف"
|
||||
},
|
||||
"shareManager": {
|
||||
"deleteSuccess": "تم حذف المشاركة بنجاح",
|
||||
"deleteError": "فشل في حذف المشاركة",
|
||||
"updateSuccess": "تم تحديث المشاركة بنجاح",
|
||||
"updateError": "فشل في تحديث المشاركة",
|
||||
"filesUpdateSuccess": "تم تحديث الملفات بنجاح",
|
||||
"filesUpdateError": "فشل في تحديث الملفات",
|
||||
"recipientsUpdateSuccess": "تم تحديث المستلمين بنجاح",
|
||||
"recipientsUpdateError": "فشل في تحديث المستلمين",
|
||||
"linkGenerateSuccess": "تم إنشاء رابط المشاركة بنجاح",
|
||||
"linkGenerateError": "فشل في إنشاء رابط المشاركة",
|
||||
"notifyLoading": "جاري إرسال الإشعارات...",
|
||||
"notifySuccess": "تم إعلام المستلمين بنجاح",
|
||||
"notifyError": "فشل في إعلام المستلمين"
|
||||
},
|
||||
"quickAccess": {
|
||||
"files": {
|
||||
"title": "ملفاتي",
|
||||
"description": "الوصول إلى الملفات المرفوعة وإدارتها"
|
||||
},
|
||||
"shares": {
|
||||
"title": "مشاركاتي",
|
||||
"description": "عرض وإدارة الملفات المشتركة"
|
||||
}
|
||||
},
|
||||
"recentFiles": {
|
||||
"title": "الرفع الأخير",
|
||||
"viewAll": "عرض الكل",
|
||||
"uploadFile": "رفع ملف",
|
||||
"noFiles": "لم يتم رفع أي ملفات بعد"
|
||||
},
|
||||
"recentShares": {
|
||||
"title": "المشاركات الأخيرة",
|
||||
"viewAll": "عرض الكل",
|
||||
"createShare": "إنشاء مشاركة",
|
||||
"noShares": "لم يتم إنشاء أي مشاركات بعد",
|
||||
"createFirst": "أنشئ مشاركتك الأولى"
|
||||
},
|
||||
"storageUsage": {
|
||||
"title": "استخدام التخزين",
|
||||
"ariaLabel": "شريط تقدم استخدام التخزين",
|
||||
"used": "المستخدمة: {{size}}",
|
||||
"available": "المتاحة: {{size}}"
|
||||
},
|
||||
"dashboard": {
|
||||
"loadError": "فشل في تحميل بيانات لوحة التحكم",
|
||||
"linkCopied": "تم نسخ الرابط إلى الحافظة",
|
||||
"pageTitle": "لوحة التحكم",
|
||||
"breadcrumb": "لوحة التحكم"
|
||||
},
|
||||
"emptyState": {
|
||||
"noFiles": "لم يتم رفع أي ملفات بعد",
|
||||
"uploadFile": "رفع ملف"
|
||||
},
|
||||
"files": {
|
||||
"title": "كل الملفات",
|
||||
"uploadFile": "رفع ملف",
|
||||
"loadError": "فشل في تحميل الملفات",
|
||||
"pageTitle": "ملفاتي",
|
||||
"breadcrumb": "ملفاتي"
|
||||
},
|
||||
"searchBar": {
|
||||
"placeholder": "ابحث عن الملفات...",
|
||||
"results": "تم العثور على {{filtered}} من {{total}} ملف"
|
||||
},
|
||||
"forgotPassword": {
|
||||
"emailLabel": "البريد الإلكتروني",
|
||||
"emailPlaceholder": "أدخل بريدك الإلكتروني",
|
||||
"sending": "جاري الإرسال...",
|
||||
"submit": "أرسل تعليمات إعادة التعيين",
|
||||
"backToLogin": "العودة إلى تسجيل الدخول",
|
||||
"title": "نسيت كلمة المرور",
|
||||
"description": "أدخل بريدك الإلكتروني وسنرسل لك تعليمات إعادة تعيين كلمة المرور.",
|
||||
"resetInstructions": "تم إرسال تعليمات إعادة التعيين إلى بريدك الإلكتروني",
|
||||
"pageTitle": "نسيت كلمة المرور"
|
||||
},
|
||||
"home": {
|
||||
"description": "البديل مفتوح المصدر لـ WeTransfer. شارك ملفاتك بأمان، دون تتبع أو قيود.",
|
||||
"documentation": "التوثيق",
|
||||
"starOnGithub": "ضع نجمة على GitHub",
|
||||
"privacyMessage": "مصمم مع مراعاة الخصوصية. ملفاتك قبل الرفع متاحة فقط لأولئك الذين لديهم رابط المشاركة. مجاني ومفتوح المصدر دائمًا.",
|
||||
"header": {
|
||||
"fileSharing": "مشاركة الملفات",
|
||||
"tagline": "بسيط ومجاني"
|
||||
},
|
||||
"pageTitle": "الصفحة الرئيسية"
|
||||
},
|
||||
"profile": {
|
||||
"password": {
|
||||
"title": "تغيير كلمة المرور",
|
||||
"newPassword": "كلمة مرور جديدة",
|
||||
"confirmPassword": "تأكيد كلمة المرور الجديدة",
|
||||
"updateButton": "تحديث كلمة المرور"
|
||||
},
|
||||
"form": {
|
||||
"title": "معلومات الملف الشخصي",
|
||||
"firstName": "الاسم الأول",
|
||||
"lastName": "اسم العائلة",
|
||||
"username": "اسم المستخدم",
|
||||
"email": "البريد الإلكتروني",
|
||||
"updateButton": "تحديث الملف الشخصي"
|
||||
},
|
||||
"header": {
|
||||
"title": "الملف الشخصي",
|
||||
"subtitle": "إدارة معلوماتك الشخصية وكلمة المرور"
|
||||
},
|
||||
"picture": {
|
||||
"title": "صورة الملف الشخصي",
|
||||
"description": "انقر على أيقونة الكاميرا لتغيير صورة الملف الشخصي",
|
||||
"uploadPhoto": "رفع صورة",
|
||||
"removePhoto": "حذف الصورة"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "فشل في تحميل بيانات المستخدم",
|
||||
"updateFailed": "فشل في تحديث الملف الشخصي",
|
||||
"passwordFailed": "فشل في تحديث كلمة المرور",
|
||||
"imageFailed": "فشل في تحديث صورة الملف الشخصي",
|
||||
"imageRemoveFailed": "فشل في حذف صورة الملف الشخصي"
|
||||
},
|
||||
"messages": {
|
||||
"noChanges": "لا توجد تغييرات للحفظ",
|
||||
"updateSuccess": "تم تحديث الملف الشخصي بنجاح",
|
||||
"fillPasswords": "يرجى ملء كلا حقلي كلمة المرور",
|
||||
"passwordSuccess": "تم تحديث كلمة المرور بنجاح",
|
||||
"imageSuccess": "تم تحديث صورة الملف الشخصي بنجاح",
|
||||
"imageRemoved": "تم حذف صورة الملف الشخصي بنجاح"
|
||||
},
|
||||
"pageTitle": "الملف الشخصي"
|
||||
},
|
||||
"resetPassword": {
|
||||
"pageTitle": "إعادة تعيين كلمة المرور",
|
||||
"header": {
|
||||
"title": "إعادة تعيين كلمة المرور",
|
||||
"description": "أدخل كلمة المرور الجديدة أدناه"
|
||||
},
|
||||
"form": {
|
||||
"newPassword": "كلمة مرور جديدة",
|
||||
"newPasswordPlaceholder": "أدخل كلمة المرور الجديدة",
|
||||
"confirmPassword": "تأكيد كلمة المرور الجديدة",
|
||||
"confirmPasswordPlaceholder": "أدخل تأكيد كلمة المرور الجديدة",
|
||||
"resetting": "جاري إعادة تعيين كلمة المرور...",
|
||||
"submit": "إعادة تعيين كلمة المرور",
|
||||
"backToLogin": "العودة إلى تسجيل الدخول"
|
||||
},
|
||||
"messages": {
|
||||
"success": "تم إعادة تعيين كلمة المرور بنجاح"
|
||||
},
|
||||
"errors": {
|
||||
"serverError": "فشل في إعادة تعيين كلمة المرور. يرجى المحاولة مرة أخرى.",
|
||||
"invalidToken": "رمز إعادة التعيين غير صالح أو مفقود"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"groups": {
|
||||
"defaultDescription": "خيارات التكوين",
|
||||
"general": {
|
||||
"title": "عام",
|
||||
"description": "إعدادات التطبيق الأساسية"
|
||||
},
|
||||
"email": {
|
||||
"title": "البريد الإلكتروني",
|
||||
"description": "تكوين خادم البريد الإلكتروني"
|
||||
},
|
||||
"security": {
|
||||
"title": "الأمان",
|
||||
"description": "إعدادات الأمان والمصادقة"
|
||||
},
|
||||
"storage": {
|
||||
"title": "التخزين",
|
||||
"description": "تكوين تخزين الملفات"
|
||||
}
|
||||
},
|
||||
"fields": {
|
||||
"noDescription": "لا يوجد وصف متاح",
|
||||
"appLogo": {
|
||||
"title": "شعار التطبيق",
|
||||
"description": "صورة شعار التطبيق"
|
||||
},
|
||||
"appName": {
|
||||
"title": "اسم التطبيق",
|
||||
"description": "اسم التطبيق الذي يظهر للمستخدمين"
|
||||
},
|
||||
"appDescription": {
|
||||
"title": "وصف التطبيق",
|
||||
"description": "وصف مختصر للتطبيق"
|
||||
},
|
||||
"showHomePage": {
|
||||
"title": "عرض الصفحة الرئيسية",
|
||||
"description": "عرض الصفحة الرئيسية بعد التثبيت"
|
||||
},
|
||||
"smtpEnabled": {
|
||||
"title": "تمكين SMTP",
|
||||
"description": "تمكين أو تعطيل وظيفة البريد الإلكتروني عبر SMTP"
|
||||
},
|
||||
"smtpHost": {
|
||||
"title": "خادم SMTP",
|
||||
"description": "عنوان خادم SMTP"
|
||||
},
|
||||
"smtpPort": {
|
||||
"title": "منفذ SMTP",
|
||||
"description": "منفذ خادم SMTP"
|
||||
},
|
||||
"smtpUser": {
|
||||
"title": "مستخدم SMTP",
|
||||
"description": "اسم المستخدم لمصادقة SMTP"
|
||||
},
|
||||
"smtpPass": {
|
||||
"title": "كلمة مرور SMTP",
|
||||
"description": "كلمة المرور لمصادقة SMTP"
|
||||
},
|
||||
"smtpFromName": {
|
||||
"title": "اسم المرسل",
|
||||
"description": "الاسم الظاهر في الرسائل المرسلة"
|
||||
},
|
||||
"smtpFromEmail": {
|
||||
"title": "البريد الإلكتروني للمرسل",
|
||||
"description": "عنوان البريد الإلكتروني للمرسل"
|
||||
},
|
||||
"maxLoginAttempts": {
|
||||
"title": "أقصى محاولات تسجيل دخول",
|
||||
"description": "الحد الأقصى لمحاولات تسجيل الدخول قبل الحظر"
|
||||
},
|
||||
"loginBlockDuration": {
|
||||
"title": "مدة حظر تسجيل الدخول",
|
||||
"description": "مدة الحظر (بالثواني) بعد تجاوز الحد الأقصى للمحاولات"
|
||||
},
|
||||
"passwordMinLength": {
|
||||
"title": "الحد الأدنى لطول كلمة المرور",
|
||||
"description": "الحد الأدنى لعدد الأحرف في كلمة المرور"
|
||||
},
|
||||
"passwordResetTokenExpiration": {
|
||||
"title": "انتهاء صلاحية رمز إعادة التعيين",
|
||||
"description": "مدة صلاحية رمز إعادة تعيين كلمة المرور (بالثواني)"
|
||||
},
|
||||
"maxFileSize": {
|
||||
"title": "أقصى حجم للملف",
|
||||
"description": "الحد الأقصى لحجم الملف المسموح به للرفع (بالبايت)"
|
||||
},
|
||||
"maxTotalStoragePerUser": {
|
||||
"title": "أقصى تخزين لكل مستخدم",
|
||||
"description": "الحد الإجمالي للتخزين لكل مستخدم (بالبايت)"
|
||||
}
|
||||
},
|
||||
"buttons": {
|
||||
"save": "احفظ {{group}}"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "فشل في تحميل الإعدادات",
|
||||
"updateFailed": "فشل في تحديث الإعدادات"
|
||||
},
|
||||
"messages": {
|
||||
"noChanges": "لا توجد تغييرات للحفظ",
|
||||
"updateSuccess": "تم تحديث إعدادات {{group}} بنجاح"
|
||||
},
|
||||
"title": "الإعدادات",
|
||||
"breadcrumb": "الإعدادات",
|
||||
"pageTitle": "الإعدادات"
|
||||
},
|
||||
"share": {
|
||||
"errors": {
|
||||
"invalidPassword": "كلمة مرور غير صحيحة. يرجى المحاولة مرة أخرى.",
|
||||
"loadFailed": "فشل في تحميل المشاركة",
|
||||
"downloadFailed": "فشل في تنزيل الملف"
|
||||
},
|
||||
"messages": {
|
||||
"downloadStarted": "بدأ التنزيل"
|
||||
},
|
||||
"password": {
|
||||
"title": "مشاركة محمية بكلمة المرور",
|
||||
"protected": "هذه المشاركة محمية بكلمة مرور",
|
||||
"incorrect": "كلمة المرور غير صحيحة. يرجى المحاولة مرة أخرى.",
|
||||
"label": "كلمة المرور",
|
||||
"placeholder": "أدخل كلمة مرور المشاركة",
|
||||
"submit": "إرسال"
|
||||
},
|
||||
"details": {
|
||||
"untitled": "بدون عنوان",
|
||||
"created": "تم الإنشاء: {{date}}",
|
||||
"expires": "تنتهي: {{date}}"
|
||||
},
|
||||
"notFound": {
|
||||
"title": "لم يتم العثور على المشاركة",
|
||||
"description": "قد يكون تم حذف هذه المشاركة أو انتهت صلاحيتها."
|
||||
},
|
||||
"pageTitle": "المشاركة"
|
||||
},
|
||||
"shares": {
|
||||
"errors": {
|
||||
"loadFailed": "فشل في تحميل المشاركات",
|
||||
"notifyFailed": "فشل في إعلام المستلمين",
|
||||
"smtpConfigFailed": "فشل في تحميل إعدادات SMTP"
|
||||
},
|
||||
"messages": {
|
||||
"linkCopied": "تم نسخ الرابط إلى الحافظة",
|
||||
"recipientsNotified": "تم إعلام المستلمين بنجاح"
|
||||
},
|
||||
"empty": {
|
||||
"message": "لم يتم إنشاء أي مشاركات بعد",
|
||||
"createButton": "إنشاء مشاركة"
|
||||
},
|
||||
"header": {
|
||||
"title": "مشاركاتي",
|
||||
"myShares": "مشاركاتي"
|
||||
},
|
||||
"search": {
|
||||
"title": "كل المشاركات",
|
||||
"createButton": "إنشاء مشاركة",
|
||||
"placeholder": "ابحث عن المشاركات...",
|
||||
"results": "تم العثور على {{filtered}} من {{total}} مشاركات"
|
||||
},
|
||||
"pageTitle": "المشاركات"
|
||||
},
|
||||
"users": {
|
||||
"modes": {
|
||||
"create": "إنشاء",
|
||||
"edit": "تعديل"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "فشل في تحميل المستخدمين",
|
||||
"submitFailed": "فشل في {{mode}} المستخدم",
|
||||
"deleteFailed": "فشل في حذف المستخدم",
|
||||
"statusUpdateFailed": "فشل في تحديث حالة المستخدم"
|
||||
},
|
||||
"messages": {
|
||||
"createSuccess": "تم إنشاء المستخدم بنجاح",
|
||||
"updateSuccess": "تم تحديث المستخدم بنجاح",
|
||||
"deleteSuccess": "تم حذف المستخدم بنجاح",
|
||||
"activateSuccess": "تم تفعيل المستخدم بنجاح",
|
||||
"deactivateSuccess": "تم إلغاء تفعيل المستخدم بنجاح"
|
||||
},
|
||||
"actions": {
|
||||
"edit": "تعديل",
|
||||
"activate": "تفعيل",
|
||||
"deactivate": "إلغاء التفعيل",
|
||||
"delete": "حذف"
|
||||
},
|
||||
"delete": {
|
||||
"title": "تأكيد حذف المستخدم",
|
||||
"confirmation": "هل أنت متأكد من أنك تريد حذف {{firstName}} {{lastName}}؟ هذا الإجراء لا يمكن التراجع عنه.",
|
||||
"confirm": "حذف المستخدم"
|
||||
},
|
||||
"form": {
|
||||
"titleCreate": "إضافة مستخدم جديد",
|
||||
"titleEdit": "تعديل المستخدم",
|
||||
"firstName": "الاسم الأول",
|
||||
"lastName": "اسم العائلة",
|
||||
"username": "اسم المستخدم",
|
||||
"email": "البريد الإلكتروني",
|
||||
"password": "كلمة المرور",
|
||||
"newPassword": "كلمة مرور جديدة (اختياري)",
|
||||
"passwordPlaceholder": "اتركه فارغاً للاحتفاظ بكلمة المرور الحالية",
|
||||
"role": "الدور",
|
||||
"roleUser": "مستخدم",
|
||||
"roleAdmin": "مسؤول",
|
||||
"create": "إنشاء",
|
||||
"save": "حفظ"
|
||||
},
|
||||
"status": {
|
||||
"title": "تأكيد تغيير الحالة",
|
||||
"confirmation": "هل أنت متأكد من أنك تريد {{action}} المستخدم {{firstName}} {{lastName}}؟",
|
||||
"activate": "تفعيل",
|
||||
"deactivate": "إلغاء التفعيل",
|
||||
"user": "المستخدم"
|
||||
},
|
||||
"header": {
|
||||
"title": "إدارة المستخدمين",
|
||||
"addUser": "إضافة مستخدم",
|
||||
"management": "إدارة المستخدمين"
|
||||
},
|
||||
"table": {
|
||||
"user": "المستخدم",
|
||||
"email": "البريد الإلكتروني",
|
||||
"status": "الحالة",
|
||||
"role": "الدور",
|
||||
"actions": "الإجراءات",
|
||||
"active": "مفعل",
|
||||
"inactive": "غير مفعل",
|
||||
"admin": "مسؤول",
|
||||
"userr": "مستخدم"
|
||||
}
|
||||
},
|
||||
"logo": {
|
||||
"labels": {
|
||||
"appLogo": "شعار التطبيق"
|
||||
},
|
||||
"buttons": {
|
||||
"upload": "رفع الشعار",
|
||||
"remove": "حذف الشعار"
|
||||
},
|
||||
"messages": {
|
||||
"uploadSuccess": "تم رفع الشعار بنجاح",
|
||||
"removeSuccess": "تم حذف الشعار بنجاح"
|
||||
},
|
||||
"errors": {
|
||||
"uploadFailed": "فشل في رفع الشعار",
|
||||
"removeFailed": "فشل في حذف الشعار"
|
||||
}
|
||||
},
|
||||
"navbar": {
|
||||
"logoAlt": "شعار التطبيق",
|
||||
"profileMenu": "قائمة الملف الشخصي",
|
||||
"profile": "الملف الشخصي",
|
||||
"settings": "الإعدادات",
|
||||
"usersManagement": "إدارة المستخدمين",
|
||||
"logout": "تسجيل الخروج"
|
||||
}
|
||||
}
|
638
apps/app/messages/de-DE.json
Normal file
638
apps/app/messages/de-DE.json
Normal file
@@ -0,0 +1,638 @@
|
||||
{
|
||||
"login": {
|
||||
"welcome": "Willkommen zu",
|
||||
"signInToContinue": "Melden Sie sich an, um fortzufahren",
|
||||
"emailLabel": "E-Mail-Adresse",
|
||||
"emailPlaceholder": "Geben Sie Ihre E-Mail-Adresse ein",
|
||||
"passwordLabel": "Passwort",
|
||||
"passwordPlaceholder": "Geben Sie Ihr Passwort ein",
|
||||
"signIn": "Anmelden",
|
||||
"signingIn": "Melde an...",
|
||||
"forgotPassword": "Passwort vergessen?",
|
||||
"pageTitle": "Anmeldung"
|
||||
},
|
||||
"errors": {
|
||||
"invalidCredentials": "Ungültige E-Mail oder Passwort",
|
||||
"userNotFound": "Benutzer nicht gefunden",
|
||||
"accountLocked": "Konto gesperrt. Bitte versuchen Sie es später erneut",
|
||||
"unexpectedError": "Ein unerwarteter Fehler ist aufgetreten. Bitte versuchen Sie es erneut"
|
||||
},
|
||||
"validation": {
|
||||
"invalidEmail": "Ungültige E-Mail-Adresse",
|
||||
"passwordMinLength": "Das Passwort muss mindestens 6 Zeichen lang sein",
|
||||
"firstNameRequired": "Vorname ist erforderlich",
|
||||
"lastNameRequired": "Nachname ist erforderlich",
|
||||
"usernameLength": "Der Benutzername muss mindestens 3 Zeichen lang sein",
|
||||
"usernameSpaces": "Der Benutzername darf keine Leerzeichen enthalten",
|
||||
"passwordLength": "Das Passwort muss mindestens 8 Zeichen lang sein",
|
||||
"passwordsMatch": "Die Passwörter stimmen nicht überein",
|
||||
"emailRequired": "E-Mail ist erforderlich",
|
||||
"passwordRequired": "Passwort ist erforderlich"
|
||||
},
|
||||
"fileSelector": {
|
||||
"availableFiles": "Verfügbare Dateien ({{count}})",
|
||||
"shareFiles": "Dateien teilen ({{count}})",
|
||||
"searchPlaceholder": "Dateien suchen...",
|
||||
"noMatchingFiles": "Keine übereinstimmenden Dateien",
|
||||
"noAvailableFiles": "Keine Dateien verfügbar",
|
||||
"noFilesInShare": "Keine Dateien in der Freigabe",
|
||||
"saveChanges": "Änderungen speichern"
|
||||
},
|
||||
"recipientSelector": {
|
||||
"emailPlaceholder": "Empfänger-E-Mail eingeben",
|
||||
"add": "Hinzufügen",
|
||||
"recipients": "Empfänger ({{count}})",
|
||||
"notifyAll": "Alle benachrichtigen",
|
||||
"noRecipients": "Noch keine Empfänger hinzugefügt",
|
||||
"addSuccess": "Empfänger erfolgreich hinzugefügt",
|
||||
"addError": "Fehler beim Hinzufügen des Empfängers",
|
||||
"removeSuccess": "Empfänger erfolgreich entfernt",
|
||||
"removeError": "Fehler beim Entfernen des Empfängers",
|
||||
"sendingNotifications": "Benachrichtigungen werden gesendet...",
|
||||
"notifySuccess": "Empfänger erfolgreich benachrichtigt",
|
||||
"notifyError": "Fehler beim Benachrichtigen der Empfänger"
|
||||
},
|
||||
"navigation": {
|
||||
"dashboard": "Übersicht"
|
||||
},
|
||||
"common": {
|
||||
"loading": "Lädt, bitte warten...",
|
||||
"cancel": "Abbrechen",
|
||||
"save": "Speichern",
|
||||
"delete": "Löschen",
|
||||
"close": "Schließen",
|
||||
"download": "Herunterladen",
|
||||
"unexpectedError": "Ein unerwarteter Fehler ist aufgetreten. Bitte versuchen Sie es erneut.",
|
||||
"yes": "Ja",
|
||||
"no": "Nein",
|
||||
"dashboard": "Übersicht"
|
||||
},
|
||||
"createShare": {
|
||||
"title": "Freigabe erstellen",
|
||||
"nameLabel": "Freigabename",
|
||||
"expirationLabel": "Ablaufdatum",
|
||||
"expirationPlaceholder": "MM/TT/JJJJ SS:MM",
|
||||
"maxViewsLabel": "Maximale Ansichten",
|
||||
"maxViewsPlaceholder": "Leer lassen für unbegrenzt",
|
||||
"passwordProtection": "Passwortgeschützt",
|
||||
"passwordLabel": "Passwort",
|
||||
"create": "Freigabe erstellen",
|
||||
"success": "Freigabe erfolgreich erstellt",
|
||||
"error": "Fehler beim Erstellen der Freigabe"
|
||||
},
|
||||
"fileActions": {
|
||||
"editFile": "Datei bearbeiten",
|
||||
"nameLabel": "Name",
|
||||
"namePlaceholder": "Neuen Namen eingeben",
|
||||
"extension": "Erweiterung",
|
||||
"descriptionLabel": "Beschreibung",
|
||||
"descriptionPlaceholder": "Dateibeschreibung eingeben",
|
||||
"deleteFile": "Datei löschen",
|
||||
"deleteConfirmation": "Sind Sie sicher, dass Sie \"{{fileName}}\" löschen möchten?",
|
||||
"deleteWarning": "Diese Aktion kann nicht rückgängig gemacht werden."
|
||||
},
|
||||
"filePreview": {
|
||||
"loading": "Vorschau wird geladen...",
|
||||
"notAvailable": "Vorschau nicht verfügbar",
|
||||
"downloadToView": "Datei herunterladen, um den Inhalt anzuzeigen",
|
||||
"audioNotSupported": "Ihr Browser unterstützt das Audioelement nicht",
|
||||
"videoNotSupported": "Ihr Browser unterstützt das Videoelement nicht",
|
||||
"loadError": "Fehler beim Laden der Vorschau",
|
||||
"downloadError": "Fehler beim Herunterladen der Datei"
|
||||
},
|
||||
"generateShareLink": {
|
||||
"generateTitle": "Freigabelink generieren",
|
||||
"updateTitle": "Freigabelink aktualisieren",
|
||||
"generateDescription": "Erstellen Sie einen Link, um Ihre Dateien zu teilen",
|
||||
"updateDescription": "Aktualisieren Sie den Alias für diesen Freigabelink",
|
||||
"aliasPlaceholder": "Alias eingeben",
|
||||
"linkReady": "Ihr Freigabelink ist fertig:",
|
||||
"generateButton": "Link generieren",
|
||||
"updateButton": "Link aktualisieren",
|
||||
"copyButton": "Link kopieren",
|
||||
"success": "Link erfolgreich generiert",
|
||||
"error": "Fehler beim Generieren des Links",
|
||||
"copied": "Link in die Zwischenablage kopiert"
|
||||
},
|
||||
"shareActions": {
|
||||
"deleteTitle": "Freigabe löschen",
|
||||
"deleteConfirmation": "Sind Sie sicher, dass Sie diese Freigabe löschen möchten? Diese Aktion kann nicht rückgängig gemacht werden.",
|
||||
"editTitle": "Freigabe bearbeiten",
|
||||
"nameLabel": "Freigabename",
|
||||
"expirationLabel": "Ablaufdatum",
|
||||
"expirationPlaceholder": "MM/TT/JJJJ SS:MM",
|
||||
"maxViewsLabel": "Maximale Ansichten",
|
||||
"maxViewsPlaceholder": "Leer lassen für unbegrenzt",
|
||||
"passwordProtection": "Passwortgeschützt",
|
||||
"passwordLabel": "Passwort",
|
||||
"passwordPlaceholder": "Passwort eingeben",
|
||||
"newPasswordLabel": "Neues Passwort (leer lassen, um das aktuelle zu behalten)",
|
||||
"newPasswordPlaceholder": "Neues Passwort eingeben",
|
||||
"manageFilesTitle": "Dateien verwalten",
|
||||
"manageRecipientsTitle": "Empfänger verwalten",
|
||||
"editSuccess": "Freigabe erfolgreich aktualisiert",
|
||||
"editError": "Fehler beim Aktualisieren der Freigabe"
|
||||
},
|
||||
"shareDetails": {
|
||||
"title": "Freigabedetails",
|
||||
"subtitle": "Detaillierte Informationen zu dieser Freigabe",
|
||||
"basicInfo": "Grundinformationen",
|
||||
"name": "Name",
|
||||
"untitled": "Ohne Titel",
|
||||
"views": "Aufrufe",
|
||||
"dates": "Daten",
|
||||
"created": "Erstellt",
|
||||
"expires": "Läuft ab",
|
||||
"never": "Nie",
|
||||
"security": "Sicherheit",
|
||||
"passwordProtected": "Passwortgeschützt",
|
||||
"publicAccess": "Öffentlicher Zugriff",
|
||||
"maxViews": "Maximale Ansichten: {{count}}",
|
||||
"files": "Dateien ({{count}})",
|
||||
"recipients": "Empfänger ({{count}})",
|
||||
"notAvailable": "N/V",
|
||||
"invalidDate": "Ungültiges Datum",
|
||||
"loadError": "Fehler beim Laden der Freigabedetails"
|
||||
},
|
||||
"uploadFile": {
|
||||
"title": "Datei hochladen",
|
||||
"selectFile": "Klicken Sie, um eine Datei auszuwählen",
|
||||
"preview": "Vorschau",
|
||||
"uploadProgress": "Upload-Fortschritt",
|
||||
"upload": "Hochladen",
|
||||
"success": "Datei erfolgreich hochgeladen",
|
||||
"error": "Fehler beim Hochladen der Datei"
|
||||
},
|
||||
"filesTable": {
|
||||
"ariaLabel": "Dateitabelle",
|
||||
"columns": {
|
||||
"name": "NAME",
|
||||
"description": "BESCHREIBUNG",
|
||||
"size": "GRÖSSE",
|
||||
"createdAt": "ERSTELLT AM",
|
||||
"updatedAt": "AKTUALISIERT AM",
|
||||
"actions": "AKTIONEN"
|
||||
},
|
||||
"actions": {
|
||||
"menu": "Dateiaktionsmenü",
|
||||
"preview": "Vorschau",
|
||||
"edit": "Bearbeiten",
|
||||
"download": "Herunterladen",
|
||||
"delete": "Löschen"
|
||||
}
|
||||
},
|
||||
"sharesTable": {
|
||||
"ariaLabel": "Freigabetabelle",
|
||||
"never": "Nie",
|
||||
"columns": {
|
||||
"name": "NAME",
|
||||
"createdAt": "ERSTELLT AM",
|
||||
"expiresAt": "LÄUFT AB",
|
||||
"status": "STATUS",
|
||||
"security": "SICHERHEIT",
|
||||
"files": "DATEIEN",
|
||||
"recipients": "EMPFÄNGER",
|
||||
"actions": "AKTIONEN"
|
||||
},
|
||||
"status": {
|
||||
"neverExpires": "Läuft nie ab",
|
||||
"active": "Aktiv",
|
||||
"expired": "Abgelaufen"
|
||||
},
|
||||
"security": {
|
||||
"protected": "Geschützt",
|
||||
"public": "Öffentlich"
|
||||
},
|
||||
"filesCount": "{{count}} Dateien",
|
||||
"recipientsCount": "{{count}} Empfänger",
|
||||
"actions": {
|
||||
"menu": "Freigabeaktionsmenü",
|
||||
"edit": "Bearbeiten",
|
||||
"manageFiles": "Dateien verwalten",
|
||||
"manageRecipients": "Empfänger verwalten",
|
||||
"viewDetails": "Details anzeigen",
|
||||
"generateLink": "Link generieren",
|
||||
"editLink": "Link bearbeiten",
|
||||
"copyLink": "Link kopieren",
|
||||
"notifyRecipients": "Empfänger benachrichtigen",
|
||||
"delete": "Löschen"
|
||||
}
|
||||
},
|
||||
"footer": {
|
||||
"poweredBy": "Powered by",
|
||||
"kyanHomepage": "Kyantech Homepage"
|
||||
},
|
||||
"fileManager": {
|
||||
"downloadError": "Fehler beim Herunterladen der Datei",
|
||||
"updateSuccess": "Datei erfolgreich aktualisiert",
|
||||
"updateError": "Fehler beim Aktualisieren der Datei",
|
||||
"deleteSuccess": "Datei erfolgreich gelöscht",
|
||||
"deleteError": "Fehler beim Löschen der Datei"
|
||||
},
|
||||
"shareManager": {
|
||||
"deleteSuccess": "Freigabe erfolgreich gelöscht",
|
||||
"deleteError": "Fehler beim Löschen der Freigabe",
|
||||
"updateSuccess": "Freigabe erfolgreich aktualisiert",
|
||||
"updateError": "Fehler beim Aktualisieren der Freigabe",
|
||||
"filesUpdateSuccess": "Dateien erfolgreich aktualisiert",
|
||||
"filesUpdateError": "Fehler beim Aktualisieren der Dateien",
|
||||
"recipientsUpdateSuccess": "Empfänger erfolgreich aktualisiert",
|
||||
"recipientsUpdateError": "Fehler beim Aktualisieren der Empfänger",
|
||||
"linkGenerateSuccess": "Freigabelink erfolgreich generiert",
|
||||
"linkGenerateError": "Fehler beim Generieren des Freigabelinks",
|
||||
"notifyLoading": "Benachrichtigungen werden gesendet...",
|
||||
"notifySuccess": "Empfänger erfolgreich benachrichtigt",
|
||||
"notifyError": "Fehler beim Benachrichtigen der Empfänger"
|
||||
},
|
||||
"quickAccess": {
|
||||
"files": {
|
||||
"title": "Meine Dateien",
|
||||
"description": "Zugriff und Verwaltung Ihrer hochgeladenen Dateien"
|
||||
},
|
||||
"shares": {
|
||||
"title": "Meine Freigaben",
|
||||
"description": "Anzeigen und Verwalten Ihrer geteilten Dateien"
|
||||
}
|
||||
},
|
||||
"recentFiles": {
|
||||
"title": "Kürzlich hochgeladen",
|
||||
"viewAll": "Alle anzeigen",
|
||||
"uploadFile": "Datei hochladen",
|
||||
"noFiles": "Noch keine Dateien hochgeladen"
|
||||
},
|
||||
"recentShares": {
|
||||
"title": "Kürzlich geteilte",
|
||||
"viewAll": "Alle anzeigen",
|
||||
"createShare": "Freigabe erstellen",
|
||||
"noShares": "Noch keine Freigaben erstellt",
|
||||
"createFirst": "Erstellen Sie Ihre erste Freigabe"
|
||||
},
|
||||
"storageUsage": {
|
||||
"title": "Speichernutzung",
|
||||
"ariaLabel": "Fortschrittsbalken der Speichernutzung",
|
||||
"used": "{{size}} genutzt",
|
||||
"available": "{{size}} verfügbar"
|
||||
},
|
||||
"dashboard": {
|
||||
"loadError": "Fehler beim Laden der Dashboard-Daten",
|
||||
"linkCopied": "Link in die Zwischenablage kopiert",
|
||||
"pageTitle": "Übersicht",
|
||||
"breadcrumb": "Übersicht"
|
||||
},
|
||||
"emptyState": {
|
||||
"noFiles": "Noch keine Dateien hochgeladen",
|
||||
"uploadFile": "Datei hochladen"
|
||||
},
|
||||
"files": {
|
||||
"title": "Alle Dateien",
|
||||
"uploadFile": "Datei hochladen",
|
||||
"loadError": "Fehler beim Laden der Dateien",
|
||||
"pageTitle": "Meine Dateien",
|
||||
"breadcrumb": "Meine Dateien"
|
||||
},
|
||||
"searchBar": {
|
||||
"placeholder": "Dateien suchen...",
|
||||
"results": "Gefunden {{filtered}} von {{total}} Dateien"
|
||||
},
|
||||
"forgotPassword": {
|
||||
"emailLabel": "E-Mail-Adresse",
|
||||
"emailPlaceholder": "Geben Sie Ihre E-Mail-Adresse ein",
|
||||
"sending": "Wird gesendet...",
|
||||
"submit": "Anweisungen zum Zurücksetzen senden",
|
||||
"backToLogin": "Zurück zur Anmeldung",
|
||||
"title": "Passwort vergessen",
|
||||
"description": "Geben Sie Ihre E-Mail-Adresse ein und wir senden Ihnen Anweisungen zum Zurücksetzen Ihres Passworts.",
|
||||
"resetInstructions": "Anweisungen zum Zurücksetzen wurden an Ihre E-Mail gesendet",
|
||||
"pageTitle": "Passwort vergessen"
|
||||
},
|
||||
"home": {
|
||||
"description": "Die Open-Source-Alternative zu WeTransfer. Teilen Sie Dateien sicher, ohne Tracking oder Einschränkungen.",
|
||||
"documentation": "Dokumentation",
|
||||
"starOnGithub": "Auf GitHub Sternchen vergeben",
|
||||
"privacyMessage": "Mit Blick auf den Datenschutz entwickelt. Ihre Dateien sind vor dem Hochladen nur für diejenigen zugänglich, die den Freigabelink haben. Immer kostenlos und Open Source.",
|
||||
"header": {
|
||||
"fileSharing": "Dateifreigabe",
|
||||
"tagline": "einfach und kostenlos"
|
||||
},
|
||||
"pageTitle": "Startseite"
|
||||
},
|
||||
"profile": {
|
||||
"password": {
|
||||
"title": "Passwort ändern",
|
||||
"newPassword": "Neues Passwort",
|
||||
"confirmPassword": "Neues Passwort bestätigen",
|
||||
"updateButton": "Passwort aktualisieren"
|
||||
},
|
||||
"form": {
|
||||
"title": "Profilinformationen",
|
||||
"firstName": "Vorname",
|
||||
"lastName": "Nachname",
|
||||
"username": "Benutzername",
|
||||
"email": "E-Mail",
|
||||
"updateButton": "Profil aktualisieren"
|
||||
},
|
||||
"header": {
|
||||
"title": "Profil",
|
||||
"subtitle": "Verwalten Sie Ihre persönlichen Informationen und Ihr Passwort"
|
||||
},
|
||||
"picture": {
|
||||
"title": "Profilbild",
|
||||
"description": "Klicken Sie auf das Kamerasymbol, um Ihr Profilbild zu ändern",
|
||||
"uploadPhoto": "Foto hochladen",
|
||||
"removePhoto": "Foto entfernen"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "Fehler beim Laden der Benutzerdaten",
|
||||
"updateFailed": "Fehler beim Aktualisieren des Profils",
|
||||
"passwordFailed": "Fehler beim Aktualisieren des Passworts",
|
||||
"imageFailed": "Fehler beim Aktualisieren des Profilbilds",
|
||||
"imageRemoveFailed": "Fehler beim Entfernen des Profilbilds"
|
||||
},
|
||||
"messages": {
|
||||
"noChanges": "Keine Änderungen zum Speichern",
|
||||
"updateSuccess": "Profil erfolgreich aktualisiert",
|
||||
"fillPasswords": "Bitte beide Passwortfelder ausfüllen",
|
||||
"passwordSuccess": "Passwort erfolgreich aktualisiert",
|
||||
"imageSuccess": "Profilbild erfolgreich aktualisiert",
|
||||
"imageRemoved": "Profilbild erfolgreich entfernt"
|
||||
},
|
||||
"pageTitle": "Profil"
|
||||
},
|
||||
"resetPassword": {
|
||||
"pageTitle": "Passwort zurücksetzen",
|
||||
"header": {
|
||||
"title": "Passwort zurücksetzen",
|
||||
"description": "Geben Sie unten Ihr neues Passwort ein"
|
||||
},
|
||||
"form": {
|
||||
"newPassword": "Neues Passwort",
|
||||
"newPasswordPlaceholder": "Geben Sie Ihr neues Passwort ein",
|
||||
"confirmPassword": "Neues Passwort bestätigen",
|
||||
"confirmPasswordPlaceholder": "Bestätigen Sie Ihr neues Passwort",
|
||||
"resetting": "Passwort wird zurückgesetzt...",
|
||||
"submit": "Passwort zurücksetzen",
|
||||
"backToLogin": "Zurück zur Anmeldung"
|
||||
},
|
||||
"messages": {
|
||||
"success": "Passwort erfolgreich zurückgesetzt"
|
||||
},
|
||||
"errors": {
|
||||
"serverError": "Fehler beim Zurücksetzen des Passworts. Bitte versuchen Sie es erneut.",
|
||||
"invalidToken": "Ungültiges oder fehlendes Zurücksetzungstoken"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"groups": {
|
||||
"defaultDescription": "Konfigurationsoptionen",
|
||||
"general": {
|
||||
"title": "Allgemein",
|
||||
"description": "Grundlegende Anwendungseinstellungen"
|
||||
},
|
||||
"email": {
|
||||
"title": "E-Mail",
|
||||
"description": "Konfiguration des E-Mail-Servers"
|
||||
},
|
||||
"security": {
|
||||
"title": "Sicherheit",
|
||||
"description": "Sicherheits- und Authentifizierungseinstellungen"
|
||||
},
|
||||
"storage": {
|
||||
"title": "Speicher",
|
||||
"description": "Konfiguration des Dateispeichers"
|
||||
}
|
||||
},
|
||||
"fields": {
|
||||
"noDescription": "Keine Beschreibung verfügbar",
|
||||
"appLogo": {
|
||||
"title": "Anwendungslogo",
|
||||
"description": "Logo-Bild der Anwendung"
|
||||
},
|
||||
"appName": {
|
||||
"title": "Anwendungsname",
|
||||
"description": "Anwendungsname, der den Benutzern angezeigt wird"
|
||||
},
|
||||
"appDescription": {
|
||||
"title": "Anwendungsbeschreibung",
|
||||
"description": "Kurze Beschreibung der Anwendung"
|
||||
},
|
||||
"showHomePage": {
|
||||
"title": "Startseite anzeigen",
|
||||
"description": "Startseite nach der Installation anzeigen"
|
||||
},
|
||||
"smtpEnabled": {
|
||||
"title": "SMTP aktiviert",
|
||||
"description": "SMTP-E-Mail-Funktionalität aktivieren oder deaktivieren"
|
||||
},
|
||||
"smtpHost": {
|
||||
"title": "SMTP-Server",
|
||||
"description": "Adresse des SMTP-Servers"
|
||||
},
|
||||
"smtpPort": {
|
||||
"title": "SMTP-Port",
|
||||
"description": "Port des SMTP-Servers"
|
||||
},
|
||||
"smtpUser": {
|
||||
"title": "SMTP-Benutzer",
|
||||
"description": "Benutzername für die SMTP-Authentifizierung"
|
||||
},
|
||||
"smtpPass": {
|
||||
"title": "SMTP-Passwort",
|
||||
"description": "Passwort für die SMTP-Authentifizierung"
|
||||
},
|
||||
"smtpFromName": {
|
||||
"title": "Absendername",
|
||||
"description": "Anzeigename für gesendete E-Mails"
|
||||
},
|
||||
"smtpFromEmail": {
|
||||
"title": "Absender-E-Mail",
|
||||
"description": "E-Mail-Adresse des Absenders"
|
||||
},
|
||||
"maxLoginAttempts": {
|
||||
"title": "Maximale Anmeldeversuche",
|
||||
"description": "Maximale Anzahl von Anmeldeversuchen, bevor gesperrt wird"
|
||||
},
|
||||
"loginBlockDuration": {
|
||||
"title": "Sperrdauer",
|
||||
"description": "Dauer (in Sekunden) der Sperre nach Überschreiten der Versuche"
|
||||
},
|
||||
"passwordMinLength": {
|
||||
"title": "Minimale Passwortlänge",
|
||||
"description": "Minimale Anzahl an Zeichen für Passwörter"
|
||||
},
|
||||
"passwordResetTokenExpiration": {
|
||||
"title": "Ablauf des Reset-Tokens",
|
||||
"description": "Gültigkeitsdauer (in Sekunden) des Passwort-Reset-Tokens"
|
||||
},
|
||||
"maxFileSize": {
|
||||
"title": "Maximale Dateigröße",
|
||||
"description": "Maximal erlaubte Dateigröße für Uploads (in Bytes)"
|
||||
},
|
||||
"maxTotalStoragePerUser": {
|
||||
"title": "Maximaler Speicher pro Benutzer",
|
||||
"description": "Gesamtspeicherlimit pro Benutzer (in Bytes)"
|
||||
}
|
||||
},
|
||||
"buttons": {
|
||||
"save": "{{group}} speichern"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "Fehler beim Laden der Einstellungen",
|
||||
"updateFailed": "Fehler beim Aktualisieren der Einstellungen"
|
||||
},
|
||||
"messages": {
|
||||
"noChanges": "Keine Änderungen zum Speichern",
|
||||
"updateSuccess": "{{group}}-Einstellungen erfolgreich aktualisiert"
|
||||
},
|
||||
"title": "Einstellungen",
|
||||
"breadcrumb": "Einstellungen",
|
||||
"pageTitle": "Einstellungen"
|
||||
},
|
||||
"share": {
|
||||
"errors": {
|
||||
"invalidPassword": "Ungültiges Passwort. Bitte versuchen Sie es erneut.",
|
||||
"loadFailed": "Fehler beim Laden der Freigabe",
|
||||
"downloadFailed": "Fehler beim Herunterladen der Datei"
|
||||
},
|
||||
"messages": {
|
||||
"downloadStarted": "Download gestartet"
|
||||
},
|
||||
"password": {
|
||||
"title": "Passwortgeschützte Freigabe",
|
||||
"protected": "Diese Freigabe ist passwortgeschützt",
|
||||
"incorrect": "Falsches Passwort. Bitte versuchen Sie es erneut.",
|
||||
"label": "Passwort",
|
||||
"placeholder": "Passwort der Freigabe eingeben",
|
||||
"submit": "Absenden"
|
||||
},
|
||||
"details": {
|
||||
"untitled": "Unbenannte Freigabe",
|
||||
"created": "Erstellt: {{date}}",
|
||||
"expires": "Läuft ab: {{date}}"
|
||||
},
|
||||
"notFound": {
|
||||
"title": "Freigabe nicht gefunden",
|
||||
"description": "Diese Freigabe wurde möglicherweise gelöscht oder ist abgelaufen."
|
||||
},
|
||||
"pageTitle": "Freigabe"
|
||||
},
|
||||
"shares": {
|
||||
"errors": {
|
||||
"loadFailed": "Fehler beim Laden der Freigaben",
|
||||
"notifyFailed": "Fehler beim Benachrichtigen der Empfänger",
|
||||
"smtpConfigFailed": "Fehler beim Laden der SMTP-Konfiguration"
|
||||
},
|
||||
"messages": {
|
||||
"linkCopied": "Link in die Zwischenablage kopiert",
|
||||
"recipientsNotified": "Empfänger erfolgreich benachrichtigt"
|
||||
},
|
||||
"empty": {
|
||||
"message": "Noch keine Freigaben erstellt",
|
||||
"createButton": "Freigabe erstellen"
|
||||
},
|
||||
"header": {
|
||||
"title": "Meine Freigaben",
|
||||
"myShares": "Meine Freigaben"
|
||||
},
|
||||
"search": {
|
||||
"title": "Alle Freigaben",
|
||||
"createButton": "Freigabe erstellen",
|
||||
"placeholder": "Freigaben suchen...",
|
||||
"results": "Gefunden {{filtered}} von {{total}} Freigaben"
|
||||
},
|
||||
"pageTitle": "Freigaben"
|
||||
},
|
||||
"users": {
|
||||
"modes": {
|
||||
"create": "erstellen",
|
||||
"edit": "bearbeiten"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "Fehler beim Laden der Benutzer",
|
||||
"submitFailed": "Fehler beim {{mode}} des Benutzers",
|
||||
"deleteFailed": "Fehler beim Löschen des Benutzers",
|
||||
"statusUpdateFailed": "Fehler beim Aktualisieren des Benutzerstatus"
|
||||
},
|
||||
"messages": {
|
||||
"createSuccess": "Benutzer erfolgreich erstellt",
|
||||
"updateSuccess": "Benutzer erfolgreich aktualisiert",
|
||||
"deleteSuccess": "Benutzer erfolgreich gelöscht",
|
||||
"activateSuccess": "Benutzer erfolgreich aktiviert",
|
||||
"deactivateSuccess": "Benutzer erfolgreich deaktiviert"
|
||||
},
|
||||
"actions": {
|
||||
"edit": "Bearbeiten",
|
||||
"activate": "Aktivieren",
|
||||
"deactivate": "Deaktivieren",
|
||||
"delete": "Löschen"
|
||||
},
|
||||
"delete": {
|
||||
"title": "Löschen des Benutzers bestätigen",
|
||||
"confirmation": "Sind Sie sicher, dass Sie den Benutzer {{firstName}} {{lastName}} löschen möchten? Diese Aktion kann nicht rückgängig gemacht werden.",
|
||||
"confirm": "Benutzer löschen"
|
||||
},
|
||||
"form": {
|
||||
"titleCreate": "Neuen Benutzer hinzufügen",
|
||||
"titleEdit": "Benutzer bearbeiten",
|
||||
"firstName": "Vorname",
|
||||
"lastName": "Nachname",
|
||||
"username": "Benutzername",
|
||||
"email": "E-Mail",
|
||||
"password": "Passwort",
|
||||
"newPassword": "Neues Passwort (optional)",
|
||||
"passwordPlaceholder": "Leer lassen, um das aktuelle Passwort zu behalten",
|
||||
"role": "Rolle",
|
||||
"roleUser": "Benutzer",
|
||||
"roleAdmin": "Administrator",
|
||||
"create": "Erstellen",
|
||||
"save": "Speichern"
|
||||
},
|
||||
"status": {
|
||||
"title": "Statusänderung bestätigen",
|
||||
"confirmation": "Sind Sie sicher, dass Sie den Benutzer {{firstName}} {{lastName}} {{action}} möchten?",
|
||||
"activate": "aktivieren",
|
||||
"deactivate": "deaktivieren",
|
||||
"user": "Benutzer"
|
||||
},
|
||||
"header": {
|
||||
"title": "Benutzerverwaltung",
|
||||
"addUser": "Benutzer hinzufügen",
|
||||
"management": "Benutzerverwaltung"
|
||||
},
|
||||
"table": {
|
||||
"user": "BENUTZER",
|
||||
"email": "E-MAIL",
|
||||
"status": "STATUS",
|
||||
"role": "ROLLE",
|
||||
"actions": "AKTIONEN",
|
||||
"active": "Aktiv",
|
||||
"inactive": "Inaktiv",
|
||||
"admin": "Administrator",
|
||||
"userr": "Benutzer"
|
||||
}
|
||||
},
|
||||
"logo": {
|
||||
"labels": {
|
||||
"appLogo": "Anwendungslogo"
|
||||
},
|
||||
"buttons": {
|
||||
"upload": "Logo hochladen",
|
||||
"remove": "Logo entfernen"
|
||||
},
|
||||
"messages": {
|
||||
"uploadSuccess": "Logo erfolgreich hochgeladen",
|
||||
"removeSuccess": "Logo erfolgreich entfernt"
|
||||
},
|
||||
"errors": {
|
||||
"uploadFailed": "Fehler beim Hochladen des Logos",
|
||||
"removeFailed": "Fehler beim Entfernen des Logos"
|
||||
}
|
||||
},
|
||||
"navbar": {
|
||||
"logoAlt": "Anwendungslogo",
|
||||
"profileMenu": "Profilmenü",
|
||||
"profile": "Profil",
|
||||
"settings": "Einstellungen",
|
||||
"usersManagement": "Benutzerverwaltung",
|
||||
"logout": "Abmelden"
|
||||
}
|
||||
}
|
638
apps/app/messages/en-US.json
Normal file
638
apps/app/messages/en-US.json
Normal file
@@ -0,0 +1,638 @@
|
||||
{
|
||||
"login": {
|
||||
"welcome": "Welcome to",
|
||||
"signInToContinue": "Sign in to continue",
|
||||
"emailLabel": "Email Address",
|
||||
"emailPlaceholder": "Enter your email",
|
||||
"passwordLabel": "Password",
|
||||
"passwordPlaceholder": "Enter your password",
|
||||
"signIn": "Sign In",
|
||||
"signingIn": "Signing in...",
|
||||
"forgotPassword": "Forgot password?",
|
||||
"pageTitle": "Login"
|
||||
},
|
||||
"errors": {
|
||||
"invalidCredentials": "Invalid email or password",
|
||||
"userNotFound": "User not found",
|
||||
"accountLocked": "Account locked. Please try again later",
|
||||
"unexpectedError": "An unexpected error occurred. Please try again"
|
||||
},
|
||||
"validation": {
|
||||
"invalidEmail": "Invalid email address",
|
||||
"passwordMinLength": "Password must be at least 6 characters",
|
||||
"firstNameRequired": "First name is required",
|
||||
"lastNameRequired": "Last name is required",
|
||||
"usernameLength": "Username must be at least 3 characters",
|
||||
"usernameSpaces": "Username cannot contain spaces",
|
||||
"passwordLength": "Password must be at least 8 characters",
|
||||
"passwordsMatch": "Passwords do not match",
|
||||
"emailRequired": "Email is required",
|
||||
"passwordRequired": "Password is required"
|
||||
},
|
||||
"fileSelector": {
|
||||
"availableFiles": "Available Files ({{count}})",
|
||||
"shareFiles": "Share Files ({{count}})",
|
||||
"searchPlaceholder": "Search files...",
|
||||
"noMatchingFiles": "No matching files",
|
||||
"noAvailableFiles": "No files available",
|
||||
"noFilesInShare": "No files in share",
|
||||
"saveChanges": "Save Changes"
|
||||
},
|
||||
"recipientSelector": {
|
||||
"emailPlaceholder": "Enter recipient email",
|
||||
"add": "Add",
|
||||
"recipients": "Recipients ({{count}})",
|
||||
"notifyAll": "Notify All",
|
||||
"noRecipients": "No recipients added yet",
|
||||
"addSuccess": "Recipient added successfully",
|
||||
"addError": "Failed to add recipient",
|
||||
"removeSuccess": "Recipient removed successfully",
|
||||
"removeError": "Failed to remove recipient",
|
||||
"sendingNotifications": "Sending notifications...",
|
||||
"notifySuccess": "Recipients notified successfully",
|
||||
"notifyError": "Failed to notify recipients"
|
||||
},
|
||||
"navigation": {
|
||||
"dashboard": "Dashboard"
|
||||
},
|
||||
"common": {
|
||||
"loading": "Loading, please wait...",
|
||||
"cancel": "Cancel",
|
||||
"save": "Save",
|
||||
"delete": "Delete",
|
||||
"close": "Close",
|
||||
"download": "Download",
|
||||
"unexpectedError": "An unexpected error occurred. Please try again.",
|
||||
"yes": "Yes",
|
||||
"no": "No",
|
||||
"dashboard": "Dashboard"
|
||||
},
|
||||
"createShare": {
|
||||
"title": "Create Share",
|
||||
"nameLabel": "Share Name",
|
||||
"expirationLabel": "Expiration Date",
|
||||
"expirationPlaceholder": "MM/DD/YYYY HH:MM",
|
||||
"maxViewsLabel": "Max Views",
|
||||
"maxViewsPlaceholder": "Leave empty for unlimited",
|
||||
"passwordProtection": "Password Protected",
|
||||
"passwordLabel": "Password",
|
||||
"create": "Create Share",
|
||||
"success": "Share created successfully",
|
||||
"error": "Failed to create share"
|
||||
},
|
||||
"fileActions": {
|
||||
"editFile": "Edit File",
|
||||
"nameLabel": "Name",
|
||||
"namePlaceholder": "Enter new name",
|
||||
"extension": "Extension",
|
||||
"descriptionLabel": "Description",
|
||||
"descriptionPlaceholder": "Enter file description",
|
||||
"deleteFile": "Delete File",
|
||||
"deleteConfirmation": "Are you sure you want to delete \"{{fileName}}\"?",
|
||||
"deleteWarning": "This action cannot be undone."
|
||||
},
|
||||
"filePreview": {
|
||||
"loading": "Loading preview...",
|
||||
"notAvailable": "Preview not available",
|
||||
"downloadToView": "Download file to view contents",
|
||||
"audioNotSupported": "Your browser does not support the audio element",
|
||||
"videoNotSupported": "Your browser does not support the video element",
|
||||
"loadError": "Failed to load preview",
|
||||
"downloadError": "Failed to download file"
|
||||
},
|
||||
"generateShareLink": {
|
||||
"generateTitle": "Generate Share Link",
|
||||
"updateTitle": "Update Share Link",
|
||||
"generateDescription": "Generate a link to share your files",
|
||||
"updateDescription": "Update the alias for this share link",
|
||||
"aliasPlaceholder": "Enter alias",
|
||||
"linkReady": "Your share link is ready:",
|
||||
"generateButton": "Generate Link",
|
||||
"updateButton": "Update Link",
|
||||
"copyButton": "Copy Link",
|
||||
"success": "Link generated successfully",
|
||||
"error": "Failed to generate link",
|
||||
"copied": "Link copied to clipboard"
|
||||
},
|
||||
"shareActions": {
|
||||
"deleteTitle": "Delete Share",
|
||||
"deleteConfirmation": "Are you sure you want to delete this share? This action cannot be undone.",
|
||||
"editTitle": "Edit Share",
|
||||
"nameLabel": "Share Name",
|
||||
"expirationLabel": "Expiration Date",
|
||||
"expirationPlaceholder": "MM/DD/YYYY HH:MM",
|
||||
"maxViewsLabel": "Max Views",
|
||||
"maxViewsPlaceholder": "Leave empty for unlimited",
|
||||
"passwordProtection": "Password Protected",
|
||||
"passwordLabel": "Password",
|
||||
"passwordPlaceholder": "Enter password",
|
||||
"newPasswordLabel": "New Password (leave empty to keep current)",
|
||||
"newPasswordPlaceholder": "Enter new password",
|
||||
"manageFilesTitle": "Manage Files",
|
||||
"manageRecipientsTitle": "Manage Recipients",
|
||||
"editSuccess": "Share updated successfully",
|
||||
"editError": "Failed to update share"
|
||||
},
|
||||
"shareDetails": {
|
||||
"title": "Share Details",
|
||||
"subtitle": "Detailed information about this share",
|
||||
"basicInfo": "Basic Information",
|
||||
"name": "Name",
|
||||
"untitled": "Untitled",
|
||||
"views": "Views",
|
||||
"dates": "Dates",
|
||||
"created": "Created",
|
||||
"expires": "Expires",
|
||||
"never": "Never",
|
||||
"security": "Security",
|
||||
"passwordProtected": "Password Protected",
|
||||
"publicAccess": "Public Access",
|
||||
"maxViews": "Max Views: {{count}}",
|
||||
"files": "Files ({{count}})",
|
||||
"recipients": "Recipients ({{count}})",
|
||||
"notAvailable": "N/A",
|
||||
"invalidDate": "Invalid date",
|
||||
"loadError": "Failed to load share details"
|
||||
},
|
||||
"uploadFile": {
|
||||
"title": "Upload File",
|
||||
"selectFile": "Click to select a file",
|
||||
"preview": "Preview",
|
||||
"uploadProgress": "Upload progress",
|
||||
"upload": "Upload",
|
||||
"success": "File uploaded successfully",
|
||||
"error": "Failed to upload file"
|
||||
},
|
||||
"filesTable": {
|
||||
"ariaLabel": "Files table",
|
||||
"columns": {
|
||||
"name": "NAME",
|
||||
"description": "DESCRIPTION",
|
||||
"size": "SIZE",
|
||||
"createdAt": "CREATED AT",
|
||||
"updatedAt": "UPDATED AT",
|
||||
"actions": "ACTIONS"
|
||||
},
|
||||
"actions": {
|
||||
"menu": "File actions menu",
|
||||
"preview": "Preview",
|
||||
"edit": "Edit",
|
||||
"download": "Download",
|
||||
"delete": "Delete"
|
||||
}
|
||||
},
|
||||
"sharesTable": {
|
||||
"ariaLabel": "Shares table",
|
||||
"never": "Never",
|
||||
"columns": {
|
||||
"name": "NAME",
|
||||
"createdAt": "CREATED AT",
|
||||
"expiresAt": "EXPIRES AT",
|
||||
"status": "STATUS",
|
||||
"security": "SECURITY",
|
||||
"files": "FILES",
|
||||
"recipients": "RECIPIENTS",
|
||||
"actions": "ACTIONS"
|
||||
},
|
||||
"status": {
|
||||
"neverExpires": "Never Expires",
|
||||
"active": "Active",
|
||||
"expired": "Expired"
|
||||
},
|
||||
"security": {
|
||||
"protected": "Protected",
|
||||
"public": "Public"
|
||||
},
|
||||
"filesCount": "{{count}} files",
|
||||
"recipientsCount": "{{count}} recipients",
|
||||
"actions": {
|
||||
"menu": "Share actions menu",
|
||||
"edit": "Edit",
|
||||
"manageFiles": "Manage Files",
|
||||
"manageRecipients": "Manage Recipients",
|
||||
"viewDetails": "View Details",
|
||||
"generateLink": "Generate Link",
|
||||
"editLink": "Edit Link",
|
||||
"copyLink": "Copy Link",
|
||||
"notifyRecipients": "Notify Recipients",
|
||||
"delete": "Delete"
|
||||
}
|
||||
},
|
||||
"footer": {
|
||||
"poweredBy": "Powered by",
|
||||
"kyanHomepage": "Kyantech homepage"
|
||||
},
|
||||
"fileManager": {
|
||||
"downloadError": "Failed to download file",
|
||||
"updateSuccess": "File updated successfully",
|
||||
"updateError": "Failed to update file",
|
||||
"deleteSuccess": "File deleted successfully",
|
||||
"deleteError": "Failed to delete file"
|
||||
},
|
||||
"shareManager": {
|
||||
"deleteSuccess": "Share deleted successfully",
|
||||
"deleteError": "Failed to delete share",
|
||||
"updateSuccess": "Share updated successfully",
|
||||
"updateError": "Failed to update share",
|
||||
"filesUpdateSuccess": "Files updated successfully",
|
||||
"filesUpdateError": "Failed to update files",
|
||||
"recipientsUpdateSuccess": "Recipients updated successfully",
|
||||
"recipientsUpdateError": "Failed to update recipients",
|
||||
"linkGenerateSuccess": "Share link generated successfully",
|
||||
"linkGenerateError": "Failed to generate share link",
|
||||
"notifyLoading": "Sending notifications...",
|
||||
"notifySuccess": "Recipients notified successfully",
|
||||
"notifyError": "Failed to notify recipients"
|
||||
},
|
||||
"quickAccess": {
|
||||
"files": {
|
||||
"title": "My Files",
|
||||
"description": "Access and manage your uploaded files"
|
||||
},
|
||||
"shares": {
|
||||
"title": "My Shares",
|
||||
"description": "View and manage your shared files"
|
||||
}
|
||||
},
|
||||
"recentFiles": {
|
||||
"title": "Recent Uploads",
|
||||
"viewAll": "View All",
|
||||
"uploadFile": "Upload File",
|
||||
"noFiles": "No files uploaded yet"
|
||||
},
|
||||
"recentShares": {
|
||||
"title": "Recent Shares",
|
||||
"viewAll": "View All",
|
||||
"createShare": "Create Share",
|
||||
"noShares": "No shares created yet",
|
||||
"createFirst": "Create your first share"
|
||||
},
|
||||
"storageUsage": {
|
||||
"title": "Storage Usage",
|
||||
"ariaLabel": "Storage usage progress bar",
|
||||
"used": "{{size}} used",
|
||||
"available": "{{size}} available"
|
||||
},
|
||||
"dashboard": {
|
||||
"loadError": "Failed to load dashboard data",
|
||||
"linkCopied": "Link copied to clipboard",
|
||||
"pageTitle": "Dashboard",
|
||||
"breadcrumb": "Dashboard"
|
||||
},
|
||||
"emptyState": {
|
||||
"noFiles": "No files uploaded yet",
|
||||
"uploadFile": "Upload File"
|
||||
},
|
||||
"files": {
|
||||
"title": "All Files",
|
||||
"uploadFile": "Upload File",
|
||||
"loadError": "Failed to load files",
|
||||
"pageTitle": "My Files",
|
||||
"breadcrumb": "My Files"
|
||||
},
|
||||
"searchBar": {
|
||||
"placeholder": "Search files...",
|
||||
"results": "Found {{filtered}} of {{total}} files"
|
||||
},
|
||||
"forgotPassword": {
|
||||
"emailLabel": "Email Address",
|
||||
"emailPlaceholder": "Enter your email",
|
||||
"sending": "Sending...",
|
||||
"submit": "Send Reset Instructions",
|
||||
"backToLogin": "Back to Login",
|
||||
"title": "Forgot Password",
|
||||
"description": "Enter your email address and we'll send you instructions to reset your password.",
|
||||
"resetInstructions": "Reset instructions sent to your email",
|
||||
"pageTitle": "Forgot Password"
|
||||
},
|
||||
"home": {
|
||||
"description": "The open-source alternative to WeTransfer. Share files securely, without tracking, or limitations.",
|
||||
"documentation": "Documentation",
|
||||
"starOnGithub": "Star on GitHub",
|
||||
"privacyMessage": "Built with privacy in mind. Your files before upload only accessible by those with the sharing link. Forever free and open source.",
|
||||
"header": {
|
||||
"fileSharing": "File sharing",
|
||||
"tagline": "made simple and free"
|
||||
},
|
||||
"pageTitle": "Home"
|
||||
},
|
||||
"profile": {
|
||||
"password": {
|
||||
"title": "Change Password",
|
||||
"newPassword": "New Password",
|
||||
"confirmPassword": "Confirm New Password",
|
||||
"updateButton": "Update Password"
|
||||
},
|
||||
"form": {
|
||||
"title": "Profile Information",
|
||||
"firstName": "First Name",
|
||||
"lastName": "Last Name",
|
||||
"username": "Username",
|
||||
"email": "Email",
|
||||
"updateButton": "Update Profile"
|
||||
},
|
||||
"header": {
|
||||
"title": "Profile",
|
||||
"subtitle": "Manage your personal information and password"
|
||||
},
|
||||
"picture": {
|
||||
"title": "Profile Picture",
|
||||
"description": "Click the camera icon to change your profile picture",
|
||||
"uploadPhoto": "Upload Photo",
|
||||
"removePhoto": "Remove Photo"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "Failed to load user data",
|
||||
"updateFailed": "Failed to update profile",
|
||||
"passwordFailed": "Failed to update password",
|
||||
"imageFailed": "Failed to update profile image",
|
||||
"imageRemoveFailed": "Failed to remove profile image"
|
||||
},
|
||||
"messages": {
|
||||
"noChanges": "No changes to save",
|
||||
"updateSuccess": "Profile updated successfully",
|
||||
"fillPasswords": "Please fill in both password fields",
|
||||
"passwordSuccess": "Password updated successfully",
|
||||
"imageSuccess": "Profile image updated successfully",
|
||||
"imageRemoved": "Profile image removed successfully"
|
||||
},
|
||||
"pageTitle": "Profile"
|
||||
},
|
||||
"resetPassword": {
|
||||
"pageTitle": "Reset Password",
|
||||
"header": {
|
||||
"title": "Reset Password",
|
||||
"description": "Enter your new password below"
|
||||
},
|
||||
"form": {
|
||||
"newPassword": "New Password",
|
||||
"newPasswordPlaceholder": "Enter your new password",
|
||||
"confirmPassword": "Confirm New Password",
|
||||
"confirmPasswordPlaceholder": "Confirm your new password",
|
||||
"resetting": "Resetting Password...",
|
||||
"submit": "Reset Password",
|
||||
"backToLogin": "Back to Login"
|
||||
},
|
||||
"messages": {
|
||||
"success": "Password reset successfully"
|
||||
},
|
||||
"errors": {
|
||||
"serverError": "Failed to reset password. Please try again.",
|
||||
"invalidToken": "Invalid or missing reset token"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"groups": {
|
||||
"defaultDescription": "Configuration options",
|
||||
"general": {
|
||||
"title": "General",
|
||||
"description": "Basic application settings"
|
||||
},
|
||||
"email": {
|
||||
"title": "Email",
|
||||
"description": "Email server configuration"
|
||||
},
|
||||
"security": {
|
||||
"title": "Security",
|
||||
"description": "Security and authentication settings"
|
||||
},
|
||||
"storage": {
|
||||
"title": "Storage",
|
||||
"description": "File storage configuration"
|
||||
}
|
||||
},
|
||||
"fields": {
|
||||
"noDescription": "No description available",
|
||||
"appLogo": {
|
||||
"title": "Application Logo",
|
||||
"description": "Application logo image"
|
||||
},
|
||||
"appName": {
|
||||
"title": "Application Name",
|
||||
"description": "Application name displayed to users"
|
||||
},
|
||||
"appDescription": {
|
||||
"title": "Application Description",
|
||||
"description": "Brief description of the application"
|
||||
},
|
||||
"showHomePage": {
|
||||
"title": "Show Home Page",
|
||||
"description": "Show Home Page after installation"
|
||||
},
|
||||
"smtpEnabled": {
|
||||
"title": "SMTP Enabled",
|
||||
"description": "Enable or disable SMTP email functionality"
|
||||
},
|
||||
"smtpHost": {
|
||||
"title": "SMTP Server",
|
||||
"description": "SMTP server address"
|
||||
},
|
||||
"smtpPort": {
|
||||
"title": "SMTP Port",
|
||||
"description": "SMTP server port"
|
||||
},
|
||||
"smtpUser": {
|
||||
"title": "SMTP Username",
|
||||
"description": "Username for SMTP authentication"
|
||||
},
|
||||
"smtpPass": {
|
||||
"title": "SMTP Password",
|
||||
"description": "Password for SMTP authentication"
|
||||
},
|
||||
"smtpFromName": {
|
||||
"title": "Sender Name",
|
||||
"description": "Display name for sent emails"
|
||||
},
|
||||
"smtpFromEmail": {
|
||||
"title": "Sender Email",
|
||||
"description": "Sender email address"
|
||||
},
|
||||
"maxLoginAttempts": {
|
||||
"title": "Maximum Login Attempts",
|
||||
"description": "Maximum number of login attempts before blocking"
|
||||
},
|
||||
"loginBlockDuration": {
|
||||
"title": "Block Duration",
|
||||
"description": "Duration (in seconds) to block after exceeding attempts"
|
||||
},
|
||||
"passwordMinLength": {
|
||||
"title": "Minimum Password Length",
|
||||
"description": "Minimum number of characters for passwords"
|
||||
},
|
||||
"passwordResetTokenExpiration": {
|
||||
"title": "Reset Token Expiration",
|
||||
"description": "Validity time (in seconds) for password reset token"
|
||||
},
|
||||
"maxFileSize": {
|
||||
"title": "Maximum File Size",
|
||||
"description": "Maximum allowed file size for uploads (in bytes)"
|
||||
},
|
||||
"maxTotalStoragePerUser": {
|
||||
"title": "Maximum Storage Per User",
|
||||
"description": "Total storage limit per user (in bytes)"
|
||||
}
|
||||
},
|
||||
"buttons": {
|
||||
"save": "Save {{group}}"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "Failed to load settings",
|
||||
"updateFailed": "Failed to update settings"
|
||||
},
|
||||
"messages": {
|
||||
"noChanges": "No changes to save",
|
||||
"updateSuccess": "{{group}} settings updated successfully"
|
||||
},
|
||||
"title": "Settings",
|
||||
"breadcrumb": "Settings",
|
||||
"pageTitle": "Settings"
|
||||
},
|
||||
"share": {
|
||||
"errors": {
|
||||
"invalidPassword": "Invalid password. Please try again.",
|
||||
"loadFailed": "Failed to load share",
|
||||
"downloadFailed": "Failed to download file"
|
||||
},
|
||||
"messages": {
|
||||
"downloadStarted": "Download started"
|
||||
},
|
||||
"password": {
|
||||
"title": "Password Protected Share",
|
||||
"protected": "This share is password protected",
|
||||
"incorrect": "Incorrect password. Please try again.",
|
||||
"label": "Password",
|
||||
"placeholder": "Enter share password",
|
||||
"submit": "Submit"
|
||||
},
|
||||
"details": {
|
||||
"untitled": "Untitled Share",
|
||||
"created": "Created: {{date}}",
|
||||
"expires": "Expires: {{date}}"
|
||||
},
|
||||
"notFound": {
|
||||
"title": "Share Not Found",
|
||||
"description": "This share may have been deleted or expired."
|
||||
},
|
||||
"pageTitle": "Share"
|
||||
},
|
||||
"shares": {
|
||||
"errors": {
|
||||
"loadFailed": "Failed to load shares",
|
||||
"notifyFailed": "Failed to notify recipients",
|
||||
"smtpConfigFailed": "Failed to load SMTP configuration"
|
||||
},
|
||||
"messages": {
|
||||
"linkCopied": "Link copied to clipboard",
|
||||
"recipientsNotified": "Recipients notified successfully"
|
||||
},
|
||||
"empty": {
|
||||
"message": "No shares created yet",
|
||||
"createButton": "Create Share"
|
||||
},
|
||||
"header": {
|
||||
"title": "My Shares",
|
||||
"myShares": "My Shares"
|
||||
},
|
||||
"search": {
|
||||
"title": "All Shares",
|
||||
"createButton": "Create Share",
|
||||
"placeholder": "Search shares...",
|
||||
"results": "Found {{filtered}} of {{total}} shares"
|
||||
},
|
||||
"pageTitle": "Shares"
|
||||
},
|
||||
"users": {
|
||||
"modes": {
|
||||
"create": "create",
|
||||
"edit": "edit"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "Failed to load users",
|
||||
"submitFailed": "Failed to {{mode}} user",
|
||||
"deleteFailed": "Failed to delete user",
|
||||
"statusUpdateFailed": "Failed to update user status"
|
||||
},
|
||||
"messages": {
|
||||
"createSuccess": "User created successfully",
|
||||
"updateSuccess": "User updated successfully",
|
||||
"deleteSuccess": "User deleted successfully",
|
||||
"activateSuccess": "User activated successfully",
|
||||
"deactivateSuccess": "User deactivated successfully"
|
||||
},
|
||||
"actions": {
|
||||
"edit": "Edit",
|
||||
"activate": "Activate",
|
||||
"deactivate": "Deactivate",
|
||||
"delete": "Delete"
|
||||
},
|
||||
"delete": {
|
||||
"title": "Confirm Delete User",
|
||||
"confirmation": "Are you sure you want to delete user {{firstName}} {{lastName}}? This action cannot be undone.",
|
||||
"confirm": "Delete User"
|
||||
},
|
||||
"form": {
|
||||
"titleCreate": "Add New User",
|
||||
"titleEdit": "Edit User",
|
||||
"firstName": "First Name",
|
||||
"lastName": "Last Name",
|
||||
"username": "Username",
|
||||
"email": "Email",
|
||||
"password": "Password",
|
||||
"newPassword": "New Password (optional)",
|
||||
"passwordPlaceholder": "Leave blank to keep current password",
|
||||
"role": "Role",
|
||||
"roleUser": "User",
|
||||
"roleAdmin": "Admin",
|
||||
"create": "Create",
|
||||
"save": "Save"
|
||||
},
|
||||
"status": {
|
||||
"title": "Confirm Status Change",
|
||||
"confirmation": "Are you sure you want to {{action}} user {{firstName}} {{lastName}}?",
|
||||
"activate": "activate",
|
||||
"deactivate": "deactivate",
|
||||
"user": "User"
|
||||
},
|
||||
"header": {
|
||||
"title": "User Management",
|
||||
"addUser": "Add User",
|
||||
"management": "User Management"
|
||||
},
|
||||
"table": {
|
||||
"user": "USER",
|
||||
"email": "EMAIL",
|
||||
"status": "STATUS",
|
||||
"role": "ROLE",
|
||||
"actions": "ACTIONS",
|
||||
"active": "Active",
|
||||
"inactive": "Inactive",
|
||||
"admin": "Admin",
|
||||
"userr": "User"
|
||||
}
|
||||
},
|
||||
"logo": {
|
||||
"labels": {
|
||||
"appLogo": "App Logo"
|
||||
},
|
||||
"buttons": {
|
||||
"upload": "Upload Logo",
|
||||
"remove": "Remove Logo"
|
||||
},
|
||||
"messages": {
|
||||
"uploadSuccess": "Logo uploaded successfully",
|
||||
"removeSuccess": "Logo removed successfully"
|
||||
},
|
||||
"errors": {
|
||||
"uploadFailed": "Failed to upload logo",
|
||||
"removeFailed": "Failed to remove logo"
|
||||
}
|
||||
},
|
||||
"navbar": {
|
||||
"logoAlt": "App Logo",
|
||||
"profileMenu": "Profile Menu",
|
||||
"profile": "Profile",
|
||||
"settings": "Settings",
|
||||
"usersManagement": "Users Management",
|
||||
"logout": "Log Out"
|
||||
}
|
||||
}
|
638
apps/app/messages/es-ES.json
Normal file
638
apps/app/messages/es-ES.json
Normal file
@@ -0,0 +1,638 @@
|
||||
{
|
||||
"login": {
|
||||
"welcome": "Bienvenido a",
|
||||
"signInToContinue": "Inicia sesión para continuar",
|
||||
"emailLabel": "Dirección de correo electrónico",
|
||||
"emailPlaceholder": "Introduce tu correo electrónico",
|
||||
"passwordLabel": "Contraseña",
|
||||
"passwordPlaceholder": "Introduce tu contraseña",
|
||||
"signIn": "Iniciar sesión",
|
||||
"signingIn": "Iniciando sesión...",
|
||||
"forgotPassword": "¿Olvidaste tu contraseña?",
|
||||
"pageTitle": "Iniciar sesión"
|
||||
},
|
||||
"errors": {
|
||||
"invalidCredentials": "Correo electrónico o contraseña inválidos",
|
||||
"userNotFound": "Usuario no encontrado",
|
||||
"accountLocked": "Cuenta bloqueada. Por favor, inténtalo de nuevo más tarde",
|
||||
"unexpectedError": "Ocurrió un error inesperado. Por favor, inténtalo de nuevo"
|
||||
},
|
||||
"validation": {
|
||||
"invalidEmail": "Dirección de correo electrónico no válida",
|
||||
"passwordMinLength": "La contraseña debe tener al menos 6 caracteres",
|
||||
"firstNameRequired": "Se requiere el nombre",
|
||||
"lastNameRequired": "Se requiere el apellido",
|
||||
"usernameLength": "El nombre de usuario debe tener al menos 3 caracteres",
|
||||
"usernameSpaces": "El nombre de usuario no puede contener espacios",
|
||||
"passwordLength": "La contraseña debe tener al menos 8 caracteres",
|
||||
"passwordsMatch": "Las contraseñas no coinciden",
|
||||
"emailRequired": "Se requiere el correo electrónico",
|
||||
"passwordRequired": "Se requiere la contraseña"
|
||||
},
|
||||
"fileSelector": {
|
||||
"availableFiles": "Archivos disponibles ({{count}})",
|
||||
"shareFiles": "Compartir archivos ({{count}})",
|
||||
"searchPlaceholder": "Buscar archivos...",
|
||||
"noMatchingFiles": "No hay archivos que coincidan",
|
||||
"noAvailableFiles": "No hay archivos disponibles",
|
||||
"noFilesInShare": "No hay archivos compartidos",
|
||||
"saveChanges": "Guardar cambios"
|
||||
},
|
||||
"recipientSelector": {
|
||||
"emailPlaceholder": "Introduce el correo del destinatario",
|
||||
"add": "Agregar",
|
||||
"recipients": "Destinatarios ({{count}})",
|
||||
"notifyAll": "Notificar a todos",
|
||||
"noRecipients": "Aún no se han agregado destinatarios",
|
||||
"addSuccess": "Destinatario agregado exitosamente",
|
||||
"addError": "Error al agregar el destinatario",
|
||||
"removeSuccess": "Destinatario eliminado exitosamente",
|
||||
"removeError": "Error al eliminar el destinatario",
|
||||
"sendingNotifications": "Enviando notificaciones...",
|
||||
"notifySuccess": "Destinatarios notificados exitosamente",
|
||||
"notifyError": "Error al notificar a los destinatarios"
|
||||
},
|
||||
"navigation": {
|
||||
"dashboard": "Panel de control"
|
||||
},
|
||||
"common": {
|
||||
"loading": "Cargando, por favor espera...",
|
||||
"cancel": "Cancelar",
|
||||
"save": "Guardar",
|
||||
"delete": "Eliminar",
|
||||
"close": "Cerrar",
|
||||
"download": "Descargar",
|
||||
"unexpectedError": "Ocurrió un error inesperado. Por favor, inténtalo de nuevo.",
|
||||
"yes": "Sí",
|
||||
"no": "No",
|
||||
"dashboard": "Panel de control"
|
||||
},
|
||||
"createShare": {
|
||||
"title": "Crear compartición",
|
||||
"nameLabel": "Nombre de la compartición",
|
||||
"expirationLabel": "Fecha de expiración",
|
||||
"expirationPlaceholder": "MM/DD/AAAA HH:MM",
|
||||
"maxViewsLabel": "Máximo de visualizaciones",
|
||||
"maxViewsPlaceholder": "Dejar vacío para ilimitado",
|
||||
"passwordProtection": "Protección por contraseña",
|
||||
"passwordLabel": "Contraseña",
|
||||
"create": "Crear compartición",
|
||||
"success": "Compartición creada exitosamente",
|
||||
"error": "Error al crear la compartición"
|
||||
},
|
||||
"fileActions": {
|
||||
"editFile": "Editar archivo",
|
||||
"nameLabel": "Nombre",
|
||||
"namePlaceholder": "Introduce un nuevo nombre",
|
||||
"extension": "Extensión",
|
||||
"descriptionLabel": "Descripción",
|
||||
"descriptionPlaceholder": "Introduce una descripción del archivo",
|
||||
"deleteFile": "Eliminar archivo",
|
||||
"deleteConfirmation": "¿Estás seguro de que deseas eliminar \"{{fileName}}\"?",
|
||||
"deleteWarning": "Esta acción no se puede deshacer."
|
||||
},
|
||||
"filePreview": {
|
||||
"loading": "Cargando vista previa...",
|
||||
"notAvailable": "Vista previa no disponible",
|
||||
"downloadToView": "Descarga el archivo para ver su contenido",
|
||||
"audioNotSupported": "Tu navegador no soporta el elemento de audio",
|
||||
"videoNotSupported": "Tu navegador no soporta el elemento de video",
|
||||
"loadError": "Error al cargar la vista previa",
|
||||
"downloadError": "Error al descargar el archivo"
|
||||
},
|
||||
"generateShareLink": {
|
||||
"generateTitle": "Generar enlace de compartición",
|
||||
"updateTitle": "Actualizar enlace de compartición",
|
||||
"generateDescription": "Genera un enlace para compartir tus archivos",
|
||||
"updateDescription": "Actualiza el alias para este enlace de compartición",
|
||||
"aliasPlaceholder": "Introduce un alias",
|
||||
"linkReady": "Tu enlace de compartición está listo:",
|
||||
"generateButton": "Generar enlace",
|
||||
"updateButton": "Actualizar enlace",
|
||||
"copyButton": "Copiar enlace",
|
||||
"success": "Enlace generado exitosamente",
|
||||
"error": "Error al generar el enlace",
|
||||
"copied": "Enlace copiado al portapapeles"
|
||||
},
|
||||
"shareActions": {
|
||||
"deleteTitle": "Eliminar compartición",
|
||||
"deleteConfirmation": "¿Estás seguro de que deseas eliminar esta compartición? Esta acción no se puede deshacer.",
|
||||
"editTitle": "Editar compartición",
|
||||
"nameLabel": "Nombre de la compartición",
|
||||
"expirationLabel": "Fecha de expiración",
|
||||
"expirationPlaceholder": "MM/DD/AAAA HH:MM",
|
||||
"maxViewsLabel": "Máximo de visualizaciones",
|
||||
"maxViewsPlaceholder": "Dejar vacío para ilimitado",
|
||||
"passwordProtection": "Protegido con contraseña",
|
||||
"passwordLabel": "Contraseña",
|
||||
"passwordPlaceholder": "Introduce la contraseña",
|
||||
"newPasswordLabel": "Nueva contraseña (dejar vacío para mantener la actual)",
|
||||
"newPasswordPlaceholder": "Introduce la nueva contraseña",
|
||||
"manageFilesTitle": "Gestionar archivos",
|
||||
"manageRecipientsTitle": "Gestionar destinatarios",
|
||||
"editSuccess": "Compartición actualizada exitosamente",
|
||||
"editError": "Error al actualizar la compartición"
|
||||
},
|
||||
"shareDetails": {
|
||||
"title": "Detalles de la compartición",
|
||||
"subtitle": "Información detallada sobre esta compartición",
|
||||
"basicInfo": "Información básica",
|
||||
"name": "Nombre",
|
||||
"untitled": "Sin título",
|
||||
"views": "Visualizaciones",
|
||||
"dates": "Fechas",
|
||||
"created": "Creada",
|
||||
"expires": "Expira",
|
||||
"never": "Nunca",
|
||||
"security": "Seguridad",
|
||||
"passwordProtected": "Protegido con contraseña",
|
||||
"publicAccess": "Acceso público",
|
||||
"maxViews": "Máximo de visualizaciones: {{count}}",
|
||||
"files": "Archivos ({{count}})",
|
||||
"recipients": "Destinatarios ({{count}})",
|
||||
"notAvailable": "N/D",
|
||||
"invalidDate": "Fecha inválida",
|
||||
"loadError": "Error al cargar los detalles de la compartición"
|
||||
},
|
||||
"uploadFile": {
|
||||
"title": "Subir archivo",
|
||||
"selectFile": "Haz clic para seleccionar un archivo",
|
||||
"preview": "Vista previa",
|
||||
"uploadProgress": "Progreso de la subida",
|
||||
"upload": "Subir",
|
||||
"success": "Archivo subido exitosamente",
|
||||
"error": "Error al subir el archivo"
|
||||
},
|
||||
"filesTable": {
|
||||
"ariaLabel": "Tabla de archivos",
|
||||
"columns": {
|
||||
"name": "NOMBRE",
|
||||
"description": "DESCRIPCIÓN",
|
||||
"size": "TAMAÑO",
|
||||
"createdAt": "CREADO",
|
||||
"updatedAt": "ACTUALIZADO",
|
||||
"actions": "ACCIONES"
|
||||
},
|
||||
"actions": {
|
||||
"menu": "Menú de acciones del archivo",
|
||||
"preview": "Vista previa",
|
||||
"edit": "Editar",
|
||||
"download": "Descargar",
|
||||
"delete": "Eliminar"
|
||||
}
|
||||
},
|
||||
"sharesTable": {
|
||||
"ariaLabel": "Tabla de comparticiones",
|
||||
"never": "Nunca",
|
||||
"columns": {
|
||||
"name": "NOMBRE",
|
||||
"createdAt": "CREADO",
|
||||
"expiresAt": "EXPIRA",
|
||||
"status": "ESTADO",
|
||||
"security": "SEGURIDAD",
|
||||
"files": "ARCHIVOS",
|
||||
"recipients": "DESTINATARIOS",
|
||||
"actions": "ACCIONES"
|
||||
},
|
||||
"status": {
|
||||
"neverExpires": "Nunca expira",
|
||||
"active": "Activa",
|
||||
"expired": "Expirada"
|
||||
},
|
||||
"security": {
|
||||
"protected": "Protegida",
|
||||
"public": "Pública"
|
||||
},
|
||||
"filesCount": "{{count}} archivos",
|
||||
"recipientsCount": "{{count}} destinatarios",
|
||||
"actions": {
|
||||
"menu": "Menú de acciones de la compartición",
|
||||
"edit": "Editar",
|
||||
"manageFiles": "Gestionar archivos",
|
||||
"manageRecipients": "Gestionar destinatarios",
|
||||
"viewDetails": "Ver detalles",
|
||||
"generateLink": "Generar enlace",
|
||||
"editLink": "Editar enlace",
|
||||
"copyLink": "Copiar enlace",
|
||||
"notifyRecipients": "Notificar destinatarios",
|
||||
"delete": "Eliminar"
|
||||
}
|
||||
},
|
||||
"footer": {
|
||||
"poweredBy": "Desarrollado por",
|
||||
"kyanHomepage": "Página principal de Kyantech"
|
||||
},
|
||||
"fileManager": {
|
||||
"downloadError": "Error al descargar el archivo",
|
||||
"updateSuccess": "Archivo actualizado exitosamente",
|
||||
"updateError": "Error al actualizar el archivo",
|
||||
"deleteSuccess": "Archivo eliminado exitosamente",
|
||||
"deleteError": "Error al eliminar el archivo"
|
||||
},
|
||||
"shareManager": {
|
||||
"deleteSuccess": "Compartición eliminada exitosamente",
|
||||
"deleteError": "Error al eliminar la compartición",
|
||||
"updateSuccess": "Compartición actualizada exitosamente",
|
||||
"updateError": "Error al actualizar la compartición",
|
||||
"filesUpdateSuccess": "Archivos actualizados exitosamente",
|
||||
"filesUpdateError": "Error al actualizar los archivos",
|
||||
"recipientsUpdateSuccess": "Destinatarios actualizados exitosamente",
|
||||
"recipientsUpdateError": "Error al actualizar los destinatarios",
|
||||
"linkGenerateSuccess": "Enlace de compartición generado exitosamente",
|
||||
"linkGenerateError": "Error al generar el enlace de compartición",
|
||||
"notifyLoading": "Enviando notificaciones...",
|
||||
"notifySuccess": "Destinatarios notificados exitosamente",
|
||||
"notifyError": "Error al notificar a los destinatarios"
|
||||
},
|
||||
"quickAccess": {
|
||||
"files": {
|
||||
"title": "Mis archivos",
|
||||
"description": "Accede y gestiona tus archivos subidos"
|
||||
},
|
||||
"shares": {
|
||||
"title": "Mis comparticiones",
|
||||
"description": "Visualiza y gestiona tus archivos compartidos"
|
||||
}
|
||||
},
|
||||
"recentFiles": {
|
||||
"title": "Subidas recientes",
|
||||
"viewAll": "Ver todo",
|
||||
"uploadFile": "Subir archivo",
|
||||
"noFiles": "Aún no se han subido archivos"
|
||||
},
|
||||
"recentShares": {
|
||||
"title": "Comparticiones recientes",
|
||||
"viewAll": "Ver todo",
|
||||
"createShare": "Crear compartición",
|
||||
"noShares": "Aún no se han creado comparticiones",
|
||||
"createFirst": "Crea tu primera compartición"
|
||||
},
|
||||
"storageUsage": {
|
||||
"title": "Uso de almacenamiento",
|
||||
"ariaLabel": "Barra de progreso del uso de almacenamiento",
|
||||
"used": "{{size}} usados",
|
||||
"available": "{{size}} disponibles"
|
||||
},
|
||||
"dashboard": {
|
||||
"loadError": "Error al cargar los datos del tablero",
|
||||
"linkCopied": "Enlace copiado al portapapeles",
|
||||
"pageTitle": "Panel de control",
|
||||
"breadcrumb": "Panel de control"
|
||||
},
|
||||
"emptyState": {
|
||||
"noFiles": "Aún no se han subido archivos",
|
||||
"uploadFile": "Subir archivo"
|
||||
},
|
||||
"files": {
|
||||
"title": "Todos los archivos",
|
||||
"uploadFile": "Subir archivo",
|
||||
"loadError": "Error al cargar los archivos",
|
||||
"pageTitle": "Mis archivos",
|
||||
"breadcrumb": "Mis archivos"
|
||||
},
|
||||
"searchBar": {
|
||||
"placeholder": "Buscar archivos...",
|
||||
"results": "Se encontraron {{filtered}} de {{total}} archivos"
|
||||
},
|
||||
"forgotPassword": {
|
||||
"emailLabel": "Dirección de correo electrónico",
|
||||
"emailPlaceholder": "Introduce tu correo electrónico",
|
||||
"sending": "Enviando...",
|
||||
"submit": "Enviar instrucciones de restablecimiento",
|
||||
"backToLogin": "Volver a iniciar sesión",
|
||||
"title": "Recuperar contraseña",
|
||||
"description": "Introduce tu dirección de correo electrónico y te enviaremos instrucciones para restablecer tu contraseña.",
|
||||
"resetInstructions": "Instrucciones de restablecimiento enviadas a tu correo electrónico",
|
||||
"pageTitle": "Recuperar contraseña"
|
||||
},
|
||||
"home": {
|
||||
"description": "La alternativa de código abierto a WeTransfer. Comparte archivos de forma segura, sin rastreo ni limitaciones.",
|
||||
"documentation": "Documentación",
|
||||
"starOnGithub": "Dale una estrella en GitHub",
|
||||
"privacyMessage": "Construido con la privacidad en mente. Tus archivos antes de la subida son accesibles solo para aquellos con el enlace de compartición. Siempre libre y de código abierto.",
|
||||
"header": {
|
||||
"fileSharing": "Compartir archivos",
|
||||
"tagline": "simple y gratuito"
|
||||
},
|
||||
"pageTitle": "Inicio"
|
||||
},
|
||||
"profile": {
|
||||
"password": {
|
||||
"title": "Cambiar contraseña",
|
||||
"newPassword": "Nueva contraseña",
|
||||
"confirmPassword": "Confirmar nueva contraseña",
|
||||
"updateButton": "Actualizar contraseña"
|
||||
},
|
||||
"form": {
|
||||
"title": "Información del perfil",
|
||||
"firstName": "Nombre",
|
||||
"lastName": "Apellido",
|
||||
"username": "Nombre de usuario",
|
||||
"email": "Correo electrónico",
|
||||
"updateButton": "Actualizar perfil"
|
||||
},
|
||||
"header": {
|
||||
"title": "Perfil",
|
||||
"subtitle": "Gestiona tu información personal y contraseña"
|
||||
},
|
||||
"picture": {
|
||||
"title": "Foto de perfil",
|
||||
"description": "Haz clic en el icono de la cámara para cambiar tu foto de perfil",
|
||||
"uploadPhoto": "Subir foto",
|
||||
"removePhoto": "Eliminar foto"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "Error al cargar los datos del usuario",
|
||||
"updateFailed": "Error al actualizar el perfil",
|
||||
"passwordFailed": "Error al actualizar la contraseña",
|
||||
"imageFailed": "Error al actualizar la imagen del perfil",
|
||||
"imageRemoveFailed": "Error al eliminar la imagen del perfil"
|
||||
},
|
||||
"messages": {
|
||||
"noChanges": "No hay cambios para guardar",
|
||||
"updateSuccess": "Perfil actualizado exitosamente",
|
||||
"fillPasswords": "Por favor, completa ambos campos de contraseña",
|
||||
"passwordSuccess": "Contraseña actualizada exitosamente",
|
||||
"imageSuccess": "Imagen de perfil actualizada exitosamente",
|
||||
"imageRemoved": "Imagen de perfil eliminada exitosamente"
|
||||
},
|
||||
"pageTitle": "Perfil"
|
||||
},
|
||||
"resetPassword": {
|
||||
"pageTitle": "Restablecer contraseña",
|
||||
"header": {
|
||||
"title": "Restablecer contraseña",
|
||||
"description": "Introduce tu nueva contraseña abajo"
|
||||
},
|
||||
"form": {
|
||||
"newPassword": "Nueva contraseña",
|
||||
"newPasswordPlaceholder": "Introduce tu nueva contraseña",
|
||||
"confirmPassword": "Confirmar nueva contraseña",
|
||||
"confirmPasswordPlaceholder": "Confirma tu nueva contraseña",
|
||||
"resetting": "Restableciendo contraseña...",
|
||||
"submit": "Restablecer contraseña",
|
||||
"backToLogin": "Volver a iniciar sesión"
|
||||
},
|
||||
"messages": {
|
||||
"success": "Contraseña restablecida exitosamente"
|
||||
},
|
||||
"errors": {
|
||||
"serverError": "Error al restablecer la contraseña. Por favor, inténtalo de nuevo.",
|
||||
"invalidToken": "Token de restablecimiento inválido o ausente"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"groups": {
|
||||
"defaultDescription": "Opciones de configuración",
|
||||
"general": {
|
||||
"title": "General",
|
||||
"description": "Configuraciones básicas de la aplicación"
|
||||
},
|
||||
"email": {
|
||||
"title": "Correo electrónico",
|
||||
"description": "Configuración del servidor de correo electrónico"
|
||||
},
|
||||
"security": {
|
||||
"title": "Seguridad",
|
||||
"description": "Configuraciones de seguridad y autenticación"
|
||||
},
|
||||
"storage": {
|
||||
"title": "Almacenamiento",
|
||||
"description": "Configuración del almacenamiento de archivos"
|
||||
}
|
||||
},
|
||||
"fields": {
|
||||
"noDescription": "No hay descripción disponible",
|
||||
"appLogo": {
|
||||
"title": "Logo de la aplicación",
|
||||
"description": "Imagen del logo de la aplicación"
|
||||
},
|
||||
"appName": {
|
||||
"title": "Nombre de la aplicación",
|
||||
"description": "Nombre de la aplicación mostrado a los usuarios"
|
||||
},
|
||||
"appDescription": {
|
||||
"title": "Descripción de la aplicación",
|
||||
"description": "Breve descripción de la aplicación"
|
||||
},
|
||||
"showHomePage": {
|
||||
"title": "Mostrar página de inicio",
|
||||
"description": "Mostrar la página de inicio después de la instalación"
|
||||
},
|
||||
"smtpEnabled": {
|
||||
"title": "SMTP activado",
|
||||
"description": "Habilitar o deshabilitar la funcionalidad de correo electrónico SMTP"
|
||||
},
|
||||
"smtpHost": {
|
||||
"title": "Servidor SMTP",
|
||||
"description": "Dirección del servidor SMTP"
|
||||
},
|
||||
"smtpPort": {
|
||||
"title": "Puerto SMTP",
|
||||
"description": "Puerto del servidor SMTP"
|
||||
},
|
||||
"smtpUser": {
|
||||
"title": "Usuario SMTP",
|
||||
"description": "Nombre de usuario para la autenticación SMTP"
|
||||
},
|
||||
"smtpPass": {
|
||||
"title": "Contraseña SMTP",
|
||||
"description": "Contraseña para la autenticación SMTP"
|
||||
},
|
||||
"smtpFromName": {
|
||||
"title": "Nombre del remitente",
|
||||
"description": "Nombre mostrado para los correos enviados"
|
||||
},
|
||||
"smtpFromEmail": {
|
||||
"title": "Correo del remitente",
|
||||
"description": "Dirección de correo del remitente"
|
||||
},
|
||||
"maxLoginAttempts": {
|
||||
"title": "Máximo de intentos de inicio de sesión",
|
||||
"description": "Número máximo de intentos antes de bloquear"
|
||||
},
|
||||
"loginBlockDuration": {
|
||||
"title": "Duración del bloqueo",
|
||||
"description": "Duración (en segundos) del bloqueo tras exceder los intentos"
|
||||
},
|
||||
"passwordMinLength": {
|
||||
"title": "Longitud mínima de contraseña",
|
||||
"description": "Número mínimo de caracteres para las contraseñas"
|
||||
},
|
||||
"passwordResetTokenExpiration": {
|
||||
"title": "Expiración del token de restablecimiento",
|
||||
"description": "Tiempo de validez (en segundos) para el token de restablecimiento de contraseña"
|
||||
},
|
||||
"maxFileSize": {
|
||||
"title": "Tamaño máximo de archivo",
|
||||
"description": "Tamaño máximo permitido para subir archivos (en bytes)"
|
||||
},
|
||||
"maxTotalStoragePerUser": {
|
||||
"title": "Almacenamiento máximo por usuario",
|
||||
"description": "Límite total de almacenamiento por usuario (en bytes)"
|
||||
}
|
||||
},
|
||||
"buttons": {
|
||||
"save": "Guardar {{group}}"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "Error al cargar la configuración",
|
||||
"updateFailed": "Error al actualizar la configuración"
|
||||
},
|
||||
"messages": {
|
||||
"noChanges": "No hay cambios para guardar",
|
||||
"updateSuccess": "Configuración de {{group}} actualizada exitosamente"
|
||||
},
|
||||
"title": "Configuración",
|
||||
"breadcrumb": "Configuración",
|
||||
"pageTitle": "Configuración"
|
||||
},
|
||||
"share": {
|
||||
"errors": {
|
||||
"invalidPassword": "Contraseña inválida. Por favor, inténtalo de nuevo.",
|
||||
"loadFailed": "Error al cargar la compartición",
|
||||
"downloadFailed": "Error al descargar el archivo"
|
||||
},
|
||||
"messages": {
|
||||
"downloadStarted": "Descarga iniciada"
|
||||
},
|
||||
"password": {
|
||||
"title": "Compartición protegida por contraseña",
|
||||
"protected": "Esta compartición está protegida por contraseña",
|
||||
"incorrect": "Contraseña incorrecta. Por favor, inténtalo de nuevo.",
|
||||
"label": "Contraseña",
|
||||
"placeholder": "Introduce la contraseña de la compartición",
|
||||
"submit": "Enviar"
|
||||
},
|
||||
"details": {
|
||||
"untitled": "Compartición sin título",
|
||||
"created": "Creada: {{date}}",
|
||||
"expires": "Expira: {{date}}"
|
||||
},
|
||||
"notFound": {
|
||||
"title": "Compartición no encontrada",
|
||||
"description": "Esta compartición puede haber sido eliminada o haber expirado."
|
||||
},
|
||||
"pageTitle": "Compartición"
|
||||
},
|
||||
"shares": {
|
||||
"errors": {
|
||||
"loadFailed": "Error al cargar las comparticiones",
|
||||
"notifyFailed": "Error al notificar a los destinatarios",
|
||||
"smtpConfigFailed": "Error al cargar la configuración SMTP"
|
||||
},
|
||||
"messages": {
|
||||
"linkCopied": "Enlace copiado al portapapeles",
|
||||
"recipientsNotified": "Destinatarios notificados exitosamente"
|
||||
},
|
||||
"empty": {
|
||||
"message": "Aún no se han creado comparticiones",
|
||||
"createButton": "Crear compartición"
|
||||
},
|
||||
"header": {
|
||||
"title": "Mis comparticiones",
|
||||
"myShares": "Mis comparticiones"
|
||||
},
|
||||
"search": {
|
||||
"title": "Todas las comparticiones",
|
||||
"createButton": "Crear compartición",
|
||||
"placeholder": "Buscar comparticiones...",
|
||||
"results": "Se encontraron {{filtered}} de {{total}} comparticiones"
|
||||
},
|
||||
"pageTitle": "Comparticiones"
|
||||
},
|
||||
"users": {
|
||||
"modes": {
|
||||
"create": "crear",
|
||||
"edit": "editar"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "Error al cargar los usuarios",
|
||||
"submitFailed": "Error al {{mode}} el usuario",
|
||||
"deleteFailed": "Error al eliminar el usuario",
|
||||
"statusUpdateFailed": "Error al actualizar el estado del usuario"
|
||||
},
|
||||
"messages": {
|
||||
"createSuccess": "Usuario creado exitosamente",
|
||||
"updateSuccess": "Usuario actualizado exitosamente",
|
||||
"deleteSuccess": "Usuario eliminado exitosamente",
|
||||
"activateSuccess": "Usuario activado exitosamente",
|
||||
"deactivateSuccess": "Usuario desactivado exitosamente"
|
||||
},
|
||||
"actions": {
|
||||
"edit": "Editar",
|
||||
"activate": "Activar",
|
||||
"deactivate": "Desactivar",
|
||||
"delete": "Eliminar"
|
||||
},
|
||||
"delete": {
|
||||
"title": "Confirmar eliminación del usuario",
|
||||
"confirmation": "¿Estás seguro de que deseas eliminar al usuario {{firstName}} {{lastName}}? Esta acción no se puede deshacer.",
|
||||
"confirm": "Eliminar usuario"
|
||||
},
|
||||
"form": {
|
||||
"titleCreate": "Agregar nuevo usuario",
|
||||
"titleEdit": "Editar usuario",
|
||||
"firstName": "Nombre",
|
||||
"lastName": "Apellido",
|
||||
"username": "Nombre de usuario",
|
||||
"email": "Correo electrónico",
|
||||
"password": "Contraseña",
|
||||
"newPassword": "Nueva contraseña (opcional)",
|
||||
"passwordPlaceholder": "Dejar en blanco para mantener la contraseña actual",
|
||||
"role": "Rol",
|
||||
"roleUser": "Usuario",
|
||||
"roleAdmin": "Administrador",
|
||||
"create": "Crear",
|
||||
"save": "Guardar"
|
||||
},
|
||||
"status": {
|
||||
"title": "Confirmar cambio de estado",
|
||||
"confirmation": "¿Estás seguro de que deseas {{action}} al usuario {{firstName}} {{lastName}}?",
|
||||
"activate": "activar",
|
||||
"deactivate": "desactivar",
|
||||
"user": "Usuario"
|
||||
},
|
||||
"header": {
|
||||
"title": "Gestión de usuarios",
|
||||
"addUser": "Agregar usuario",
|
||||
"management": "Gestión de usuarios"
|
||||
},
|
||||
"table": {
|
||||
"user": "USUARIO",
|
||||
"email": "CORREO",
|
||||
"status": "ESTADO",
|
||||
"role": "ROL",
|
||||
"actions": "ACCIONES",
|
||||
"active": "Activo",
|
||||
"inactive": "Inactivo",
|
||||
"admin": "Administrador",
|
||||
"userr": "Usuario"
|
||||
}
|
||||
},
|
||||
"logo": {
|
||||
"labels": {
|
||||
"appLogo": "Logo de la aplicación"
|
||||
},
|
||||
"buttons": {
|
||||
"upload": "Subir logo",
|
||||
"remove": "Eliminar logo"
|
||||
},
|
||||
"messages": {
|
||||
"uploadSuccess": "Logo subido exitosamente",
|
||||
"removeSuccess": "Logo eliminado exitosamente"
|
||||
},
|
||||
"errors": {
|
||||
"uploadFailed": "Error al subir el logo",
|
||||
"removeFailed": "Error al eliminar el logo"
|
||||
}
|
||||
},
|
||||
"navbar": {
|
||||
"logoAlt": "Logo de la aplicación",
|
||||
"profileMenu": "Menú de perfil",
|
||||
"profile": "Perfil",
|
||||
"settings": "Configuración",
|
||||
"usersManagement": "Gestión de usuarios",
|
||||
"logout": "Cerrar sesión"
|
||||
}
|
||||
}
|
637
apps/app/messages/fr-FR.json
Normal file
637
apps/app/messages/fr-FR.json
Normal file
@@ -0,0 +1,637 @@
|
||||
{
|
||||
"login": {
|
||||
"welcome": "Bienvenue à",
|
||||
"signInToContinue": "Connectez-vous pour continuer",
|
||||
"emailLabel": "Adresse e-mail",
|
||||
"emailPlaceholder": "Entrez votre e-mail",
|
||||
"passwordLabel": "Mot de passe",
|
||||
"passwordPlaceholder": "Entrez votre mot de passe",
|
||||
"signIn": "Se connecter",
|
||||
"signingIn": "Connexion en cours...",
|
||||
"forgotPassword": "Mot de passe oublié ?",
|
||||
"pageTitle": "Connexion"
|
||||
},
|
||||
"errors": {
|
||||
"invalidCredentials": "E-mail ou mot de passe invalide",
|
||||
"userNotFound": "Utilisateur non trouvé",
|
||||
"accountLocked": "Compte bloqué. Veuillez réessayer plus tard",
|
||||
"unexpectedError": "Une erreur inattendue s'est produite. Veuillez réessayer"
|
||||
},
|
||||
"validation": {
|
||||
"invalidEmail": "Adresse email invalide",
|
||||
"passwordMinLength": "Le mot de passe doit contenir au moins 6 caractères",
|
||||
"firstNameRequired": "Le prénom est requis",
|
||||
"lastNameRequired": "Le nom est requis",
|
||||
"usernameLength": "Le nom d'utilisateur doit contenir au moins 3 caractères",
|
||||
"usernameSpaces": "Le nom d'utilisateur ne peut pas contenir d'espaces",
|
||||
"passwordLength": "Le mot de passe doit contenir au moins 8 caractères",
|
||||
"passwordsMatch": "Les mots de passe ne correspondent pas",
|
||||
"emailRequired": "L'email est requis",
|
||||
"passwordRequired": "Le mot de passe est requis"
|
||||
},
|
||||
"fileSelector": {
|
||||
"availableFiles": "Fichiers Disponibles ({{count}})",
|
||||
"shareFiles": "Fichiers Partagés ({{count}})",
|
||||
"searchPlaceholder": "Rechercher des fichiers...",
|
||||
"noMatchingFiles": "Aucun fichier correspondant",
|
||||
"noAvailableFiles": "Aucun fichier disponible",
|
||||
"noFilesInShare": "Aucun fichier partagé",
|
||||
"saveChanges": "Enregistrer les Modifications"
|
||||
},
|
||||
"recipientSelector": {
|
||||
"emailPlaceholder": "Entrez l'e-mail du destinataire",
|
||||
"add": "Ajouter",
|
||||
"recipients": "Destinataires ({{count}})",
|
||||
"notifyAll": "Notifier Tous",
|
||||
"noRecipients": "Aucun destinataire ajouté",
|
||||
"addSuccess": "Destinataire ajouté avec succès",
|
||||
"addError": "Échec de l'ajout du destinataire",
|
||||
"removeSuccess": "Destinataire supprimé avec succès",
|
||||
"removeError": "Échec de la suppression du destinataire",
|
||||
"sendingNotifications": "Envoi des notifications...",
|
||||
"notifySuccess": "Destinataires notifiés avec succès",
|
||||
"notifyError": "Échec de la notification des destinataires"
|
||||
},
|
||||
"navigation": {
|
||||
"dashboard": "Tableau de bord"
|
||||
},
|
||||
"common": {
|
||||
"loading": "Chargement, veuillez patienter...",
|
||||
"cancel": "Annuler",
|
||||
"save": "Enregistrer",
|
||||
"delete": "Supprimer",
|
||||
"close": "Fermer",
|
||||
"download": "Télécharger",
|
||||
"unexpectedError": "Une erreur inattendue s'est produite. Veuillez réessayer.",
|
||||
"yes": "Oui",
|
||||
"no": "Non",
|
||||
"dashboard": "Tableau de Bord"
|
||||
},
|
||||
"createShare": {
|
||||
"title": "Créer un Partage",
|
||||
"nameLabel": "Nom du Partage",
|
||||
"expirationLabel": "Date d'Expiration",
|
||||
"expirationPlaceholder": "JJ/MM/AAAA HH:MM",
|
||||
"maxViewsLabel": "Vues Maximales",
|
||||
"maxViewsPlaceholder": "Laisser vide pour illimité",
|
||||
"passwordProtection": "Protégé par Mot de Passe",
|
||||
"passwordLabel": "Mot de Passe",
|
||||
"create": "Créer le Partage",
|
||||
"success": "Partage créé avec succès",
|
||||
"error": "Échec de la création du partage"
|
||||
},
|
||||
"fileActions": {
|
||||
"editFile": "Modifier le Fichier",
|
||||
"nameLabel": "Nom",
|
||||
"namePlaceholder": "Entrez le nouveau nom",
|
||||
"extension": "Extension",
|
||||
"descriptionLabel": "Description",
|
||||
"descriptionPlaceholder": "Entrez la description du fichier",
|
||||
"deleteFile": "Supprimer le Fichier",
|
||||
"deleteConfirmation": "Êtes-vous sûr de vouloir supprimer \"{{fileName}}\" ?",
|
||||
"deleteWarning": "Cette action ne peut pas être annulée."
|
||||
},
|
||||
"filePreview": {
|
||||
"loading": "Chargement de l'aperçu...",
|
||||
"notAvailable": "Aperçu non disponible",
|
||||
"downloadToView": "Téléchargez le fichier pour voir le contenu",
|
||||
"audioNotSupported": "Votre navigateur ne prend pas en charge l'élément audio",
|
||||
"videoNotSupported": "Votre navigateur ne prend pas en charge l'élément vidéo",
|
||||
"loadError": "Échec du chargement de l'aperçu",
|
||||
"downloadError": "Échec du téléchargement du fichier"
|
||||
},
|
||||
"generateShareLink": {
|
||||
"generateTitle": "Générer un Lien de Partage",
|
||||
"updateTitle": "Mettre à Jour le Lien de Partage",
|
||||
"generateDescription": "Générez un lien pour partager vos fichiers",
|
||||
"updateDescription": "Mettez à jour l'alias de ce lien de partage",
|
||||
"aliasPlaceholder": "Entrez l'alias",
|
||||
"linkReady": "Votre lien de partage est prêt :",
|
||||
"generateButton": "Générer le Lien",
|
||||
"updateButton": "Mettre à Jour le Lien",
|
||||
"copyButton": "Copier le Lien",
|
||||
"success": "Lien généré avec succès",
|
||||
"error": "Échec de la génération du lien",
|
||||
"copied": "Lien copié dans le presse-papiers"
|
||||
},
|
||||
"shareActions": {
|
||||
"deleteTitle": "Supprimer le Partage",
|
||||
"deleteConfirmation": "Êtes-vous sûr de vouloir supprimer ce partage ? Cette action ne peut pas être annulée.",
|
||||
"editTitle": "Modifier le Partage",
|
||||
"nameLabel": "Nom du Partage",
|
||||
"expirationLabel": "Date d'Expiration",
|
||||
"expirationPlaceholder": "JJ/MM/AAAA HH:MM",
|
||||
"maxViewsLabel": "Vues Maximales",
|
||||
"maxViewsPlaceholder": "Laisser vide pour illimité",
|
||||
"passwordProtection": "Protégé par Mot de Passe",
|
||||
"passwordLabel": "Mot de Passe",
|
||||
"passwordPlaceholder": "Entrez le mot de passe",
|
||||
"newPasswordLabel": "Nouveau Mot de Passe (laisser vide pour garder l'actuel)",
|
||||
"newPasswordPlaceholder": "Entrez le nouveau mot de passe",
|
||||
"manageFilesTitle": "Gérer les Fichiers",
|
||||
"manageRecipientsTitle": "Gérer les Destinataires",
|
||||
"editSuccess": "Partage mis à jour avec succès",
|
||||
"editError": "Échec de la mise à jour du partage"
|
||||
},
|
||||
"shareDetails": {
|
||||
"title": "Détails du Partage",
|
||||
"subtitle": "Informations détaillées sur ce partage",
|
||||
"basicInfo": "Informations de Base",
|
||||
"name": "Nom",
|
||||
"untitled": "Partage sans titre",
|
||||
"views": "Vues",
|
||||
"dates": "Dates",
|
||||
"created": "Créé le: {{date}}",
|
||||
"expires": "Expire le: {{date}}",
|
||||
"never": "Jamais",
|
||||
"security": "Sécurité",
|
||||
"passwordProtected": "Protégé par Mot de Passe",
|
||||
"publicAccess": "Accès Public",
|
||||
"maxViews": "Vues Maximales : {{count}}",
|
||||
"files": "Fichiers ({{count}})",
|
||||
"recipients": "Destinataires ({{count}})",
|
||||
"notAvailable": "N/D",
|
||||
"invalidDate": "Date invalide",
|
||||
"loadError": "Échec du chargement des détails du partage"
|
||||
},
|
||||
"uploadFile": {
|
||||
"title": "Envoyer un Fichier",
|
||||
"selectFile": "Cliquez pour sélectionner un fichier",
|
||||
"preview": "Aperçu",
|
||||
"uploadProgress": "Progression de l'envoi",
|
||||
"upload": "Envoyer",
|
||||
"success": "Fichier envoyé avec succès",
|
||||
"error": "Échec de l'envoi du fichier"
|
||||
},
|
||||
"filesTable": {
|
||||
"ariaLabel": "Tableau des fichiers",
|
||||
"columns": {
|
||||
"name": "NOM",
|
||||
"description": "DESCRIPTION",
|
||||
"size": "TAILLE",
|
||||
"createdAt": "CRÉÉ LE",
|
||||
"updatedAt": "MODIFIÉ LE",
|
||||
"actions": "ACTIONS"
|
||||
},
|
||||
"actions": {
|
||||
"menu": "Menu d'actions du fichier",
|
||||
"preview": "Aperçu",
|
||||
"edit": "Modifier",
|
||||
"download": "Télécharger",
|
||||
"delete": "Supprimer"
|
||||
}
|
||||
},
|
||||
"sharesTable": {
|
||||
"ariaLabel": "Tableau des partages",
|
||||
"never": "Jamais",
|
||||
"columns": {
|
||||
"name": "NOM",
|
||||
"createdAt": "CRÉÉ LE",
|
||||
"expiresAt": "EXPIRE LE",
|
||||
"status": "STATUT",
|
||||
"security": "SÉCURITÉ",
|
||||
"files": "FICHIERS",
|
||||
"recipients": "DESTINATAIRES",
|
||||
"actions": "ACTIONS"
|
||||
},
|
||||
"status": {
|
||||
"neverExpires": "N'expire Jamais",
|
||||
"active": "Actif",
|
||||
"expired": "Expiré"
|
||||
},
|
||||
"security": {
|
||||
"protected": "Protégé",
|
||||
"public": "Public"
|
||||
},
|
||||
"filesCount": "{{count}} fichiers",
|
||||
"recipientsCount": "{{count}} destinataires",
|
||||
"actions": {
|
||||
"menu": "Menu d'actions du partage",
|
||||
"edit": "Modifier",
|
||||
"manageFiles": "Gérer les Fichiers",
|
||||
"manageRecipients": "Gérer les Destinataires",
|
||||
"viewDetails": "Voir les Détails",
|
||||
"generateLink": "Générer un Lien",
|
||||
"editLink": "Modifier le Lien",
|
||||
"copyLink": "Copier le Lien",
|
||||
"notifyRecipients": "Notifier les Destinataires",
|
||||
"delete": "Supprimer"
|
||||
}
|
||||
},
|
||||
"footer": {
|
||||
"poweredBy": "Propulsé par",
|
||||
"kyanHomepage": "Page d'accueil de Kyantech"
|
||||
},
|
||||
"fileManager": {
|
||||
"downloadError": "Échec du téléchargement du fichier",
|
||||
"updateSuccess": "Fichier mis à jour avec succès",
|
||||
"updateError": "Échec de la mise à jour du fichier",
|
||||
"deleteSuccess": "Fichier supprimé avec succès",
|
||||
"deleteError": "Échec de la suppression du fichier"
|
||||
},
|
||||
"shareManager": {
|
||||
"deleteSuccess": "Partage supprimé avec succès",
|
||||
"deleteError": "Échec de la suppression du partage",
|
||||
"updateSuccess": "Partage mis à jour avec succès",
|
||||
"updateError": "Échec de la mise à jour du partage",
|
||||
"filesUpdateSuccess": "Fichiers mis à jour avec succès",
|
||||
"filesUpdateError": "Échec de la mise à jour des fichiers",
|
||||
"recipientsUpdateSuccess": "Destinataires mis à jour avec succès",
|
||||
"recipientsUpdateError": "Échec de la mise à jour des destinataires",
|
||||
"linkGenerateSuccess": "Lien de partage généré avec succès",
|
||||
"linkGenerateError": "Échec de la génération du lien de partage",
|
||||
"notifyLoading": "Envoi des notifications...",
|
||||
"notifySuccess": "Destinataires notifiés avec succès",
|
||||
"notifyError": "Échec de la notification des destinataires"
|
||||
},
|
||||
"quickAccess": {
|
||||
"files": {
|
||||
"title": "Mes Fichiers",
|
||||
"description": "Accédez et gérez vos fichiers téléchargés"
|
||||
},
|
||||
"shares": {
|
||||
"title": "Mes Partages",
|
||||
"description": "Visualisez et gérez vos fichiers partagés"
|
||||
}
|
||||
},
|
||||
"recentFiles": {
|
||||
"title": "Téléchargements Récents",
|
||||
"viewAll": "Voir Tout",
|
||||
"uploadFile": "Envoyer un Fichier",
|
||||
"noFiles": "Aucun fichier téléchargé pour le moment"
|
||||
},
|
||||
"recentShares": {
|
||||
"title": "Partages Récents",
|
||||
"viewAll": "Voir Tout",
|
||||
"createShare": "Créer un Partage",
|
||||
"noShares": "Aucun partage créé pour le moment",
|
||||
"createFirst": "Créer votre premier partage"
|
||||
},
|
||||
"storageUsage": {
|
||||
"title": "Utilisation du Stockage",
|
||||
"ariaLabel": "Barre de progression de l'utilisation du stockage",
|
||||
"used": "{{size}} utilisé",
|
||||
"available": "{{size}} disponible"
|
||||
},
|
||||
"dashboard": {
|
||||
"loadError": "Échec du chargement des données du tableau de bord",
|
||||
"linkCopied": "Lien copié dans le presse-papiers",
|
||||
"pageTitle": "Tableau de Bord",
|
||||
"breadcrumb": "Tableau de Bord"
|
||||
},
|
||||
"emptyState": {
|
||||
"noFiles": "Aucun fichier téléchargé pour le moment",
|
||||
"uploadFile": "Envoyer un Fichier"
|
||||
},
|
||||
"files": {
|
||||
"title": "Tous les Fichiers",
|
||||
"uploadFile": "Envoyer un Fichier",
|
||||
"loadError": "Échec du chargement des fichiers",
|
||||
"pageTitle": "Mes Fichiers",
|
||||
"breadcrumb": "Mes Fichiers"
|
||||
},
|
||||
"searchBar": {
|
||||
"placeholder": "Rechercher des fichiers...",
|
||||
"results": "Trouvé {{filtered}} sur {{total}} fichiers"
|
||||
},
|
||||
"forgotPassword": {
|
||||
"emailLabel": "Adresse Email",
|
||||
"emailPlaceholder": "Entrez votre email",
|
||||
"sending": "Envoi en cours...",
|
||||
"submit": "Envoyer les Instructions",
|
||||
"backToLogin": "Retour à la Connexion",
|
||||
"title": "Mot de Passe Oublié",
|
||||
"description": "Entrez votre adresse email et nous vous enverrons les instructions pour réinitialiser votre mot de passe.",
|
||||
"resetInstructions": "Instructions de réinitialisation envoyées à votre email",
|
||||
"pageTitle": "Mot de Passe Oublié"
|
||||
},
|
||||
"home": {
|
||||
"description": "L'alternative open-source à WeTransfer. Partagez des fichiers en toute sécurité, sans suivi ni limitations.",
|
||||
"documentation": "Documentation",
|
||||
"starOnGithub": "Star sur GitHub",
|
||||
"privacyMessage": "Conçu avec la confidentialité à l'esprit. Vos fichiers avant téléchargement ne sont accessibles que par ceux ayant le lien de partage. Gratuit et open source pour toujours.",
|
||||
"header": {
|
||||
"fileSharing": "Partage de fichiers",
|
||||
"tagline": "simple et gratuit"
|
||||
},
|
||||
"pageTitle": "Accueil"
|
||||
},
|
||||
"profile": {
|
||||
"password": {
|
||||
"title": "Changer le Mot de Passe",
|
||||
"newPassword": "Nouveau Mot de Passe",
|
||||
"confirmPassword": "Confirmer le Nouveau Mot de Passe",
|
||||
"updateButton": "Mettre à Jour le Mot de Passe"
|
||||
},
|
||||
"form": {
|
||||
"title": "Informations du Profil",
|
||||
"firstName": "Prénom",
|
||||
"lastName": "Nom",
|
||||
"username": "Nom d'Utilisateur",
|
||||
"email": "Email",
|
||||
"updateButton": "Mettre à Jour le Profil"
|
||||
},
|
||||
"header": {
|
||||
"title": "Profil",
|
||||
"subtitle": "Gérez vos informations personnelles et votre mot de passe"
|
||||
},
|
||||
"picture": {
|
||||
"title": "Photo de Profil",
|
||||
"description": "Cliquez sur l'icône de l'appareil photo pour changer votre photo de profil",
|
||||
"uploadPhoto": "Télécharger une Photo",
|
||||
"removePhoto": "Supprimer la Photo"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "Échec du chargement des données utilisateur",
|
||||
"updateFailed": "Échec de la mise à jour du profil",
|
||||
"passwordFailed": "Échec de la mise à jour du mot de passe",
|
||||
"imageFailed": "Échec de la mise à jour de l'image",
|
||||
"imageRemoveFailed": "Échec de la suppression de l'image"
|
||||
},
|
||||
"messages": {
|
||||
"noChanges": "Aucun changement à enregistrer",
|
||||
"updateSuccess": "Profil mis à jour avec succès",
|
||||
"fillPasswords": "Veuillez remplir les deux champs de mot de passe",
|
||||
"passwordSuccess": "Mot de passe mis à jour avec succès",
|
||||
"imageSuccess": "Image de profil mise à jour avec succès",
|
||||
"imageRemoved": "Image de profil supprimée avec succès"
|
||||
},
|
||||
"pageTitle": "Profil"
|
||||
},
|
||||
"resetPassword": {
|
||||
"pageTitle": "Réinitialiser le Mot de Passe",
|
||||
"header": {
|
||||
"title": "Réinitialiser le Mot de Passe",
|
||||
"description": "Entrez votre nouveau mot de passe ci-dessous"
|
||||
},
|
||||
"form": {
|
||||
"newPassword": "Nouveau Mot de Passe",
|
||||
"newPasswordPlaceholder": "Entrez votre nouveau mot de passe",
|
||||
"confirmPassword": "Confirmer le Nouveau Mot de Passe",
|
||||
"confirmPasswordPlaceholder": "Confirmez votre nouveau mot de passe",
|
||||
"resetting": "Réinitialisation en Cours...",
|
||||
"submit": "Réinitialiser le Mot de Passe",
|
||||
"backToLogin": "Retour à la Connexion"
|
||||
},
|
||||
"messages": {
|
||||
"success": "Mot de passe réinitialisé avec succès"
|
||||
},
|
||||
"errors": {
|
||||
"serverError": "Échec de la réinitialisation du mot de passe. Veuillez réessayer.",
|
||||
"invalidToken": "Jeton de réinitialisation invalide ou manquant"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Paramètres",
|
||||
"breadcrumb": "Paramètres",
|
||||
"pageTitle": "Paramètres",
|
||||
"groups": {
|
||||
"defaultDescription": "Options de configuration",
|
||||
"general": {
|
||||
"title": "Général",
|
||||
"description": "Paramètres de base de l'application"
|
||||
},
|
||||
"email": {
|
||||
"title": "Email",
|
||||
"description": "Configuration du serveur de messagerie"
|
||||
},
|
||||
"security": {
|
||||
"title": "Sécurité",
|
||||
"description": "Paramètres de sécurité et d'authentification"
|
||||
},
|
||||
"storage": {
|
||||
"title": "Stockage",
|
||||
"description": "Configuration du stockage des fichiers"
|
||||
}
|
||||
},
|
||||
"fields": {
|
||||
"noDescription": "Aucune description disponible",
|
||||
"appLogo": {
|
||||
"title": "Logo de l'Application",
|
||||
"description": "Image du logo de l'application"
|
||||
},
|
||||
"appName": {
|
||||
"title": "Nom de l'Application",
|
||||
"description": "Nom de l'application affiché aux utilisateurs"
|
||||
},
|
||||
"appDescription": {
|
||||
"title": "Description de l'Application",
|
||||
"description": "Brève description de l'application"
|
||||
},
|
||||
"showHomePage": {
|
||||
"title": "Afficher la Page d'Accueil",
|
||||
"description": "Afficher la page d'accueil après l'installation"
|
||||
},
|
||||
"smtpEnabled": {
|
||||
"description": "Activer les notifications par email"
|
||||
},
|
||||
"smtpHost": {
|
||||
"title": "Serveur SMTP",
|
||||
"description": "Adresse du serveur SMTP"
|
||||
},
|
||||
"smtpPort": {
|
||||
"title": "Port SMTP",
|
||||
"description": "Port du serveur SMTP"
|
||||
},
|
||||
"smtpUser": {
|
||||
"title": "Utilisateur SMTP",
|
||||
"description": "Nom d'utilisateur pour l'authentification SMTP"
|
||||
},
|
||||
"smtpPass": {
|
||||
"title": "Mot de passe SMTP",
|
||||
"description": "Mot de passe pour l'authentification SMTP"
|
||||
},
|
||||
"smtpFromName": {
|
||||
"title": "Nom de l'Expéditeur",
|
||||
"description": "Nom affiché dans les emails envoyés"
|
||||
},
|
||||
"smtpFromEmail": {
|
||||
"title": "Email de l'Expéditeur",
|
||||
"description": "Adresse email de l'expéditeur"
|
||||
},
|
||||
"maxLoginAttempts": {
|
||||
"title": "Tentatives de Connexion Maximum",
|
||||
"description": "Nombre maximum de tentatives de connexion avant le blocage"
|
||||
},
|
||||
"loginBlockDuration": {
|
||||
"title": "Durée du Blocage",
|
||||
"description": "Durée (en secondes) du blocage après dépassement des tentatives"
|
||||
},
|
||||
"passwordMinLength": {
|
||||
"title": "Longueur Minimale du Mot de Passe",
|
||||
"description": "Nombre minimum de caractères pour les mots de passe"
|
||||
},
|
||||
"passwordResetTokenExpiration": {
|
||||
"title": "Expiration du Jeton de Réinitialisation",
|
||||
"description": "Durée de validité (en secondes) du jeton de réinitialisation"
|
||||
},
|
||||
"maxFileSize": {
|
||||
"title": "Taille Maximale de Fichier",
|
||||
"description": "Taille maximale autorisée pour les fichiers (en octets)"
|
||||
},
|
||||
"maxTotalStoragePerUser": {
|
||||
"title": "Stockage Maximum par Utilisateur",
|
||||
"description": "Limite totale de stockage par utilisateur (en octets)"
|
||||
}
|
||||
},
|
||||
"buttons": {
|
||||
"save": "Enregistrer {{group}}"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "Échec du chargement des paramètres",
|
||||
"updateFailed": "Échec de la mise à jour des paramètres"
|
||||
},
|
||||
"messages": {
|
||||
"noChanges": "Aucun changement à enregistrer",
|
||||
"updateSuccess": "Paramètres {{group}} mis à jour avec succès"
|
||||
}
|
||||
},
|
||||
"share": {
|
||||
"errors": {
|
||||
"invalidPassword": "Mot de passe invalide. Veuillez réessayer.",
|
||||
"loadFailed": "Échec du chargement du partage",
|
||||
"downloadFailed": "Échec du téléchargement du fichier"
|
||||
},
|
||||
"messages": {
|
||||
"downloadStarted": "Téléchargement commencé"
|
||||
},
|
||||
"password": {
|
||||
"title": "Partage Protégé par Mot de Passe",
|
||||
"protected": "Ce partage est protégé par mot de passe",
|
||||
"incorrect": "Mot de passe incorrect. Veuillez réessayer.",
|
||||
"label": "Mot de passe",
|
||||
"placeholder": "Entrez le mot de passe du partage",
|
||||
"submit": "Envoyer"
|
||||
},
|
||||
"details": {
|
||||
"untitled": "Partage sans titre",
|
||||
"created": "Créé le: {{date}}",
|
||||
"expires": "Expire le: {{date}}"
|
||||
},
|
||||
"notFound": {
|
||||
"title": "Partage Non Trouvé",
|
||||
"description": "Ce partage a peut-être été supprimé ou a expiré."
|
||||
},
|
||||
"pageTitle": "Partage"
|
||||
},
|
||||
"shares": {
|
||||
"errors": {
|
||||
"loadFailed": "Échec du chargement des partages",
|
||||
"notifyFailed": "Échec de la notification des destinataires",
|
||||
"smtpConfigFailed": "Échec du chargement de la configuration SMTP"
|
||||
},
|
||||
"messages": {
|
||||
"linkCopied": "Lien copié dans le presse-papiers",
|
||||
"recipientsNotified": "Destinataires notifiés avec succès"
|
||||
},
|
||||
"empty": {
|
||||
"message": "Aucun partage créé pour le moment",
|
||||
"createButton": "Créer un Partage"
|
||||
},
|
||||
"header": {
|
||||
"title": "Mes Partages",
|
||||
"myShares": "Mes Partages"
|
||||
},
|
||||
"search": {
|
||||
"title": "Tous les Partages",
|
||||
"createButton": "Créer un Partage",
|
||||
"placeholder": "Rechercher des partages...",
|
||||
"results": "Trouvé {{filtered}} sur {{total}} partages"
|
||||
},
|
||||
"pageTitle": "Partages"
|
||||
},
|
||||
"users": {
|
||||
"modes": {
|
||||
"create": "créer",
|
||||
"edit": "modifier"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "Échec du chargement des utilisateurs",
|
||||
"submitFailed": "Échec de {{mode}} l'utilisateur",
|
||||
"deleteFailed": "Échec de la suppression de l'utilisateur",
|
||||
"statusUpdateFailed": "Échec de la mise à jour du statut de l'utilisateur"
|
||||
},
|
||||
"messages": {
|
||||
"createSuccess": "Utilisateur créé avec succès",
|
||||
"updateSuccess": "Utilisateur mis à jour avec succès",
|
||||
"deleteSuccess": "Utilisateur supprimé avec succès",
|
||||
"activateSuccess": "Utilisateur activé avec succès",
|
||||
"deactivateSuccess": "Utilisateur désactivé avec succès"
|
||||
},
|
||||
"actions": {
|
||||
"edit": "Modifier",
|
||||
"activate": "Activer",
|
||||
"deactivate": "Désactiver",
|
||||
"delete": "Supprimer"
|
||||
},
|
||||
"delete": {
|
||||
"title": "Confirmer la Suppression de l'Utilisateur",
|
||||
"confirmation": "Êtes-vous sûr de vouloir supprimer l'utilisateur {{firstName}} {{lastName}} ? Cette action ne peut pas être annulée.",
|
||||
"confirm": "Supprimer l'Utilisateur"
|
||||
},
|
||||
"form": {
|
||||
"titleCreate": "Ajouter un Nouvel Utilisateur",
|
||||
"titleEdit": "Modifier l'Utilisateur",
|
||||
"firstName": "Prénom",
|
||||
"lastName": "Nom",
|
||||
"username": "Nom d'Utilisateur",
|
||||
"email": "Email",
|
||||
"password": "Mot de Passe",
|
||||
"newPassword": "Nouveau Mot de Passe (optionnel)",
|
||||
"passwordPlaceholder": "Laisser vide pour garder le mot de passe actuel",
|
||||
"role": "Rôle",
|
||||
"roleUser": "Utilisateur",
|
||||
"roleAdmin": "Administrateur",
|
||||
"create": "Créer",
|
||||
"save": "Enregistrer"
|
||||
},
|
||||
"status": {
|
||||
"title": "Confirmer le Changement de Statut",
|
||||
"confirmation": "Êtes-vous sûr de vouloir {{action}} l'utilisateur {{firstName}} {{lastName}} ?",
|
||||
"activate": "activer",
|
||||
"deactivate": "désactiver",
|
||||
"user": "Utilisateur"
|
||||
},
|
||||
"header": {
|
||||
"title": "Gestion des Utilisateurs",
|
||||
"addUser": "Ajouter un Utilisateur",
|
||||
"management": "Gestion des Utilisateurs"
|
||||
},
|
||||
"table": {
|
||||
"user": "UTILISATEUR",
|
||||
"email": "EMAIL",
|
||||
"status": "STATUT",
|
||||
"role": "RÔLE",
|
||||
"actions": "ACTIONS",
|
||||
"active": "Actif",
|
||||
"inactive": "Inactif",
|
||||
"admin": "Admin",
|
||||
"userr": "Utilisateur"
|
||||
}
|
||||
},
|
||||
"logo": {
|
||||
"labels": {
|
||||
"appLogo": "Logo de l'application"
|
||||
},
|
||||
"buttons": {
|
||||
"upload": "Télécharger le logo",
|
||||
"remove": "Supprimer le logo"
|
||||
},
|
||||
"messages": {
|
||||
"uploadSuccess": "Logo téléchargé avec succès",
|
||||
"removeSuccess": "Logo supprimé avec succès"
|
||||
},
|
||||
"errors": {
|
||||
"uploadFailed": "Échec du téléchargement du logo",
|
||||
"removeFailed": "Échec de la suppression du logo"
|
||||
}
|
||||
},
|
||||
"navbar": {
|
||||
"logoAlt": "Logo de l'Application",
|
||||
"profileMenu": "Menu du Profil",
|
||||
"profile": "Profil",
|
||||
"settings": "Paramètres",
|
||||
"usersManagement": "Gestion des Utilisateurs",
|
||||
"logout": "Déconnexion"
|
||||
}
|
||||
}
|
638
apps/app/messages/hi-IN.json
Normal file
638
apps/app/messages/hi-IN.json
Normal file
@@ -0,0 +1,638 @@
|
||||
{
|
||||
"login": {
|
||||
"welcome": "स्वागत है में",
|
||||
"signInToContinue": "जारी रखने के लिए साइन इन करें",
|
||||
"emailLabel": "ईमेल पता",
|
||||
"emailPlaceholder": "अपना ईमेल दर्ज करें",
|
||||
"passwordLabel": "पासवर्ड",
|
||||
"passwordPlaceholder": "अपना पासवर्ड दर्ज करें",
|
||||
"signIn": "साइन इन करें",
|
||||
"signingIn": "साइन इन हो रहा है...",
|
||||
"forgotPassword": "पासवर्ड भूल गए?",
|
||||
"pageTitle": "लॉगिन"
|
||||
},
|
||||
"errors": {
|
||||
"invalidCredentials": "गलत ईमेल या पासवर्ड",
|
||||
"userNotFound": "उपयोगकर्ता नहीं मिला",
|
||||
"accountLocked": "खाता लॉक है। कृपया बाद में प्रयास करें",
|
||||
"unexpectedError": "एक अप्रत्याशित त्रुटि हुई। कृपया पुनः प्रयास करें"
|
||||
},
|
||||
"validation": {
|
||||
"invalidEmail": "अमान्य ईमेल पता",
|
||||
"passwordMinLength": "पासवर्ड कम से कम 6 अक्षर का होना चाहिए",
|
||||
"firstNameRequired": "पहला नाम आवश्यक है",
|
||||
"lastNameRequired": "अंतिम नाम आवश्यक है",
|
||||
"usernameLength": "उपयोगकर्ता नाम कम से कम 3 अक्षर का होना चाहिए",
|
||||
"usernameSpaces": "उपयोगकर्ता नाम में रिक्त स्थान नहीं हो सकते",
|
||||
"passwordLength": "पासवर्ड कम से कम 8 अक्षर का होना चाहिए",
|
||||
"passwordsMatch": "पासवर्ड मेल नहीं खाते",
|
||||
"emailRequired": "ईमेल आवश्यक है",
|
||||
"passwordRequired": "पासवर्ड आवश्यक है"
|
||||
},
|
||||
"fileSelector": {
|
||||
"availableFiles": "उपलब्ध फाइलें ({{count}})",
|
||||
"shareFiles": "फाइलें साझा करें ({{count}})",
|
||||
"searchPlaceholder": "फाइलें खोजें...",
|
||||
"noMatchingFiles": "कोई मेल खाने वाली फाइलें नहीं",
|
||||
"noAvailableFiles": "कोई फाइल उपलब्ध नहीं",
|
||||
"noFilesInShare": "साझाकरण में कोई फाइलें नहीं",
|
||||
"saveChanges": "परिवर्तन सहेजें"
|
||||
},
|
||||
"recipientSelector": {
|
||||
"emailPlaceholder": "प्राप्तकर्ता का ईमेल दर्ज करें",
|
||||
"add": "जोड़ें",
|
||||
"recipients": "प्राप्तकर्ता ({{count}})",
|
||||
"notifyAll": "सभी को सूचित करें",
|
||||
"noRecipients": "अभी तक कोई प्राप्तकर्ता नहीं जोड़ा गया",
|
||||
"addSuccess": "प्राप्तकर्ता सफलतापूर्वक जोड़ा गया",
|
||||
"addError": "प्राप्तकर्ता जोड़ने में विफल",
|
||||
"removeSuccess": "प्राप्तकर्ता सफलतापूर्वक हटाया गया",
|
||||
"removeError": "प्राप्तकर्ता हटाने में विफल",
|
||||
"sendingNotifications": "सूचनाएँ भेजी जा रही हैं...",
|
||||
"notifySuccess": "प्राप्तकर्ताओं को सफलतापूर्वक सूचित किया गया",
|
||||
"notifyError": "प्राप्तकर्ताओं को सूचित करने में विफल"
|
||||
},
|
||||
"navigation": {
|
||||
"dashboard": "डैशबोर्ड"
|
||||
},
|
||||
"common": {
|
||||
"loading": "लोड हो रहा है, कृपया प्रतीक्षा करें...",
|
||||
"cancel": "रद्द करें",
|
||||
"save": "सहेजें",
|
||||
"delete": "हटाएं",
|
||||
"close": "बंद करें",
|
||||
"download": "डाउनलोड करें",
|
||||
"unexpectedError": "एक अप्रत्याशित त्रुटि हुई। कृपया पुनः प्रयास करें।",
|
||||
"yes": "हाँ",
|
||||
"no": "नहीं",
|
||||
"dashboard": "डैशबोर्ड"
|
||||
},
|
||||
"createShare": {
|
||||
"title": "साझा करें बनाएं",
|
||||
"nameLabel": "साझाकरण का नाम",
|
||||
"expirationLabel": "समाप्ति तिथि",
|
||||
"expirationPlaceholder": "MM/DD/YYYY HH:MM",
|
||||
"maxViewsLabel": "अधिकतम दृश्य",
|
||||
"maxViewsPlaceholder": "अनलिमिटेड के लिए खाली छोड़ें",
|
||||
"passwordProtection": "पासवर्ड सुरक्षा",
|
||||
"passwordLabel": "पासवर्ड",
|
||||
"create": "साझा करें बनाएं",
|
||||
"success": "साझाकरण सफलतापूर्वक बनाया गया",
|
||||
"error": "साझाकरण बनाने में विफल"
|
||||
},
|
||||
"fileActions": {
|
||||
"editFile": "फाइल संपादित करें",
|
||||
"nameLabel": "नाम",
|
||||
"namePlaceholder": "नया नाम दर्ज करें",
|
||||
"extension": "एक्सटेंशन",
|
||||
"descriptionLabel": "विवरण",
|
||||
"descriptionPlaceholder": "फाइल का विवरण दर्ज करें",
|
||||
"deleteFile": "फाइल हटाएं",
|
||||
"deleteConfirmation": "क्या आप वाकई \"{{fileName}}\" हटाना चाहते हैं?",
|
||||
"deleteWarning": "यह क्रिया अपरिवर्तनीय है।"
|
||||
},
|
||||
"filePreview": {
|
||||
"loading": "पूर्वावलोकन लोड हो रहा है...",
|
||||
"notAvailable": "पूर्वावलोकन उपलब्ध नहीं",
|
||||
"downloadToView": "सामग्री देखने के लिए फाइल डाउनलोड करें",
|
||||
"audioNotSupported": "आपका ब्राउज़र ऑडियो तत्व का समर्थन नहीं करता",
|
||||
"videoNotSupported": "आपका ब्राउज़र वीडियो तत्व का समर्थन नहीं करता",
|
||||
"loadError": "पूर्वावलोकन लोड करने में विफल",
|
||||
"downloadError": "फाइल डाउनलोड करने में विफल"
|
||||
},
|
||||
"generateShareLink": {
|
||||
"generateTitle": "साझाकरण लिंक उत्पन्न करें",
|
||||
"updateTitle": "साझाकरण लिंक अपडेट करें",
|
||||
"generateDescription": "अपनी फाइलें साझा करने के लिए एक लिंक उत्पन्न करें",
|
||||
"updateDescription": "इस साझाकरण लिंक के लिए उपनाम अपडेट करें",
|
||||
"aliasPlaceholder": "उपनाम दर्ज करें",
|
||||
"linkReady": "आपका साझाकरण लिंक तैयार है:",
|
||||
"generateButton": "लिंक उत्पन्न करें",
|
||||
"updateButton": "लिंक अपडेट करें",
|
||||
"copyButton": "लिंक कॉपी करें",
|
||||
"success": "लिंक सफलतापूर्वक उत्पन्न हुआ",
|
||||
"error": "लिंक उत्पन्न करने में विफल",
|
||||
"copied": "लिंक क्लिपबोर्ड में कॉपी किया गया"
|
||||
},
|
||||
"shareActions": {
|
||||
"deleteTitle": "साझाकरण हटाएं",
|
||||
"deleteConfirmation": "क्या आप वाकई इस साझाकरण को हटाना चाहते हैं? यह क्रिया अपरिवर्तनीय है।",
|
||||
"editTitle": "साझाकरण संपादित करें",
|
||||
"nameLabel": "साझाकरण का नाम",
|
||||
"expirationLabel": "समाप्ति तिथि",
|
||||
"expirationPlaceholder": "MM/DD/YYYY HH:MM",
|
||||
"maxViewsLabel": "अधिकतम दृश्य",
|
||||
"maxViewsPlaceholder": "अनलिमिटेड के लिए खाली छोड़ें",
|
||||
"passwordProtection": "पासवर्ड सुरक्षा",
|
||||
"passwordLabel": "पासवर्ड",
|
||||
"passwordPlaceholder": "पासवर्ड दर्ज करें",
|
||||
"newPasswordLabel": "नया पासवर्ड (वर्तमान रखने के लिए खाली छोड़ें)",
|
||||
"newPasswordPlaceholder": "नया पासवर्ड दर्ज करें",
|
||||
"manageFilesTitle": "फाइलें प्रबंधित करें",
|
||||
"manageRecipientsTitle": "प्राप्तकर्ताओं का प्रबंधन करें",
|
||||
"editSuccess": "साझाकरण सफलतापूर्वक अपडेट हुआ",
|
||||
"editError": "साझाकरण अपडेट करने में विफल"
|
||||
},
|
||||
"shareDetails": {
|
||||
"title": "साझाकरण विवरण",
|
||||
"subtitle": "इस साझाकरण की विस्तृत जानकारी",
|
||||
"basicInfo": "मूल जानकारी",
|
||||
"name": "नाम",
|
||||
"untitled": "बिना शीर्षक के",
|
||||
"views": "दृश्य",
|
||||
"dates": "तिथियाँ",
|
||||
"created": "बनाया गया",
|
||||
"expires": "समाप्त होता है",
|
||||
"never": "कभी नहीं",
|
||||
"security": "सुरक्षा",
|
||||
"passwordProtected": "पासवर्ड द्वारा संरक्षित",
|
||||
"publicAccess": "सार्वजनिक पहुँच",
|
||||
"maxViews": "अधिकतम दृश्य: {{count}}",
|
||||
"files": "फाइलें ({{count}})",
|
||||
"recipients": "प्राप्तकर्ता ({{count}})",
|
||||
"notAvailable": "एन/ए",
|
||||
"invalidDate": "अमान्य तिथि",
|
||||
"loadError": "साझाकरण विवरण लोड करने में विफल"
|
||||
},
|
||||
"uploadFile": {
|
||||
"title": "फाइल अपलोड करें",
|
||||
"selectFile": "फाइल चुनने के लिए क्लिक करें",
|
||||
"preview": "पूर्वावलोकन",
|
||||
"uploadProgress": "अपलोड प्रगति",
|
||||
"upload": "अपलोड करें",
|
||||
"success": "फाइल सफलतापूर्वक अपलोड हुई",
|
||||
"error": "फाइल अपलोड करने में विफल"
|
||||
},
|
||||
"filesTable": {
|
||||
"ariaLabel": "फाइल टेबल",
|
||||
"columns": {
|
||||
"name": "नाम",
|
||||
"description": "विवरण",
|
||||
"size": "आकार",
|
||||
"createdAt": "बनाया गया",
|
||||
"updatedAt": "अपडेट किया गया",
|
||||
"actions": "क्रियाएं"
|
||||
},
|
||||
"actions": {
|
||||
"menu": "फाइल क्रिया मेनू",
|
||||
"preview": "पूर्वावलोकन",
|
||||
"edit": "संपादित करें",
|
||||
"download": "डाउनलोड करें",
|
||||
"delete": "हटाएं"
|
||||
}
|
||||
},
|
||||
"sharesTable": {
|
||||
"ariaLabel": "साझाकरण टेबल",
|
||||
"never": "कभी नहीं",
|
||||
"columns": {
|
||||
"name": "नाम",
|
||||
"createdAt": "बनाया गया",
|
||||
"expiresAt": "समाप्त होता है",
|
||||
"status": "स्थिति",
|
||||
"security": "सुरक्षा",
|
||||
"files": "फाइलें",
|
||||
"recipients": "प्राप्तकर्ता",
|
||||
"actions": "क्रियाएं"
|
||||
},
|
||||
"status": {
|
||||
"neverExpires": "कभी समाप्त नहीं",
|
||||
"active": "सक्रिय",
|
||||
"expired": "समाप्त"
|
||||
},
|
||||
"security": {
|
||||
"protected": "संरक्षित",
|
||||
"public": "सार्वजनिक"
|
||||
},
|
||||
"filesCount": "{{count}} फाइलें",
|
||||
"recipientsCount": "{{count}} प्राप्तकर्ता",
|
||||
"actions": {
|
||||
"menu": "साझाकरण क्रिया मेनू",
|
||||
"edit": "संपादित करें",
|
||||
"manageFiles": "फाइलें प्रबंधित करें",
|
||||
"manageRecipients": "प्राप्तकर्ताओं का प्रबंधन करें",
|
||||
"viewDetails": "विवरण देखें",
|
||||
"generateLink": "लिंक उत्पन्न करें",
|
||||
"editLink": "लिंक संपादित करें",
|
||||
"copyLink": "लिंक कॉपी करें",
|
||||
"notifyRecipients": "प्राप्तकर्ताओं को सूचित करें",
|
||||
"delete": "हटाएं"
|
||||
}
|
||||
},
|
||||
"footer": {
|
||||
"poweredBy": "द्वारा संचालित",
|
||||
"kyanHomepage": "Kyantech होमपेज"
|
||||
},
|
||||
"fileManager": {
|
||||
"downloadError": "फाइल डाउनलोड करने में त्रुटि",
|
||||
"updateSuccess": "फाइल सफलतापूर्वक अपडेट हुई",
|
||||
"updateError": "फाइल अपडेट करने में त्रुटि",
|
||||
"deleteSuccess": "फाइल सफलतापूर्वक हटाई गई",
|
||||
"deleteError": "फाइल हटाने में त्रुटि"
|
||||
},
|
||||
"shareManager": {
|
||||
"deleteSuccess": "साझाकरण सफलतापूर्वक हटाया गया",
|
||||
"deleteError": "साझाकरण हटाने में त्रुटि",
|
||||
"updateSuccess": "साझाकरण सफलतापूर्वक अपडेट हुआ",
|
||||
"updateError": "साझाकरण अपडेट करने में त्रुटि",
|
||||
"filesUpdateSuccess": "फाइलें सफलतापूर्वक अपडेट हुईं",
|
||||
"filesUpdateError": "फाइलें अपडेट करने में त्रुटि",
|
||||
"recipientsUpdateSuccess": "प्राप्तकर्ता सफलतापूर्वक अपडेट हुए",
|
||||
"recipientsUpdateError": "प्राप्तकर्ता अपडेट करने में त्रुटि",
|
||||
"linkGenerateSuccess": "साझाकरण लिंक सफलतापूर्वक उत्पन्न हुआ",
|
||||
"linkGenerateError": "साझाकरण लिंक उत्पन्न करने में त्रुटि",
|
||||
"notifyLoading": "सूचनाएँ भेजी जा रही हैं...",
|
||||
"notifySuccess": "प्राप्तकर्ताओं को सफलतापूर्वक सूचित किया गया",
|
||||
"notifyError": "प्राप्तकर्ताओं को सूचित करने में त्रुटि"
|
||||
},
|
||||
"quickAccess": {
|
||||
"files": {
|
||||
"title": "मेरी फाइलें",
|
||||
"description": "अपलोड की गई फाइलों तक पहुंच और प्रबंधन"
|
||||
},
|
||||
"shares": {
|
||||
"title": "मेरे साझाकरण",
|
||||
"description": "साझा की गई फाइलों को देखें और प्रबंधित करें"
|
||||
}
|
||||
},
|
||||
"recentFiles": {
|
||||
"title": "हाल की अपलोड्स",
|
||||
"viewAll": "सभी देखें",
|
||||
"uploadFile": "फाइल अपलोड करें",
|
||||
"noFiles": "अभी तक कोई फाइल अपलोड नहीं हुई"
|
||||
},
|
||||
"recentShares": {
|
||||
"title": "हाल के साझाकरण",
|
||||
"viewAll": "सभी देखें",
|
||||
"createShare": "साझा करें बनाएं",
|
||||
"noShares": "अभी तक कोई साझाकरण नहीं बनाया गया",
|
||||
"createFirst": "अपना पहला साझाकरण बनाएं"
|
||||
},
|
||||
"storageUsage": {
|
||||
"title": "स्टोरेज उपयोग",
|
||||
"ariaLabel": "स्टोरेज उपयोग प्रगति पट्टी",
|
||||
"used": "{{size}} उपयोग किया गया",
|
||||
"available": "{{size}} उपलब्ध"
|
||||
},
|
||||
"dashboard": {
|
||||
"loadError": "डैशबोर्ड डेटा लोड करने में त्रुटि",
|
||||
"linkCopied": "लिंक क्लिपबोर्ड में कॉपी हुआ",
|
||||
"pageTitle": "डैशबोर्ड",
|
||||
"breadcrumb": "डैशबोर्ड"
|
||||
},
|
||||
"emptyState": {
|
||||
"noFiles": "अभी तक कोई फाइल अपलोड नहीं हुई",
|
||||
"uploadFile": "फाइल अपलोड करें"
|
||||
},
|
||||
"files": {
|
||||
"title": "सभी फाइलें",
|
||||
"uploadFile": "फाइल अपलोड करें",
|
||||
"loadError": "फाइलें लोड करने में त्रुटि",
|
||||
"pageTitle": "मेरी फाइलें",
|
||||
"breadcrumb": "मेरी फाइलें"
|
||||
},
|
||||
"searchBar": {
|
||||
"placeholder": "फाइलें खोजें...",
|
||||
"results": "{{total}} में से {{filtered}} फाइलें मिलीं"
|
||||
},
|
||||
"forgotPassword": {
|
||||
"emailLabel": "ईमेल पता",
|
||||
"emailPlaceholder": "अपना ईमेल दर्ज करें",
|
||||
"sending": "भेजा जा रहा है...",
|
||||
"submit": "रीसेट निर्देश भेजें",
|
||||
"backToLogin": "लॉगिन पर वापस जाएं",
|
||||
"title": "पासवर्ड भूल गए",
|
||||
"description": "अपना ईमेल पता दर्ज करें और हम आपको पासवर्ड रीसेट करने के निर्देश भेजेंगे।",
|
||||
"resetInstructions": "रीसेट निर्देश आपके ईमेल पर भेज दिए गए हैं",
|
||||
"pageTitle": "पासवर्ड भूल गए"
|
||||
},
|
||||
"home": {
|
||||
"description": "WeTransfer का ओपन-सोर्स विकल्प। फाइलें सुरक्षित रूप से साझा करें, बिना ट्रैकिंग या सीमाओं के।",
|
||||
"documentation": "दस्तावेज",
|
||||
"starOnGithub": "GitHub पर स्टार करें",
|
||||
"privacyMessage": "गोपनीयता को ध्यान में रखते हुए बनाया गया। अपलोड से पहले आपकी फाइलें केवल उनके लिए उपलब्ध हैं जिनके पास साझाकरण लिंक है। हमेशा मुफ्त और ओपन सोर्स।",
|
||||
"header": {
|
||||
"fileSharing": "फाइल साझा करें",
|
||||
"tagline": "सरल और मुफ्त"
|
||||
},
|
||||
"pageTitle": "होम"
|
||||
},
|
||||
"profile": {
|
||||
"password": {
|
||||
"title": "पासवर्ड बदलें",
|
||||
"newPassword": "नया पासवर्ड",
|
||||
"confirmPassword": "नया पासवर्ड पुष्टि करें",
|
||||
"updateButton": "पासवर्ड अपडेट करें"
|
||||
},
|
||||
"form": {
|
||||
"title": "प्रोफ़ाइल जानकारी",
|
||||
"firstName": "पहला नाम",
|
||||
"lastName": "अंतिम नाम",
|
||||
"username": "उपयोगकर्ता नाम",
|
||||
"email": "ईमेल",
|
||||
"updateButton": "प्रोफ़ाइल अपडेट करें"
|
||||
},
|
||||
"header": {
|
||||
"title": "प्रोफ़ाइल",
|
||||
"subtitle": "अपनी व्यक्तिगत जानकारी और पासवर्ड प्रबंधित करें"
|
||||
},
|
||||
"picture": {
|
||||
"title": "प्रोफ़ाइल चित्र",
|
||||
"description": "प्रोफ़ाइल चित्र बदलने के लिए कैमरा आइकन पर क्लिक करें",
|
||||
"uploadPhoto": "फोटो अपलोड करें",
|
||||
"removePhoto": "फोटो हटाएं"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "उपयोगकर्ता डेटा लोड करने में विफल",
|
||||
"updateFailed": "प्रोफ़ाइल अपडेट करने में त्रुटि",
|
||||
"passwordFailed": "पासवर्ड अपडेट करने में त्रुटि",
|
||||
"imageFailed": "प्रोफ़ाइल चित्र अपडेट करने में त्रुटि",
|
||||
"imageRemoveFailed": "प्रोफ़ाइल चित्र हटाने में त्रुटि"
|
||||
},
|
||||
"messages": {
|
||||
"noChanges": "सहेजने के लिए कोई परिवर्तन नहीं",
|
||||
"updateSuccess": "प्रोफ़ाइल सफलतापूर्वक अपडेट हुई",
|
||||
"fillPasswords": "कृपया दोनों पासवर्ड फील्ड भरें",
|
||||
"passwordSuccess": "पासवर्ड सफलतापूर्वक अपडेट हुआ",
|
||||
"imageSuccess": "प्रोफ़ाइल चित्र सफलतापूर्वक अपडेट हुआ",
|
||||
"imageRemoved": "प्रोफ़ाइल चित्र सफलतापूर्वक हटाया गया"
|
||||
},
|
||||
"pageTitle": "प्रोफ़ाइल"
|
||||
},
|
||||
"resetPassword": {
|
||||
"pageTitle": "पासवर्ड रीसेट करें",
|
||||
"header": {
|
||||
"title": "पासवर्ड रीसेट करें",
|
||||
"description": "नीचे अपना नया पासवर्ड दर्ज करें"
|
||||
},
|
||||
"form": {
|
||||
"newPassword": "नया पासवर्ड",
|
||||
"newPasswordPlaceholder": "अपना नया पासवर्ड दर्ज करें",
|
||||
"confirmPassword": "नया पासवर्ड पुष्टि करें",
|
||||
"confirmPasswordPlaceholder": "अपना नया पासवर्ड पुष्टि करें",
|
||||
"resetting": "पासवर्ड रीसेट हो रहा है...",
|
||||
"submit": "पासवर्ड रीसेट करें",
|
||||
"backToLogin": "लॉगिन पर वापस जाएं"
|
||||
},
|
||||
"messages": {
|
||||
"success": "पासवर्ड सफलतापूर्वक रीसेट हुआ"
|
||||
},
|
||||
"errors": {
|
||||
"serverError": "पासवर्ड रीसेट करने में विफल। कृपया पुनः प्रयास करें।",
|
||||
"invalidToken": "अमान्य या गायब रीसेट टोकन"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"groups": {
|
||||
"defaultDescription": "कॉन्फ़िगरेशन विकल्प",
|
||||
"general": {
|
||||
"title": "सामान्य",
|
||||
"description": "एप्लिकेशन की बुनियादी सेटिंग्स"
|
||||
},
|
||||
"email": {
|
||||
"title": "ईमेल",
|
||||
"description": "ईमेल सर्वर कॉन्फ़िगरेशन"
|
||||
},
|
||||
"security": {
|
||||
"title": "सुरक्षा",
|
||||
"description": "सुरक्षा और प्रमाणीकरण सेटिंग्स"
|
||||
},
|
||||
"storage": {
|
||||
"title": "स्टोरेज",
|
||||
"description": "फाइल स्टोरेज कॉन्फ़िगरेशन"
|
||||
}
|
||||
},
|
||||
"fields": {
|
||||
"noDescription": "कोई विवरण उपलब्ध नहीं",
|
||||
"appLogo": {
|
||||
"title": "एप्लिकेशन लोगो",
|
||||
"description": "एप्लिकेशन का लोगो चित्र"
|
||||
},
|
||||
"appName": {
|
||||
"title": "एप्लिकेशन नाम",
|
||||
"description": "उपयोगकर्ताओं को दिखाया जाने वाला एप्लिकेशन नाम"
|
||||
},
|
||||
"appDescription": {
|
||||
"title": "एप्लिकेशन विवरण",
|
||||
"description": "एप्लिकेशन का संक्षिप्त विवरण"
|
||||
},
|
||||
"showHomePage": {
|
||||
"title": "होम पेज दिखाएं",
|
||||
"description": "इंस्टॉलेशन के बाद होम पेज दिखाएं"
|
||||
},
|
||||
"smtpEnabled": {
|
||||
"title": "SMTP सक्षम",
|
||||
"description": "SMTP ईमेल कार्यक्षमता सक्षम या अक्षम करें"
|
||||
},
|
||||
"smtpHost": {
|
||||
"title": "SMTP सर्वर",
|
||||
"description": "SMTP सर्वर पता"
|
||||
},
|
||||
"smtpPort": {
|
||||
"title": "SMTP पोर्ट",
|
||||
"description": "SMTP सर्वर पोर्ट"
|
||||
},
|
||||
"smtpUser": {
|
||||
"title": "SMTP उपयोगकर्ता",
|
||||
"description": "SMTP प्रमाणीकरण के लिए उपयोगकर्ता नाम"
|
||||
},
|
||||
"smtpPass": {
|
||||
"title": "SMTP पासवर्ड",
|
||||
"description": "SMTP प्रमाणीकरण के लिए पासवर्ड"
|
||||
},
|
||||
"smtpFromName": {
|
||||
"title": "प्रेषक का नाम",
|
||||
"description": "भेजे गए ईमेल के लिए डिस्प्ले नाम"
|
||||
},
|
||||
"smtpFromEmail": {
|
||||
"title": "प्रेषक का ईमेल",
|
||||
"description": "प्रेषक का ईमेल पता"
|
||||
},
|
||||
"maxLoginAttempts": {
|
||||
"title": "अधिकतम लॉगिन प्रयास",
|
||||
"description": "ब्लॉक करने से पहले अधिकतम लॉगिन प्रयासों की संख्या"
|
||||
},
|
||||
"loginBlockDuration": {
|
||||
"title": "लॉगिन ब्लॉक अवधि",
|
||||
"description": "प्रयासों की सीमा पार करने पर ब्लॉक की अवधि (सेकंड में)"
|
||||
},
|
||||
"passwordMinLength": {
|
||||
"title": "न्यूनतम पासवर्ड लंबाई",
|
||||
"description": "पासवर्ड के लिए न्यूनतम अक्षरों की संख्या"
|
||||
},
|
||||
"passwordResetTokenExpiration": {
|
||||
"title": "रीसेट टोकन समाप्ति",
|
||||
"description": "पासवर्ड रीसेट टोकन की वैधता (सेकंड में)"
|
||||
},
|
||||
"maxFileSize": {
|
||||
"title": "अधिकतम फाइल आकार",
|
||||
"description": "अपलोड के लिए अधिकतम अनुमत फाइल आकार (बाइट में)"
|
||||
},
|
||||
"maxTotalStoragePerUser": {
|
||||
"title": "प्रति उपयोगकर्ता अधिकतम स्टोरेज",
|
||||
"description": "प्रति उपयोगकर्ता कुल स्टोरेज सीमा (बाइट में)"
|
||||
}
|
||||
},
|
||||
"buttons": {
|
||||
"save": "{{group}} सहेजें"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "सेटिंग्स लोड करने में विफल",
|
||||
"updateFailed": "सेटिंग्स अपडेट करने में विफल"
|
||||
},
|
||||
"messages": {
|
||||
"noChanges": "सहेजने के लिए कोई परिवर्तन नहीं",
|
||||
"updateSuccess": "{{group}} सेटिंग्स सफलतापूर्वक अपडेट हुईं"
|
||||
},
|
||||
"title": "सेटिंग्स",
|
||||
"breadcrumb": "सेटिंग्स",
|
||||
"pageTitle": "सेटिंग्स"
|
||||
},
|
||||
"share": {
|
||||
"errors": {
|
||||
"invalidPassword": "अमान्य पासवर्ड। कृपया पुनः प्रयास करें।",
|
||||
"loadFailed": "साझाकरण लोड करने में विफल",
|
||||
"downloadFailed": "फाइल डाउनलोड करने में विफल"
|
||||
},
|
||||
"messages": {
|
||||
"downloadStarted": "डाउनलोड शुरू हुआ"
|
||||
},
|
||||
"password": {
|
||||
"title": "पासवर्ड संरक्षित साझाकरण",
|
||||
"protected": "यह साझाकरण पासवर्ड द्वारा संरक्षित है",
|
||||
"incorrect": "गलत पासवर्ड। कृपया पुनः प्रयास करें।",
|
||||
"label": "पासवर्ड",
|
||||
"placeholder": "साझाकरण का पासवर्ड दर्ज करें",
|
||||
"submit": "सबमिट करें"
|
||||
},
|
||||
"details": {
|
||||
"untitled": "बिना शीर्षक के",
|
||||
"created": "बनाया गया: {{date}}",
|
||||
"expires": "समाप्त होता है: {{date}}"
|
||||
},
|
||||
"notFound": {
|
||||
"title": "साझाकरण नहीं मिला",
|
||||
"description": "यह साझाकरण हटा दिया गया हो सकता है या समाप्त हो चुका है।"
|
||||
},
|
||||
"pageTitle": "साझाकरण"
|
||||
},
|
||||
"shares": {
|
||||
"errors": {
|
||||
"loadFailed": "साझाकरण लोड करने में विफल",
|
||||
"notifyFailed": "प्राप्तकर्ताओं को सूचित करने में विफल",
|
||||
"smtpConfigFailed": "SMTP कॉन्फ़िगरेशन लोड करने में विफल"
|
||||
},
|
||||
"messages": {
|
||||
"linkCopied": "लिंक क्लिपबोर्ड में कॉपी किया गया",
|
||||
"recipientsNotified": "प्राप्तकर्ताओं को सफलतापूर्वक सूचित किया गया"
|
||||
},
|
||||
"empty": {
|
||||
"message": "अभी तक कोई साझाकरण नहीं बनाया गया",
|
||||
"createButton": "साझाकरण बनाएं"
|
||||
},
|
||||
"header": {
|
||||
"title": "मेरे साझाकरण",
|
||||
"myShares": "मेरे साझाकरण"
|
||||
},
|
||||
"search": {
|
||||
"title": "सभी साझाकरण",
|
||||
"createButton": "साझाकरण बनाएं",
|
||||
"placeholder": "साझाकरण खोजें...",
|
||||
"results": "{{total}} में से {{filtered}} साझाकरण मिले"
|
||||
},
|
||||
"pageTitle": "साझाकरण"
|
||||
},
|
||||
"users": {
|
||||
"modes": {
|
||||
"create": "बनाएं",
|
||||
"edit": "संपादित करें"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "उपयोगकर्ता लोड करने में विफल",
|
||||
"submitFailed": "{{mode}} करने में विफल",
|
||||
"deleteFailed": "उपयोगकर्ता हटाने में विफल",
|
||||
"statusUpdateFailed": "उपयोगकर्ता की स्थिति अपडेट करने में विफल"
|
||||
},
|
||||
"messages": {
|
||||
"createSuccess": "उपयोगकर्ता सफलतापूर्वक बनाया गया",
|
||||
"updateSuccess": "उपयोगकर्ता सफलतापूर्वक अपडेट हुआ",
|
||||
"deleteSuccess": "उपयोगकर्ता सफलतापूर्वक हटाया गया",
|
||||
"activateSuccess": "उपयोगकर्ता सफलतापूर्वक सक्रिय हुआ",
|
||||
"deactivateSuccess": "उपयोगकर्ता सफलतापूर्वक निष्क्रिय हुआ"
|
||||
},
|
||||
"actions": {
|
||||
"edit": "संपादित करें",
|
||||
"activate": "सक्रिय करें",
|
||||
"deactivate": "निष्क्रिय करें",
|
||||
"delete": "हटाएं"
|
||||
},
|
||||
"delete": {
|
||||
"title": "उपयोगकर्ता हटाने की पुष्टि करें",
|
||||
"confirmation": "क्या आप वाकई {{firstName}} {{lastName}} को हटाना चाहते हैं? यह क्रिया अपरिवर्तनीय है।",
|
||||
"confirm": "उपयोगकर्ता हटाएं"
|
||||
},
|
||||
"form": {
|
||||
"titleCreate": "नया उपयोगकर्ता जोड़ें",
|
||||
"titleEdit": "उपयोगकर्ता संपादित करें",
|
||||
"firstName": "पहला नाम",
|
||||
"lastName": "अंतिम नाम",
|
||||
"username": "उपयोगकर्ता नाम",
|
||||
"email": "ईमेल",
|
||||
"password": "पासवर्ड",
|
||||
"newPassword": "नया पासवर्ड (वैकल्पिक)",
|
||||
"passwordPlaceholder": "वर्तमान पासवर्ड रखने के लिए खाली छोड़ें",
|
||||
"role": "भूमिका",
|
||||
"roleUser": "उपयोगकर्ता",
|
||||
"roleAdmin": "व्यवस्थापक",
|
||||
"create": "बनाएं",
|
||||
"save": "सहेजें"
|
||||
},
|
||||
"status": {
|
||||
"title": "स्थिति परिवर्तन की पुष्टि करें",
|
||||
"confirmation": "क्या आप वाकई {{firstName}} {{lastName}} को {{action}} करना चाहते हैं?",
|
||||
"activate": "सक्रिय करें",
|
||||
"deactivate": "निष्क्रिय करें",
|
||||
"user": "उपयोगकर्ता"
|
||||
},
|
||||
"header": {
|
||||
"title": "उपयोगकर्ता प्रबंधन",
|
||||
"addUser": "उपयोगकर्ता जोड़ें",
|
||||
"management": "उपयोगकर्ता प्रबंधन"
|
||||
},
|
||||
"table": {
|
||||
"user": "उपयोगकर्ता",
|
||||
"email": "ईमेल",
|
||||
"status": "स्थिति",
|
||||
"role": "भूमिका",
|
||||
"actions": "क्रियाएं",
|
||||
"active": "सक्रिय",
|
||||
"inactive": "निष्क्रिय",
|
||||
"admin": "व्यवस्थापक",
|
||||
"userr": "उपयोगकर्ता"
|
||||
}
|
||||
},
|
||||
"logo": {
|
||||
"labels": {
|
||||
"appLogo": "एप्लिकेशन लोगो"
|
||||
},
|
||||
"buttons": {
|
||||
"upload": "लोगो अपलोड करें",
|
||||
"remove": "लोगो हटाएं"
|
||||
},
|
||||
"messages": {
|
||||
"uploadSuccess": "लोगो सफलतापूर्वक अपलोड हुआ",
|
||||
"removeSuccess": "लोगो सफलतापूर्वक हटाया गया"
|
||||
},
|
||||
"errors": {
|
||||
"uploadFailed": "लोगो अपलोड करने में विफल",
|
||||
"removeFailed": "लोगो हटाने में विफल"
|
||||
}
|
||||
},
|
||||
"navbar": {
|
||||
"logoAlt": "एप्लिकेशन लोगो",
|
||||
"profileMenu": "प्रोफ़ाइल मेन्यू",
|
||||
"profile": "प्रोफ़ाइल",
|
||||
"settings": "सेटिंग्स",
|
||||
"usersManagement": "उपयोगकर्ता प्रबंधन",
|
||||
"logout": "लॉग आउट"
|
||||
}
|
||||
}
|
638
apps/app/messages/ja-JP.json
Normal file
638
apps/app/messages/ja-JP.json
Normal file
@@ -0,0 +1,638 @@
|
||||
{
|
||||
"login": {
|
||||
"welcome": "ようこそへ",
|
||||
"signInToContinue": "続行するにはサインインしてください",
|
||||
"emailLabel": "メールアドレス",
|
||||
"emailPlaceholder": "メールアドレスを入力してください",
|
||||
"passwordLabel": "パスワード",
|
||||
"passwordPlaceholder": "パスワードを入力してください",
|
||||
"signIn": "サインイン",
|
||||
"signingIn": "サインイン中...",
|
||||
"forgotPassword": "パスワードをお忘れですか?",
|
||||
"pageTitle": "ログイン"
|
||||
},
|
||||
"errors": {
|
||||
"invalidCredentials": "無効なメールアドレスまたはパスワードです",
|
||||
"userNotFound": "ユーザーが見つかりません",
|
||||
"accountLocked": "アカウントがロックされています。後でもう一度お試しください",
|
||||
"unexpectedError": "予期しないエラーが発生しました。もう一度お試しください"
|
||||
},
|
||||
"validation": {
|
||||
"invalidEmail": "無効なメールアドレスです",
|
||||
"passwordMinLength": "パスワードは最低6文字必要です",
|
||||
"firstNameRequired": "名は必須です",
|
||||
"lastNameRequired": "姓は必須です",
|
||||
"usernameLength": "ユーザー名は最低3文字必要です",
|
||||
"usernameSpaces": "ユーザー名にスペースは使用できません",
|
||||
"passwordLength": "パスワードは最低8文字必要です",
|
||||
"passwordsMatch": "パスワードが一致しません",
|
||||
"emailRequired": "メールアドレスは必須です",
|
||||
"passwordRequired": "パスワードは必須です"
|
||||
},
|
||||
"fileSelector": {
|
||||
"availableFiles": "利用可能なファイル ({{count}})",
|
||||
"shareFiles": "ファイルを共有 ({{count}})",
|
||||
"searchPlaceholder": "ファイルを検索...",
|
||||
"noMatchingFiles": "一致するファイルがありません",
|
||||
"noAvailableFiles": "利用可能なファイルがありません",
|
||||
"noFilesInShare": "共有ファイルがありません",
|
||||
"saveChanges": "変更を保存"
|
||||
},
|
||||
"recipientSelector": {
|
||||
"emailPlaceholder": "受信者のメールを入力してください",
|
||||
"add": "追加",
|
||||
"recipients": "受信者 ({{count}})",
|
||||
"notifyAll": "全員に通知",
|
||||
"noRecipients": "まだ受信者が追加されていません",
|
||||
"addSuccess": "受信者が正常に追加されました",
|
||||
"addError": "受信者の追加に失敗しました",
|
||||
"removeSuccess": "受信者が正常に削除されました",
|
||||
"removeError": "受信者の削除に失敗しました",
|
||||
"sendingNotifications": "通知を送信中...",
|
||||
"notifySuccess": "受信者に正常に通知しました",
|
||||
"notifyError": "受信者への通知に失敗しました"
|
||||
},
|
||||
"navigation": {
|
||||
"dashboard": "ダッシュボード"
|
||||
},
|
||||
"common": {
|
||||
"loading": "読み込み中です。しばらくお待ちください...",
|
||||
"cancel": "キャンセル",
|
||||
"save": "保存",
|
||||
"delete": "削除",
|
||||
"close": "閉じる",
|
||||
"download": "ダウンロード",
|
||||
"unexpectedError": "予期しないエラーが発生しました。もう一度お試しください。",
|
||||
"yes": "はい",
|
||||
"no": "いいえ",
|
||||
"dashboard": "ダッシュボード"
|
||||
},
|
||||
"createShare": {
|
||||
"title": "共有を作成",
|
||||
"nameLabel": "共有名",
|
||||
"expirationLabel": "有効期限",
|
||||
"expirationPlaceholder": "MM/DD/YYYY HH:MM",
|
||||
"maxViewsLabel": "最大ビュー数",
|
||||
"maxViewsPlaceholder": "無制限の場合は空白のままにする",
|
||||
"passwordProtection": "パスワード保護",
|
||||
"passwordLabel": "パスワード",
|
||||
"create": "共有を作成",
|
||||
"success": "共有が正常に作成されました",
|
||||
"error": "共有の作成に失敗しました"
|
||||
},
|
||||
"fileActions": {
|
||||
"editFile": "ファイルを編集",
|
||||
"nameLabel": "名前",
|
||||
"namePlaceholder": "新しい名前を入力してください",
|
||||
"extension": "拡張子",
|
||||
"descriptionLabel": "説明",
|
||||
"descriptionPlaceholder": "ファイルの説明を入力してください",
|
||||
"deleteFile": "ファイルを削除",
|
||||
"deleteConfirmation": "\"{{fileName}}\"を削除してもよろしいですか?",
|
||||
"deleteWarning": "この操作は元に戻せません。"
|
||||
},
|
||||
"filePreview": {
|
||||
"loading": "プレビューを読み込み中...",
|
||||
"notAvailable": "プレビューは利用できません",
|
||||
"downloadToView": "内容を見るためにファイルをダウンロードしてください",
|
||||
"audioNotSupported": "お使いのブラウザはオーディオ要素をサポートしていません",
|
||||
"videoNotSupported": "お使いのブラウザはビデオ要素をサポートしていません",
|
||||
"loadError": "プレビューの読み込みに失敗しました",
|
||||
"downloadError": "ファイルのダウンロードに失敗しました"
|
||||
},
|
||||
"generateShareLink": {
|
||||
"generateTitle": "共有リンクを生成",
|
||||
"updateTitle": "共有リンクを更新",
|
||||
"generateDescription": "ファイルを共有するためのリンクを生成します",
|
||||
"updateDescription": "この共有リンクのエイリアスを更新します",
|
||||
"aliasPlaceholder": "エイリアスを入力してください",
|
||||
"linkReady": "共有リンクの準備ができました:",
|
||||
"generateButton": "リンクを生成",
|
||||
"updateButton": "リンクを更新",
|
||||
"copyButton": "リンクをコピー",
|
||||
"success": "リンクが正常に生成されました",
|
||||
"error": "リンクの生成に失敗しました",
|
||||
"copied": "リンクがクリップボードにコピーされました"
|
||||
},
|
||||
"shareActions": {
|
||||
"deleteTitle": "共有を削除",
|
||||
"deleteConfirmation": "この共有を削除してもよろしいですか?この操作は元に戻せません。",
|
||||
"editTitle": "共有を編集",
|
||||
"nameLabel": "共有名",
|
||||
"expirationLabel": "有効期限",
|
||||
"expirationPlaceholder": "MM/DD/YYYY HH:MM",
|
||||
"maxViewsLabel": "最大ビュー数",
|
||||
"maxViewsPlaceholder": "無制限の場合は空白のままにする",
|
||||
"passwordProtection": "パスワード保護",
|
||||
"passwordLabel": "パスワード",
|
||||
"passwordPlaceholder": "パスワードを入力してください",
|
||||
"newPasswordLabel": "新しいパスワード(現在のパスワードを保持する場合は空白のまま)",
|
||||
"newPasswordPlaceholder": "新しいパスワードを入力してください",
|
||||
"manageFilesTitle": "ファイルの管理",
|
||||
"manageRecipientsTitle": "受信者の管理",
|
||||
"editSuccess": "共有が正常に更新されました",
|
||||
"editError": "共有の更新に失敗しました"
|
||||
},
|
||||
"shareDetails": {
|
||||
"title": "共有の詳細",
|
||||
"subtitle": "この共有の詳細情報",
|
||||
"basicInfo": "基本情報",
|
||||
"name": "名前",
|
||||
"untitled": "無題",
|
||||
"views": "ビュー数",
|
||||
"dates": "日付",
|
||||
"created": "作成日",
|
||||
"expires": "有効期限",
|
||||
"never": "なし",
|
||||
"security": "セキュリティ",
|
||||
"passwordProtected": "パスワード保護",
|
||||
"publicAccess": "公開アクセス",
|
||||
"maxViews": "最大ビュー数: {{count}}",
|
||||
"files": "ファイル ({{count}})",
|
||||
"recipients": "受信者 ({{count}})",
|
||||
"notAvailable": "該当なし",
|
||||
"invalidDate": "無効な日付です",
|
||||
"loadError": "共有の詳細の読み込みに失敗しました"
|
||||
},
|
||||
"uploadFile": {
|
||||
"title": "ファイルをアップロード",
|
||||
"selectFile": "ファイルを選択するにはクリックしてください",
|
||||
"preview": "プレビュー",
|
||||
"uploadProgress": "アップロードの進行状況",
|
||||
"upload": "アップロード",
|
||||
"success": "ファイルが正常にアップロードされました",
|
||||
"error": "ファイルのアップロードに失敗しました"
|
||||
},
|
||||
"filesTable": {
|
||||
"ariaLabel": "ファイルテーブル",
|
||||
"columns": {
|
||||
"name": "名前",
|
||||
"description": "説明",
|
||||
"size": "サイズ",
|
||||
"createdAt": "作成日",
|
||||
"updatedAt": "更新日",
|
||||
"actions": "操作"
|
||||
},
|
||||
"actions": {
|
||||
"menu": "ファイル操作メニュー",
|
||||
"preview": "プレビュー",
|
||||
"edit": "編集",
|
||||
"download": "ダウンロード",
|
||||
"delete": "削除"
|
||||
}
|
||||
},
|
||||
"sharesTable": {
|
||||
"ariaLabel": "共有テーブル",
|
||||
"never": "なし",
|
||||
"columns": {
|
||||
"name": "名前",
|
||||
"createdAt": "作成日",
|
||||
"expiresAt": "有効期限",
|
||||
"status": "ステータス",
|
||||
"security": "セキュリティ",
|
||||
"files": "ファイル",
|
||||
"recipients": "受信者",
|
||||
"actions": "操作"
|
||||
},
|
||||
"status": {
|
||||
"neverExpires": "無期限",
|
||||
"active": "アクティブ",
|
||||
"expired": "期限切れ"
|
||||
},
|
||||
"security": {
|
||||
"protected": "保護済み",
|
||||
"public": "公開"
|
||||
},
|
||||
"filesCount": "{{count}} ファイル",
|
||||
"recipientsCount": "{{count}} 受信者",
|
||||
"actions": {
|
||||
"menu": "共有操作メニュー",
|
||||
"edit": "編集",
|
||||
"manageFiles": "ファイル管理",
|
||||
"manageRecipients": "受信者管理",
|
||||
"viewDetails": "詳細を表示",
|
||||
"generateLink": "リンクを生成",
|
||||
"editLink": "リンクを編集",
|
||||
"copyLink": "リンクをコピー",
|
||||
"notifyRecipients": "受信者に通知",
|
||||
"delete": "削除"
|
||||
}
|
||||
},
|
||||
"footer": {
|
||||
"poweredBy": "提供:",
|
||||
"kyanHomepage": "Kyantech ホームページ"
|
||||
},
|
||||
"fileManager": {
|
||||
"downloadError": "ファイルのダウンロードに失敗しました",
|
||||
"updateSuccess": "ファイルが正常に更新されました",
|
||||
"updateError": "ファイルの更新に失敗しました",
|
||||
"deleteSuccess": "ファイルが正常に削除されました",
|
||||
"deleteError": "ファイルの削除に失敗しました"
|
||||
},
|
||||
"shareManager": {
|
||||
"deleteSuccess": "共有が正常に削除されました",
|
||||
"deleteError": "共有の削除に失敗しました",
|
||||
"updateSuccess": "共有が正常に更新されました",
|
||||
"updateError": "共有の更新に失敗しました",
|
||||
"filesUpdateSuccess": "ファイルが正常に更新されました",
|
||||
"filesUpdateError": "ファイルの更新に失敗しました",
|
||||
"recipientsUpdateSuccess": "受信者が正常に更新されました",
|
||||
"recipientsUpdateError": "受信者の更新に失敗しました",
|
||||
"linkGenerateSuccess": "共有リンクが正常に生成されました",
|
||||
"linkGenerateError": "共有リンクの生成に失敗しました",
|
||||
"notifyLoading": "通知を送信中...",
|
||||
"notifySuccess": "受信者に正常に通知しました",
|
||||
"notifyError": "受信者への通知に失敗しました"
|
||||
},
|
||||
"quickAccess": {
|
||||
"files": {
|
||||
"title": "マイファイル",
|
||||
"description": "アップロードされたファイルにアクセスし、管理します"
|
||||
},
|
||||
"shares": {
|
||||
"title": "マイ共有",
|
||||
"description": "共有されたファイルを表示および管理します"
|
||||
}
|
||||
},
|
||||
"recentFiles": {
|
||||
"title": "最近のアップロード",
|
||||
"viewAll": "すべて表示",
|
||||
"uploadFile": "ファイルをアップロード",
|
||||
"noFiles": "まだファイルがアップロードされていません"
|
||||
},
|
||||
"recentShares": {
|
||||
"title": "最近の共有",
|
||||
"viewAll": "すべて表示",
|
||||
"createShare": "共有を作成",
|
||||
"noShares": "まだ共有が作成されていません",
|
||||
"createFirst": "最初の共有を作成してください"
|
||||
},
|
||||
"storageUsage": {
|
||||
"title": "ストレージ使用量",
|
||||
"ariaLabel": "ストレージ使用状況のプログレスバー",
|
||||
"used": "{{size}} 使用済み",
|
||||
"available": "{{size}} 利用可能"
|
||||
},
|
||||
"dashboard": {
|
||||
"loadError": "ダッシュボードデータの読み込みに失敗しました",
|
||||
"linkCopied": "リンクがクリップボードにコピーされました",
|
||||
"pageTitle": "ダッシュボード",
|
||||
"breadcrumb": "ダッシュボード"
|
||||
},
|
||||
"emptyState": {
|
||||
"noFiles": "まだファイルがアップロードされていません",
|
||||
"uploadFile": "ファイルをアップロード"
|
||||
},
|
||||
"files": {
|
||||
"title": "すべてのファイル",
|
||||
"uploadFile": "ファイルをアップロード",
|
||||
"loadError": "ファイルの読み込みに失敗しました",
|
||||
"pageTitle": "マイファイル",
|
||||
"breadcrumb": "マイファイル"
|
||||
},
|
||||
"searchBar": {
|
||||
"placeholder": "ファイルを検索...",
|
||||
"results": "全{{total}}件中{{filtered}}件が見つかりました"
|
||||
},
|
||||
"forgotPassword": {
|
||||
"emailLabel": "メールアドレス",
|
||||
"emailPlaceholder": "メールアドレスを入力してください",
|
||||
"sending": "送信中...",
|
||||
"submit": "パスワードリセットの指示を送信",
|
||||
"backToLogin": "ログインに戻る",
|
||||
"title": "パスワードをお忘れですか?",
|
||||
"description": "メールアドレスを入力すると、パスワードリセットの指示を送信します。",
|
||||
"resetInstructions": "パスワードリセットの指示がメールに送信されました",
|
||||
"pageTitle": "パスワードをお忘れですか?"
|
||||
},
|
||||
"home": {
|
||||
"description": "WeTransferのオープンソース代替です。トラッキングや制限なしに安全にファイルを共有します。",
|
||||
"documentation": "ドキュメント",
|
||||
"starOnGithub": "GitHubでスターを付ける",
|
||||
"privacyMessage": "プライバシーを重視して作られています。アップロード前のファイルは、共有リンクを持つ人だけがアクセスできます。常に無料でオープンソースです。",
|
||||
"header": {
|
||||
"fileSharing": "ファイル共有",
|
||||
"tagline": "シンプルで無料"
|
||||
},
|
||||
"pageTitle": "ホーム"
|
||||
},
|
||||
"profile": {
|
||||
"password": {
|
||||
"title": "パスワードを変更",
|
||||
"newPassword": "新しいパスワード",
|
||||
"confirmPassword": "新しいパスワードの確認",
|
||||
"updateButton": "パスワードを更新"
|
||||
},
|
||||
"form": {
|
||||
"title": "プロフィール情報",
|
||||
"firstName": "名",
|
||||
"lastName": "姓",
|
||||
"username": "ユーザー名",
|
||||
"email": "メール",
|
||||
"updateButton": "プロフィールを更新"
|
||||
},
|
||||
"header": {
|
||||
"title": "プロフィール",
|
||||
"subtitle": "個人情報とパスワードを管理"
|
||||
},
|
||||
"picture": {
|
||||
"title": "プロフィール写真",
|
||||
"description": "写真アイコンをクリックしてプロフィール写真を変更",
|
||||
"uploadPhoto": "写真をアップロード",
|
||||
"removePhoto": "写真を削除"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "ユーザーデータの読み込みに失敗しました",
|
||||
"updateFailed": "プロフィールの更新に失敗しました",
|
||||
"passwordFailed": "パスワードの更新に失敗しました",
|
||||
"imageFailed": "プロフィール画像の更新に失敗しました",
|
||||
"imageRemoveFailed": "プロフィール画像の削除に失敗しました"
|
||||
},
|
||||
"messages": {
|
||||
"noChanges": "保存する変更はありません",
|
||||
"updateSuccess": "プロフィールが正常に更新されました",
|
||||
"fillPasswords": "両方のパスワードフィールドに入力してください",
|
||||
"passwordSuccess": "パスワードが正常に更新されました",
|
||||
"imageSuccess": "プロフィール画像が正常に更新されました",
|
||||
"imageRemoved": "プロフィール画像が正常に削除されました"
|
||||
},
|
||||
"pageTitle": "プロフィール"
|
||||
},
|
||||
"resetPassword": {
|
||||
"pageTitle": "パスワードリセット",
|
||||
"header": {
|
||||
"title": "パスワードリセット",
|
||||
"description": "以下に新しいパスワードを入力してください"
|
||||
},
|
||||
"form": {
|
||||
"newPassword": "新しいパスワード",
|
||||
"newPasswordPlaceholder": "新しいパスワードを入力してください",
|
||||
"confirmPassword": "新しいパスワードの確認",
|
||||
"confirmPasswordPlaceholder": "新しいパスワードを再入力してください",
|
||||
"resetting": "パスワードをリセット中...",
|
||||
"submit": "パスワードをリセット",
|
||||
"backToLogin": "ログインに戻る"
|
||||
},
|
||||
"messages": {
|
||||
"success": "パスワードが正常にリセットされました"
|
||||
},
|
||||
"errors": {
|
||||
"serverError": "パスワードのリセットに失敗しました。もう一度お試しください。",
|
||||
"invalidToken": "無効なリセットトークン、またはトークンが存在しません"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"groups": {
|
||||
"defaultDescription": "構成オプション",
|
||||
"general": {
|
||||
"title": "一般",
|
||||
"description": "基本的なアプリケーション設定"
|
||||
},
|
||||
"email": {
|
||||
"title": "メール",
|
||||
"description": "メールサーバーの設定"
|
||||
},
|
||||
"security": {
|
||||
"title": "セキュリティ",
|
||||
"description": "セキュリティおよび認証設定"
|
||||
},
|
||||
"storage": {
|
||||
"title": "ストレージ",
|
||||
"description": "ファイルストレージの設定"
|
||||
}
|
||||
},
|
||||
"fields": {
|
||||
"noDescription": "利用可能な説明はありません",
|
||||
"appLogo": {
|
||||
"title": "アプリケーションロゴ",
|
||||
"description": "アプリケーションのロゴ画像"
|
||||
},
|
||||
"appName": {
|
||||
"title": "アプリケーション名",
|
||||
"description": "ユーザーに表示されるアプリケーション名"
|
||||
},
|
||||
"appDescription": {
|
||||
"title": "アプリケーションの説明",
|
||||
"description": "アプリケーションの簡単な説明"
|
||||
},
|
||||
"showHomePage": {
|
||||
"title": "ホームページを表示",
|
||||
"description": "インストール後にホームページを表示"
|
||||
},
|
||||
"smtpEnabled": {
|
||||
"title": "SMTP有効",
|
||||
"description": "SMTPメール機能を有効または無効にする"
|
||||
},
|
||||
"smtpHost": {
|
||||
"title": "SMTPサーバー",
|
||||
"description": "SMTPサーバーのアドレス"
|
||||
},
|
||||
"smtpPort": {
|
||||
"title": "SMTPポート",
|
||||
"description": "SMTPサーバーのポート"
|
||||
},
|
||||
"smtpUser": {
|
||||
"title": "SMTPユーザー",
|
||||
"description": "SMTP認証用のユーザー名"
|
||||
},
|
||||
"smtpPass": {
|
||||
"title": "SMTPパスワード",
|
||||
"description": "SMTP認証用のパスワード"
|
||||
},
|
||||
"smtpFromName": {
|
||||
"title": "送信者名",
|
||||
"description": "送信されるメールの表示名"
|
||||
},
|
||||
"smtpFromEmail": {
|
||||
"title": "送信者メール",
|
||||
"description": "送信者のメールアドレス"
|
||||
},
|
||||
"maxLoginAttempts": {
|
||||
"title": "最大ログイン試行回数",
|
||||
"description": "ブロックする前の最大ログイン試行回数"
|
||||
},
|
||||
"loginBlockDuration": {
|
||||
"title": "ログインブロック期間",
|
||||
"description": "試行回数超過後のブロック期間(秒単位)"
|
||||
},
|
||||
"passwordMinLength": {
|
||||
"title": "パスワードの最小長",
|
||||
"description": "パスワードに必要な最小文字数"
|
||||
},
|
||||
"passwordResetTokenExpiration": {
|
||||
"title": "リセットトークンの有効期限",
|
||||
"description": "パスワードリセットトークンの有効期間(秒単位)"
|
||||
},
|
||||
"maxFileSize": {
|
||||
"title": "最大ファイルサイズ",
|
||||
"description": "アップロード可能な最大ファイルサイズ(バイト単位)"
|
||||
},
|
||||
"maxTotalStoragePerUser": {
|
||||
"title": "ユーザーごとの最大ストレージ",
|
||||
"description": "ユーザーごとの総ストレージ制限(バイト単位)"
|
||||
}
|
||||
},
|
||||
"buttons": {
|
||||
"save": "{{group}}を保存"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "設定の読み込みに失敗しました",
|
||||
"updateFailed": "設定の更新に失敗しました"
|
||||
},
|
||||
"messages": {
|
||||
"noChanges": "保存する変更はありません",
|
||||
"updateSuccess": "{{group}}の設定が正常に更新されました"
|
||||
},
|
||||
"title": "設定",
|
||||
"breadcrumb": "設定",
|
||||
"pageTitle": "設定"
|
||||
},
|
||||
"share": {
|
||||
"errors": {
|
||||
"invalidPassword": "無効なパスワードです。もう一度お試しください。",
|
||||
"loadFailed": "共有の読み込みに失敗しました",
|
||||
"downloadFailed": "ファイルのダウンロードに失敗しました"
|
||||
},
|
||||
"messages": {
|
||||
"downloadStarted": "ダウンロードが開始されました"
|
||||
},
|
||||
"password": {
|
||||
"title": "パスワード保護された共有",
|
||||
"protected": "この共有はパスワードで保護されています",
|
||||
"incorrect": "パスワードが正しくありません。もう一度お試しください。",
|
||||
"label": "パスワード",
|
||||
"placeholder": "共有のパスワードを入力してください",
|
||||
"submit": "送信"
|
||||
},
|
||||
"details": {
|
||||
"untitled": "無題",
|
||||
"created": "作成日: {{date}}",
|
||||
"expires": "有効期限: {{date}}"
|
||||
},
|
||||
"notFound": {
|
||||
"title": "共有が見つかりません",
|
||||
"description": "この共有は削除されたか、期限が切れている可能性があります。"
|
||||
},
|
||||
"pageTitle": "共有"
|
||||
},
|
||||
"shares": {
|
||||
"errors": {
|
||||
"loadFailed": "共有の読み込みに失敗しました",
|
||||
"notifyFailed": "受信者への通知に失敗しました",
|
||||
"smtpConfigFailed": "SMTP設定の読み込みに失敗しました"
|
||||
},
|
||||
"messages": {
|
||||
"linkCopied": "リンクがクリップボードにコピーされました",
|
||||
"recipientsNotified": "受信者に正常に通知されました"
|
||||
},
|
||||
"empty": {
|
||||
"message": "まだ共有が作成されていません",
|
||||
"createButton": "共有を作成"
|
||||
},
|
||||
"header": {
|
||||
"title": "マイ共有",
|
||||
"myShares": "マイ共有"
|
||||
},
|
||||
"search": {
|
||||
"title": "すべての共有",
|
||||
"createButton": "共有を作成",
|
||||
"placeholder": "共有を検索...",
|
||||
"results": "全{{total}}件中{{filtered}}件が見つかりました"
|
||||
},
|
||||
"pageTitle": "共有"
|
||||
},
|
||||
"users": {
|
||||
"modes": {
|
||||
"create": "作成",
|
||||
"edit": "編集"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "ユーザーの読み込みに失敗しました",
|
||||
"submitFailed": "ユーザーの{{mode}}に失敗しました",
|
||||
"deleteFailed": "ユーザーの削除に失敗しました",
|
||||
"statusUpdateFailed": "ユーザー状態の更新に失敗しました"
|
||||
},
|
||||
"messages": {
|
||||
"createSuccess": "ユーザーが正常に作成されました",
|
||||
"updateSuccess": "ユーザーが正常に更新されました",
|
||||
"deleteSuccess": "ユーザーが正常に削除されました",
|
||||
"activateSuccess": "ユーザーが正常にアクティブ化されました",
|
||||
"deactivateSuccess": "ユーザーが正常に非アクティブ化されました"
|
||||
},
|
||||
"actions": {
|
||||
"edit": "編集",
|
||||
"activate": "アクティブ化",
|
||||
"deactivate": "非アクティブ化",
|
||||
"delete": "削除"
|
||||
},
|
||||
"delete": {
|
||||
"title": "ユーザー削除の確認",
|
||||
"confirmation": "{{firstName}} {{lastName}} を削除してもよろしいですか?この操作は元に戻せません。",
|
||||
"confirm": "ユーザーを削除"
|
||||
},
|
||||
"form": {
|
||||
"titleCreate": "新しいユーザーを追加",
|
||||
"titleEdit": "ユーザーを編集",
|
||||
"firstName": "名",
|
||||
"lastName": "姓",
|
||||
"username": "ユーザー名",
|
||||
"email": "メール",
|
||||
"password": "パスワード",
|
||||
"newPassword": "新しいパスワード(任意)",
|
||||
"passwordPlaceholder": "現在のパスワードを保持する場合は空白のままにする",
|
||||
"role": "役割",
|
||||
"roleUser": "ユーザー",
|
||||
"roleAdmin": "管理者",
|
||||
"create": "作成",
|
||||
"save": "保存"
|
||||
},
|
||||
"status": {
|
||||
"title": "状態変更の確認",
|
||||
"confirmation": "{{firstName}} {{lastName}} を{{action}}してもよろしいですか?",
|
||||
"activate": "アクティブ化",
|
||||
"deactivate": "非アクティブ化",
|
||||
"user": "ユーザー"
|
||||
},
|
||||
"header": {
|
||||
"title": "ユーザー管理",
|
||||
"addUser": "ユーザーを追加",
|
||||
"management": "ユーザー管理"
|
||||
},
|
||||
"table": {
|
||||
"user": "ユーザー",
|
||||
"email": "メール",
|
||||
"status": "状態",
|
||||
"role": "役割",
|
||||
"actions": "操作",
|
||||
"active": "アクティブ",
|
||||
"inactive": "非アクティブ",
|
||||
"admin": "管理者",
|
||||
"userr": "ユーザー"
|
||||
}
|
||||
},
|
||||
"logo": {
|
||||
"labels": {
|
||||
"appLogo": "アプリケーションロゴ"
|
||||
},
|
||||
"buttons": {
|
||||
"upload": "ロゴをアップロード",
|
||||
"remove": "ロゴを削除"
|
||||
},
|
||||
"messages": {
|
||||
"uploadSuccess": "ロゴが正常にアップロードされました",
|
||||
"removeSuccess": "ロゴが正常に削除されました"
|
||||
},
|
||||
"errors": {
|
||||
"uploadFailed": "ロゴのアップロードに失敗しました",
|
||||
"removeFailed": "ロゴの削除に失敗しました"
|
||||
}
|
||||
},
|
||||
"navbar": {
|
||||
"logoAlt": "アプリケーションロゴ",
|
||||
"profileMenu": "プロフィールメニュー",
|
||||
"profile": "プロフィール",
|
||||
"settings": "設定",
|
||||
"usersManagement": "ユーザー管理",
|
||||
"logout": "ログアウト"
|
||||
}
|
||||
}
|
638
apps/app/messages/ko-KR.json
Normal file
638
apps/app/messages/ko-KR.json
Normal file
@@ -0,0 +1,638 @@
|
||||
{
|
||||
"login": {
|
||||
"welcome": "에 오신 것을 환영합니다",
|
||||
"signInToContinue": "계속하려면 로그인하세요",
|
||||
"emailLabel": "이메일 주소",
|
||||
"emailPlaceholder": "이메일을 입력하세요",
|
||||
"passwordLabel": "비밀번호",
|
||||
"passwordPlaceholder": "비밀번호를 입력하세요",
|
||||
"signIn": "로그인",
|
||||
"signingIn": "로그인 중...",
|
||||
"forgotPassword": "비밀번호를 잊으셨나요?",
|
||||
"pageTitle": "로그인"
|
||||
},
|
||||
"errors": {
|
||||
"invalidCredentials": "잘못된 이메일 또는 비밀번호입니다",
|
||||
"userNotFound": "사용자를 찾을 수 없습니다",
|
||||
"accountLocked": "계정이 잠겼습니다. 나중에 다시 시도하세요",
|
||||
"unexpectedError": "예기치 않은 오류가 발생했습니다. 다시 시도해주세요"
|
||||
},
|
||||
"validation": {
|
||||
"invalidEmail": "유효하지 않은 이메일 주소입니다",
|
||||
"passwordMinLength": "비밀번호는 최소 6자 이상이어야 합니다",
|
||||
"firstNameRequired": "이름은 필수입니다",
|
||||
"lastNameRequired": "성을 입력하세요",
|
||||
"usernameLength": "사용자 이름은 최소 3자 이상이어야 합니다",
|
||||
"usernameSpaces": "사용자 이름에는 공백을 사용할 수 없습니다",
|
||||
"passwordLength": "비밀번호는 최소 8자 이상이어야 합니다",
|
||||
"passwordsMatch": "비밀번호가 일치하지 않습니다",
|
||||
"emailRequired": "이메일은 필수입니다",
|
||||
"passwordRequired": "비밀번호는 필수입니다"
|
||||
},
|
||||
"fileSelector": {
|
||||
"availableFiles": "사용 가능한 파일 ({{count}})",
|
||||
"shareFiles": "파일 공유 ({{count}})",
|
||||
"searchPlaceholder": "파일 검색...",
|
||||
"noMatchingFiles": "일치하는 파일이 없습니다",
|
||||
"noAvailableFiles": "사용 가능한 파일이 없습니다",
|
||||
"noFilesInShare": "공유된 파일이 없습니다",
|
||||
"saveChanges": "변경 사항 저장"
|
||||
},
|
||||
"recipientSelector": {
|
||||
"emailPlaceholder": "수신자 이메일을 입력하세요",
|
||||
"add": "추가",
|
||||
"recipients": "수신자 ({{count}})",
|
||||
"notifyAll": "모두에게 알림",
|
||||
"noRecipients": "아직 수신자가 추가되지 않았습니다",
|
||||
"addSuccess": "수신자가 성공적으로 추가되었습니다",
|
||||
"addError": "수신자 추가에 실패했습니다",
|
||||
"removeSuccess": "수신자가 성공적으로 제거되었습니다",
|
||||
"removeError": "수신자 제거에 실패했습니다",
|
||||
"sendingNotifications": "알림 전송 중...",
|
||||
"notifySuccess": "수신자에게 성공적으로 알렸습니다",
|
||||
"notifyError": "수신자 알림 전송에 실패했습니다"
|
||||
},
|
||||
"navigation": {
|
||||
"dashboard": "대시보드"
|
||||
},
|
||||
"common": {
|
||||
"loading": "로딩 중입니다. 잠시 기다려주세요...",
|
||||
"cancel": "취소",
|
||||
"save": "저장",
|
||||
"delete": "삭제",
|
||||
"close": "닫기",
|
||||
"download": "다운로드",
|
||||
"unexpectedError": "예기치 않은 오류가 발생했습니다. 다시 시도해주세요.",
|
||||
"yes": "예",
|
||||
"no": "아니오",
|
||||
"dashboard": "대시보드"
|
||||
},
|
||||
"createShare": {
|
||||
"title": "공유 생성",
|
||||
"nameLabel": "공유 이름",
|
||||
"expirationLabel": "만료 날짜",
|
||||
"expirationPlaceholder": "MM/DD/YYYY HH:MM",
|
||||
"maxViewsLabel": "최대 조회수",
|
||||
"maxViewsPlaceholder": "무제한인 경우 비워두세요",
|
||||
"passwordProtection": "비밀번호 보호",
|
||||
"passwordLabel": "비밀번호",
|
||||
"create": "공유 생성",
|
||||
"success": "공유가 성공적으로 생성되었습니다",
|
||||
"error": "공유 생성에 실패했습니다"
|
||||
},
|
||||
"fileActions": {
|
||||
"editFile": "파일 편집",
|
||||
"nameLabel": "이름",
|
||||
"namePlaceholder": "새 이름을 입력하세요",
|
||||
"extension": "확장자",
|
||||
"descriptionLabel": "설명",
|
||||
"descriptionPlaceholder": "파일 설명을 입력하세요",
|
||||
"deleteFile": "파일 삭제",
|
||||
"deleteConfirmation": "\"{{fileName}}\"을(를) 삭제하시겠습니까?",
|
||||
"deleteWarning": "이 작업은 취소할 수 없습니다."
|
||||
},
|
||||
"filePreview": {
|
||||
"loading": "미리보기를 불러오는 중...",
|
||||
"notAvailable": "미리보기를 사용할 수 없습니다",
|
||||
"downloadToView": "내용을 보려면 파일을 다운로드하세요",
|
||||
"audioNotSupported": "브라우저가 오디오 요소를 지원하지 않습니다",
|
||||
"videoNotSupported": "브라우저가 비디오 요소를 지원하지 않습니다",
|
||||
"loadError": "미리보기 불러오기에 실패했습니다",
|
||||
"downloadError": "파일 다운로드에 실패했습니다"
|
||||
},
|
||||
"generateShareLink": {
|
||||
"generateTitle": "공유 링크 생성",
|
||||
"updateTitle": "공유 링크 업데이트",
|
||||
"generateDescription": "파일을 공유할 링크를 생성합니다",
|
||||
"updateDescription": "이 공유 링크의 별칭을 업데이트합니다",
|
||||
"aliasPlaceholder": "별칭을 입력하세요",
|
||||
"linkReady": "공유 링크가 준비되었습니다:",
|
||||
"generateButton": "링크 생성",
|
||||
"updateButton": "링크 업데이트",
|
||||
"copyButton": "링크 복사",
|
||||
"success": "링크가 성공적으로 생성되었습니다",
|
||||
"error": "링크 생성에 실패했습니다",
|
||||
"copied": "링크가 클립보드에 복사되었습니다"
|
||||
},
|
||||
"shareActions": {
|
||||
"deleteTitle": "공유 삭제",
|
||||
"deleteConfirmation": "이 공유를 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.",
|
||||
"editTitle": "공유 편집",
|
||||
"nameLabel": "공유 이름",
|
||||
"expirationLabel": "만료 날짜",
|
||||
"expirationPlaceholder": "MM/DD/YYYY HH:MM",
|
||||
"maxViewsLabel": "최대 조회수",
|
||||
"maxViewsPlaceholder": "무제한인 경우 비워두세요",
|
||||
"passwordProtection": "비밀번호 보호",
|
||||
"passwordLabel": "비밀번호",
|
||||
"passwordPlaceholder": "비밀번호를 입력하세요",
|
||||
"newPasswordLabel": "새 비밀번호 (현재 비밀번호 유지 시 비워두세요)",
|
||||
"newPasswordPlaceholder": "새 비밀번호를 입력하세요",
|
||||
"manageFilesTitle": "파일 관리",
|
||||
"manageRecipientsTitle": "수신자 관리",
|
||||
"editSuccess": "공유가 성공적으로 업데이트되었습니다",
|
||||
"editError": "공유 업데이트에 실패했습니다"
|
||||
},
|
||||
"shareDetails": {
|
||||
"title": "공유 세부 정보",
|
||||
"subtitle": "이 공유에 대한 자세한 정보",
|
||||
"basicInfo": "기본 정보",
|
||||
"name": "이름",
|
||||
"untitled": "제목 없음",
|
||||
"views": "조회수",
|
||||
"dates": "날짜",
|
||||
"created": "생성됨",
|
||||
"expires": "만료됨",
|
||||
"never": "없음",
|
||||
"security": "보안",
|
||||
"passwordProtected": "비밀번호 보호됨",
|
||||
"publicAccess": "공개 접근",
|
||||
"maxViews": "최대 조회수: {{count}}",
|
||||
"files": "파일 ({{count}})",
|
||||
"recipients": "수신자 ({{count}})",
|
||||
"notAvailable": "해당 없음",
|
||||
"invalidDate": "유효하지 않은 날짜입니다",
|
||||
"loadError": "공유 세부 정보를 불러오는데 실패했습니다"
|
||||
},
|
||||
"uploadFile": {
|
||||
"title": "파일 업로드",
|
||||
"selectFile": "파일 선택을 위해 클릭하세요",
|
||||
"preview": "미리보기",
|
||||
"uploadProgress": "업로드 진행",
|
||||
"upload": "업로드",
|
||||
"success": "파일이 성공적으로 업로드되었습니다",
|
||||
"error": "파일 업로드에 실패했습니다"
|
||||
},
|
||||
"filesTable": {
|
||||
"ariaLabel": "파일 테이블",
|
||||
"columns": {
|
||||
"name": "이름",
|
||||
"description": "설명",
|
||||
"size": "크기",
|
||||
"createdAt": "생성일",
|
||||
"updatedAt": "수정일",
|
||||
"actions": "작업"
|
||||
},
|
||||
"actions": {
|
||||
"menu": "파일 작업 메뉴",
|
||||
"preview": "미리보기",
|
||||
"edit": "편집",
|
||||
"download": "다운로드",
|
||||
"delete": "삭제"
|
||||
}
|
||||
},
|
||||
"sharesTable": {
|
||||
"ariaLabel": "공유 테이블",
|
||||
"never": "없음",
|
||||
"columns": {
|
||||
"name": "이름",
|
||||
"createdAt": "생성일",
|
||||
"expiresAt": "만료일",
|
||||
"status": "상태",
|
||||
"security": "보안",
|
||||
"files": "파일",
|
||||
"recipients": "수신자",
|
||||
"actions": "작업"
|
||||
},
|
||||
"status": {
|
||||
"neverExpires": "만료되지 않음",
|
||||
"active": "활성",
|
||||
"expired": "만료됨"
|
||||
},
|
||||
"security": {
|
||||
"protected": "보호됨",
|
||||
"public": "공개"
|
||||
},
|
||||
"filesCount": "{{count}}개의 파일",
|
||||
"recipientsCount": "{{count}}명의 수신자",
|
||||
"actions": {
|
||||
"menu": "공유 작업 메뉴",
|
||||
"edit": "편집",
|
||||
"manageFiles": "파일 관리",
|
||||
"manageRecipients": "수신자 관리",
|
||||
"viewDetails": "세부 정보 보기",
|
||||
"generateLink": "링크 생성",
|
||||
"editLink": "링크 편집",
|
||||
"copyLink": "링크 복사",
|
||||
"notifyRecipients": "수신자 알림",
|
||||
"delete": "삭제"
|
||||
}
|
||||
},
|
||||
"footer": {
|
||||
"poweredBy": "제공:",
|
||||
"kyanHomepage": "Kyantech 홈페이지"
|
||||
},
|
||||
"fileManager": {
|
||||
"downloadError": "파일 다운로드에 실패했습니다",
|
||||
"updateSuccess": "파일이 성공적으로 업데이트되었습니다",
|
||||
"updateError": "파일 업데이트에 실패했습니다",
|
||||
"deleteSuccess": "파일이 성공적으로 삭제되었습니다",
|
||||
"deleteError": "파일 삭제에 실패했습니다"
|
||||
},
|
||||
"shareManager": {
|
||||
"deleteSuccess": "공유가 성공적으로 삭제되었습니다",
|
||||
"deleteError": "공유 삭제에 실패했습니다",
|
||||
"updateSuccess": "공유가 성공적으로 업데이트되었습니다",
|
||||
"updateError": "공유 업데이트에 실패했습니다",
|
||||
"filesUpdateSuccess": "파일이 성공적으로 업데이트되었습니다",
|
||||
"filesUpdateError": "파일 업데이트에 실패했습니다",
|
||||
"recipientsUpdateSuccess": "수신자가 성공적으로 업데이트되었습니다",
|
||||
"recipientsUpdateError": "수신자 업데이트에 실패했습니다",
|
||||
"linkGenerateSuccess": "공유 링크가 성공적으로 생성되었습니다",
|
||||
"linkGenerateError": "공유 링크 생성에 실패했습니다",
|
||||
"notifyLoading": "알림 전송 중...",
|
||||
"notifySuccess": "수신자에게 성공적으로 알렸습니다",
|
||||
"notifyError": "수신자 알림 전송에 실패했습니다"
|
||||
},
|
||||
"quickAccess": {
|
||||
"files": {
|
||||
"title": "내 파일",
|
||||
"description": "업로드된 파일에 접근하고 관리합니다"
|
||||
},
|
||||
"shares": {
|
||||
"title": "내 공유",
|
||||
"description": "공유된 파일을 보고 관리합니다"
|
||||
}
|
||||
},
|
||||
"recentFiles": {
|
||||
"title": "최근 업로드",
|
||||
"viewAll": "전체 보기",
|
||||
"uploadFile": "파일 업로드",
|
||||
"noFiles": "아직 파일이 업로드되지 않았습니다"
|
||||
},
|
||||
"recentShares": {
|
||||
"title": "최근 공유",
|
||||
"viewAll": "전체 보기",
|
||||
"createShare": "공유 생성",
|
||||
"noShares": "아직 공유가 생성되지 않았습니다",
|
||||
"createFirst": "첫 번째 공유를 생성하세요"
|
||||
},
|
||||
"storageUsage": {
|
||||
"title": "스토리지 사용량",
|
||||
"ariaLabel": "스토리지 사용량 진행 바",
|
||||
"used": "{{size}} 사용됨",
|
||||
"available": "{{size}} 사용 가능"
|
||||
},
|
||||
"dashboard": {
|
||||
"loadError": "대시보드 데이터를 불러오는데 실패했습니다",
|
||||
"linkCopied": "링크가 클립보드에 복사되었습니다",
|
||||
"pageTitle": "대시보드",
|
||||
"breadcrumb": "대시보드"
|
||||
},
|
||||
"emptyState": {
|
||||
"noFiles": "아직 파일이 업로드되지 않았습니다",
|
||||
"uploadFile": "파일 업로드"
|
||||
},
|
||||
"files": {
|
||||
"title": "모든 파일",
|
||||
"uploadFile": "파일 업로드",
|
||||
"loadError": "파일을 불러오는데 실패했습니다",
|
||||
"pageTitle": "내 파일",
|
||||
"breadcrumb": "내 파일"
|
||||
},
|
||||
"searchBar": {
|
||||
"placeholder": "파일 검색...",
|
||||
"results": "전체 {{total}}개 중 {{filtered}}개 파일을 찾았습니다"
|
||||
},
|
||||
"forgotPassword": {
|
||||
"emailLabel": "이메일 주소",
|
||||
"emailPlaceholder": "이메일을 입력하세요",
|
||||
"sending": "전송 중...",
|
||||
"submit": "비밀번호 재설정 지침 전송",
|
||||
"backToLogin": "로그인으로 돌아가기",
|
||||
"title": "비밀번호를 잊으셨나요?",
|
||||
"description": "이메일 주소를 입력하면 비밀번호 재설정 지침을 보내드립니다.",
|
||||
"resetInstructions": "비밀번호 재설정 지침이 이메일로 전송되었습니다",
|
||||
"pageTitle": "비밀번호를 잊으셨나요?"
|
||||
},
|
||||
"home": {
|
||||
"description": "WeTransfer의 오픈소스 대안입니다. 추적이나 제한 없이 파일을 안전하게 공유하세요.",
|
||||
"documentation": "문서",
|
||||
"starOnGithub": "GitHub에서 별표 달기",
|
||||
"privacyMessage": "개인정보 보호를 고려하여 제작되었습니다. 업로드 전 파일은 공유 링크가 있는 사람만 접근할 수 있습니다. 항상 무료이며 오픈소스입니다.",
|
||||
"header": {
|
||||
"fileSharing": "파일 공유",
|
||||
"tagline": "심플하고 무료"
|
||||
},
|
||||
"pageTitle": "홈"
|
||||
},
|
||||
"profile": {
|
||||
"password": {
|
||||
"title": "비밀번호 변경",
|
||||
"newPassword": "새 비밀번호",
|
||||
"confirmPassword": "새 비밀번호 확인",
|
||||
"updateButton": "비밀번호 업데이트"
|
||||
},
|
||||
"form": {
|
||||
"title": "프로필 정보",
|
||||
"firstName": "이름",
|
||||
"lastName": "성",
|
||||
"username": "사용자 이름",
|
||||
"email": "이메일",
|
||||
"updateButton": "프로필 업데이트"
|
||||
},
|
||||
"header": {
|
||||
"title": "프로필",
|
||||
"subtitle": "개인 정보와 비밀번호를 관리하세요"
|
||||
},
|
||||
"picture": {
|
||||
"title": "프로필 사진",
|
||||
"description": "프로필 사진을 변경하려면 카메라 아이콘을 클릭하세요",
|
||||
"uploadPhoto": "사진 업로드",
|
||||
"removePhoto": "사진 삭제"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "사용자 데이터를 불러오는데 실패했습니다",
|
||||
"updateFailed": "프로필 업데이트에 실패했습니다",
|
||||
"passwordFailed": "비밀번호 업데이트에 실패했습니다",
|
||||
"imageFailed": "프로필 이미지 업데이트에 실패했습니다",
|
||||
"imageRemoveFailed": "프로필 이미지 삭제에 실패했습니다"
|
||||
},
|
||||
"messages": {
|
||||
"noChanges": "저장할 변경 사항이 없습니다",
|
||||
"updateSuccess": "프로필이 성공적으로 업데이트되었습니다",
|
||||
"fillPasswords": "두 비밀번호 필드를 모두 입력하세요",
|
||||
"passwordSuccess": "비밀번호가 성공적으로 업데이트되었습니다",
|
||||
"imageSuccess": "프로필 이미지가 성공적으로 업데이트되었습니다",
|
||||
"imageRemoved": "프로필 이미지가 성공적으로 삭제되었습니다"
|
||||
},
|
||||
"pageTitle": "프로필"
|
||||
},
|
||||
"resetPassword": {
|
||||
"pageTitle": "비밀번호 재설정",
|
||||
"header": {
|
||||
"title": "비밀번호 재설정",
|
||||
"description": "아래에 새 비밀번호를 입력하세요"
|
||||
},
|
||||
"form": {
|
||||
"newPassword": "새 비밀번호",
|
||||
"newPasswordPlaceholder": "새 비밀번호를 입력하세요",
|
||||
"confirmPassword": "새 비밀번호 확인",
|
||||
"confirmPasswordPlaceholder": "새 비밀번호를 다시 입력하세요",
|
||||
"resetting": "비밀번호 재설정 중...",
|
||||
"submit": "비밀번호 재설정",
|
||||
"backToLogin": "로그인으로 돌아가기"
|
||||
},
|
||||
"messages": {
|
||||
"success": "비밀번호가 성공적으로 재설정되었습니다"
|
||||
},
|
||||
"errors": {
|
||||
"serverError": "비밀번호 재설정에 실패했습니다. 다시 시도해주세요.",
|
||||
"invalidToken": "유효하지 않거나 누락된 재설정 토큰"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"groups": {
|
||||
"defaultDescription": "구성 옵션",
|
||||
"general": {
|
||||
"title": "일반",
|
||||
"description": "기본 애플리케이션 설정"
|
||||
},
|
||||
"email": {
|
||||
"title": "이메일",
|
||||
"description": "이메일 서버 구성"
|
||||
},
|
||||
"security": {
|
||||
"title": "보안",
|
||||
"description": "보안 및 인증 설정"
|
||||
},
|
||||
"storage": {
|
||||
"title": "스토리지",
|
||||
"description": "파일 스토리지 구성"
|
||||
}
|
||||
},
|
||||
"fields": {
|
||||
"noDescription": "설명이 제공되지 않았습니다",
|
||||
"appLogo": {
|
||||
"title": "애플리케이션 로고",
|
||||
"description": "애플리케이션 로고 이미지"
|
||||
},
|
||||
"appName": {
|
||||
"title": "애플리케이션 이름",
|
||||
"description": "사용자에게 표시되는 애플리케이션 이름"
|
||||
},
|
||||
"appDescription": {
|
||||
"title": "애플리케이션 설명",
|
||||
"description": "애플리케이션에 대한 간략한 설명"
|
||||
},
|
||||
"showHomePage": {
|
||||
"title": "홈페이지 표시",
|
||||
"description": "설치 후 홈페이지를 표시합니다"
|
||||
},
|
||||
"smtpEnabled": {
|
||||
"title": "SMTP 사용",
|
||||
"description": "SMTP 이메일 기능을 활성화 또는 비활성화합니다"
|
||||
},
|
||||
"smtpHost": {
|
||||
"title": "SMTP 서버",
|
||||
"description": "SMTP 서버 주소"
|
||||
},
|
||||
"smtpPort": {
|
||||
"title": "SMTP 포트",
|
||||
"description": "SMTP 서버 포트"
|
||||
},
|
||||
"smtpUser": {
|
||||
"title": "SMTP 사용자",
|
||||
"description": "SMTP 인증을 위한 사용자 이름"
|
||||
},
|
||||
"smtpPass": {
|
||||
"title": "SMTP 비밀번호",
|
||||
"description": "SMTP 인증을 위한 비밀번호"
|
||||
},
|
||||
"smtpFromName": {
|
||||
"title": "발신자 이름",
|
||||
"description": "보내는 이메일에 표시될 이름"
|
||||
},
|
||||
"smtpFromEmail": {
|
||||
"title": "발신자 이메일",
|
||||
"description": "발신자 이메일 주소"
|
||||
},
|
||||
"maxLoginAttempts": {
|
||||
"title": "최대 로그인 시도 횟수",
|
||||
"description": "차단되기 전 최대 로그인 시도 횟수"
|
||||
},
|
||||
"loginBlockDuration": {
|
||||
"title": "로그인 차단 기간",
|
||||
"description": "시도 초과 시 차단되는 시간(초 단위)"
|
||||
},
|
||||
"passwordMinLength": {
|
||||
"title": "최소 비밀번호 길이",
|
||||
"description": "비밀번호에 필요한 최소 문자 수"
|
||||
},
|
||||
"passwordResetTokenExpiration": {
|
||||
"title": "비밀번호 재설정 토큰 만료",
|
||||
"description": "비밀번호 재설정 토큰의 유효 기간(초 단위)"
|
||||
},
|
||||
"maxFileSize": {
|
||||
"title": "최대 파일 크기",
|
||||
"description": "업로드 가능한 최대 파일 크기(바이트 단위)"
|
||||
},
|
||||
"maxTotalStoragePerUser": {
|
||||
"title": "사용자당 최대 스토리지",
|
||||
"description": "사용자당 총 스토리지 제한(바이트 단위)"
|
||||
}
|
||||
},
|
||||
"buttons": {
|
||||
"save": "{{group}} 저장"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "설정을 불러오는데 실패했습니다",
|
||||
"updateFailed": "설정 업데이트에 실패했습니다"
|
||||
},
|
||||
"messages": {
|
||||
"noChanges": "저장할 변경 사항이 없습니다",
|
||||
"updateSuccess": "{{group}} 설정이 성공적으로 업데이트되었습니다"
|
||||
},
|
||||
"title": "설정",
|
||||
"breadcrumb": "설정",
|
||||
"pageTitle": "설정"
|
||||
},
|
||||
"share": {
|
||||
"errors": {
|
||||
"invalidPassword": "잘못된 비밀번호입니다. 다시 시도해주세요.",
|
||||
"loadFailed": "공유를 불러오는데 실패했습니다",
|
||||
"downloadFailed": "파일 다운로드에 실패했습니다"
|
||||
},
|
||||
"messages": {
|
||||
"downloadStarted": "다운로드가 시작되었습니다"
|
||||
},
|
||||
"password": {
|
||||
"title": "비밀번호 보호 공유",
|
||||
"protected": "이 공유는 비밀번호로 보호되어 있습니다",
|
||||
"incorrect": "비밀번호가 올바르지 않습니다. 다시 시도해주세요.",
|
||||
"label": "비밀번호",
|
||||
"placeholder": "공유 비밀번호를 입력하세요",
|
||||
"submit": "제출"
|
||||
},
|
||||
"details": {
|
||||
"untitled": "제목 없음",
|
||||
"created": "생성됨: {{date}}",
|
||||
"expires": "만료됨: {{date}}"
|
||||
},
|
||||
"notFound": {
|
||||
"title": "공유를 찾을 수 없습니다",
|
||||
"description": "이 공유는 삭제되었거나 만료되었을 수 있습니다."
|
||||
},
|
||||
"pageTitle": "공유"
|
||||
},
|
||||
"shares": {
|
||||
"errors": {
|
||||
"loadFailed": "공유 목록을 불러오는데 실패했습니다",
|
||||
"notifyFailed": "수신자 알림에 실패했습니다",
|
||||
"smtpConfigFailed": "SMTP 설정을 불러오는데 실패했습니다"
|
||||
},
|
||||
"messages": {
|
||||
"linkCopied": "링크가 클립보드에 복사되었습니다",
|
||||
"recipientsNotified": "수신자에게 성공적으로 알렸습니다"
|
||||
},
|
||||
"empty": {
|
||||
"message": "아직 공유가 생성되지 않았습니다",
|
||||
"createButton": "공유 생성"
|
||||
},
|
||||
"header": {
|
||||
"title": "내 공유",
|
||||
"myShares": "내 공유"
|
||||
},
|
||||
"search": {
|
||||
"title": "전체 공유",
|
||||
"createButton": "공유 생성",
|
||||
"placeholder": "공유 검색...",
|
||||
"results": "전체 {{total}}개 중 {{filtered}}개가 검색되었습니다"
|
||||
},
|
||||
"pageTitle": "공유"
|
||||
},
|
||||
"users": {
|
||||
"modes": {
|
||||
"create": "생성",
|
||||
"edit": "편집"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "사용자 목록을 불러오는데 실패했습니다",
|
||||
"submitFailed": "사용자 {{mode}}에 실패했습니다",
|
||||
"deleteFailed": "사용자 삭제에 실패했습니다",
|
||||
"statusUpdateFailed": "사용자 상태 업데이트에 실패했습니다"
|
||||
},
|
||||
"messages": {
|
||||
"createSuccess": "사용자가 성공적으로 생성되었습니다",
|
||||
"updateSuccess": "사용자가 성공적으로 업데이트되었습니다",
|
||||
"deleteSuccess": "사용자가 성공적으로 삭제되었습니다",
|
||||
"activateSuccess": "사용자가 성공적으로 활성화되었습니다",
|
||||
"deactivateSuccess": "사용자가 성공적으로 비활성화되었습니다"
|
||||
},
|
||||
"actions": {
|
||||
"edit": "편집",
|
||||
"activate": "활성화",
|
||||
"deactivate": "비활성화",
|
||||
"delete": "삭제"
|
||||
},
|
||||
"delete": {
|
||||
"title": "사용자 삭제 확인",
|
||||
"confirmation": "{{firstName}} {{lastName}} 사용자를 삭제하시겠습니까? 이 작업은 취소할 수 없습니다.",
|
||||
"confirm": "사용자 삭제"
|
||||
},
|
||||
"form": {
|
||||
"titleCreate": "새 사용자 추가",
|
||||
"titleEdit": "사용자 편집",
|
||||
"firstName": "이름",
|
||||
"lastName": "성",
|
||||
"username": "사용자 이름",
|
||||
"email": "이메일",
|
||||
"password": "비밀번호",
|
||||
"newPassword": "새 비밀번호 (선택 사항)",
|
||||
"passwordPlaceholder": "현재 비밀번호를 유지하려면 비워두세요",
|
||||
"role": "역할",
|
||||
"roleUser": "사용자",
|
||||
"roleAdmin": "관리자",
|
||||
"create": "생성",
|
||||
"save": "저장"
|
||||
},
|
||||
"status": {
|
||||
"title": "상태 변경 확인",
|
||||
"confirmation": "{{firstName}} {{lastName}} 사용자를 {{action}}하시겠습니까?",
|
||||
"activate": "활성화",
|
||||
"deactivate": "비활성화",
|
||||
"user": "사용자"
|
||||
},
|
||||
"header": {
|
||||
"title": "사용자 관리",
|
||||
"addUser": "사용자 추가",
|
||||
"management": "사용자 관리"
|
||||
},
|
||||
"table": {
|
||||
"user": "사용자",
|
||||
"email": "이메일",
|
||||
"status": "상태",
|
||||
"role": "역할",
|
||||
"actions": "작업",
|
||||
"active": "활성",
|
||||
"inactive": "비활성",
|
||||
"admin": "관리자",
|
||||
"userr": "사용자"
|
||||
}
|
||||
},
|
||||
"logo": {
|
||||
"labels": {
|
||||
"appLogo": "애플리케이션 로고"
|
||||
},
|
||||
"buttons": {
|
||||
"upload": "로고 업로드",
|
||||
"remove": "로고 삭제"
|
||||
},
|
||||
"messages": {
|
||||
"uploadSuccess": "로고가 성공적으로 업로드되었습니다",
|
||||
"removeSuccess": "로고가 성공적으로 삭제되었습니다"
|
||||
},
|
||||
"errors": {
|
||||
"uploadFailed": "로고 업로드에 실패했습니다",
|
||||
"removeFailed": "로고 삭제에 실패했습니다"
|
||||
}
|
||||
},
|
||||
"navbar": {
|
||||
"logoAlt": "애플리케이션 로고",
|
||||
"profileMenu": "프로필 메뉴",
|
||||
"profile": "프로필",
|
||||
"settings": "설정",
|
||||
"usersManagement": "사용자 관리",
|
||||
"logout": "로그아웃"
|
||||
}
|
||||
}
|
638
apps/app/messages/pt-BR.json
Normal file
638
apps/app/messages/pt-BR.json
Normal file
@@ -0,0 +1,638 @@
|
||||
{
|
||||
"login": {
|
||||
"welcome": "Bem-vindo ao",
|
||||
"signInToContinue": "Entre para continuar",
|
||||
"emailLabel": "Endereço de E-mail",
|
||||
"emailPlaceholder": "Digite seu e-mail",
|
||||
"passwordLabel": "Senha",
|
||||
"passwordPlaceholder": "Digite sua senha",
|
||||
"signIn": "Entrar",
|
||||
"signingIn": "Entrando...",
|
||||
"forgotPassword": "Esqueceu a senha?",
|
||||
"pageTitle": "Entrar"
|
||||
},
|
||||
"errors": {
|
||||
"invalidCredentials": "E-mail ou senha inválidos",
|
||||
"userNotFound": "Usuário não encontrado",
|
||||
"accountLocked": "Conta bloqueada. Tente novamente mais tarde",
|
||||
"unexpectedError": "Ocorreu um erro inesperado. Por favor, tente novamente"
|
||||
},
|
||||
"validation": {
|
||||
"invalidEmail": "Endereço de email inválido",
|
||||
"passwordMinLength": "A senha deve ter pelo menos 6 caracteres",
|
||||
"firstNameRequired": "Nome é obrigatório",
|
||||
"lastNameRequired": "Sobrenome é obrigatório",
|
||||
"usernameLength": "Nome de usuário deve ter pelo menos 3 caracteres",
|
||||
"usernameSpaces": "Nome de usuário não pode conter espaços",
|
||||
"passwordLength": "A senha deve ter pelo menos 8 caracteres",
|
||||
"passwordsMatch": "As senhas não coincidem",
|
||||
"emailRequired": "Email é obrigatório",
|
||||
"passwordRequired": "Senha é obrigatória"
|
||||
},
|
||||
"fileSelector": {
|
||||
"availableFiles": "Arquivos Disponíveis ({{count}})",
|
||||
"shareFiles": "Arquivos Compartilhados ({{count}})",
|
||||
"searchPlaceholder": "Buscar arquivos...",
|
||||
"noMatchingFiles": "Nenhum arquivo encontrado",
|
||||
"noAvailableFiles": "Nenhum arquivo disponível",
|
||||
"noFilesInShare": "Nenhum arquivo compartilhado",
|
||||
"saveChanges": "Salvar Alterações"
|
||||
},
|
||||
"recipientSelector": {
|
||||
"emailPlaceholder": "Digite o e-mail do destinatário",
|
||||
"add": "Adicionar",
|
||||
"recipients": "Destinatários ({{count}})",
|
||||
"notifyAll": "Notificar Todos",
|
||||
"noRecipients": "Nenhum destinatário adicionado",
|
||||
"addSuccess": "Destinatário adicionado com sucesso",
|
||||
"addError": "Falha ao adicionar destinatário",
|
||||
"removeSuccess": "Destinatário removido com sucesso",
|
||||
"removeError": "Falha ao remover destinatário",
|
||||
"sendingNotifications": "Enviando notificações...",
|
||||
"notifySuccess": "Destinatários notificados com sucesso",
|
||||
"notifyError": "Falha ao notificar destinatários"
|
||||
},
|
||||
"navigation": {
|
||||
"dashboard": "Painel"
|
||||
},
|
||||
"common": {
|
||||
"loading": "Carregando, aguarde...",
|
||||
"cancel": "Cancelar",
|
||||
"save": "Salvar",
|
||||
"delete": "Excluir",
|
||||
"close": "Fechar",
|
||||
"download": "Baixar",
|
||||
"unexpectedError": "Ocorreu um erro inesperado. Por favor, tente novamente.",
|
||||
"yes": "Sim",
|
||||
"no": "Não",
|
||||
"dashboard": "Painel"
|
||||
},
|
||||
"createShare": {
|
||||
"title": "Criar Compartilhamento",
|
||||
"nameLabel": "Nome do Compartilhamento",
|
||||
"expirationLabel": "Data de Expiração",
|
||||
"expirationPlaceholder": "DD/MM/AAAA HH:MM",
|
||||
"maxViewsLabel": "Máximo de Visualizações",
|
||||
"maxViewsPlaceholder": "Deixe vazio para ilimitado",
|
||||
"passwordProtection": "Protegido por Senha",
|
||||
"passwordLabel": "Senha",
|
||||
"create": "Criar Compartilhamento",
|
||||
"success": "Compartilhamento criado com sucesso",
|
||||
"error": "Falha ao criar compartilhamento"
|
||||
},
|
||||
"fileActions": {
|
||||
"editFile": "Editar Arquivo",
|
||||
"nameLabel": "Nome",
|
||||
"namePlaceholder": "Digite o novo nome",
|
||||
"extension": "Extensão",
|
||||
"descriptionLabel": "Descrição",
|
||||
"descriptionPlaceholder": "Digite a descrição do arquivo",
|
||||
"deleteFile": "Excluir Arquivo",
|
||||
"deleteConfirmation": "Tem certeza que deseja excluir \"{{fileName}}\"?",
|
||||
"deleteWarning": "Esta ação não pode ser desfeita."
|
||||
},
|
||||
"filePreview": {
|
||||
"loading": "Carregando visualização...",
|
||||
"notAvailable": "Visualização não disponível",
|
||||
"downloadToView": "Faça o download para visualizar o conteúdo",
|
||||
"audioNotSupported": "Seu navegador não suporta o elemento de áudio",
|
||||
"videoNotSupported": "Seu navegador não suporta o elemento de vídeo",
|
||||
"loadError": "Falha ao carregar a visualização",
|
||||
"downloadError": "Falha ao baixar o arquivo"
|
||||
},
|
||||
"generateShareLink": {
|
||||
"generateTitle": "Gerar Link de Compartilhamento",
|
||||
"updateTitle": "Atualizar Link de Compartilhamento",
|
||||
"generateDescription": "Gere um link para compartilhar seus arquivos",
|
||||
"updateDescription": "Atualize o alias deste link de compartilhamento",
|
||||
"aliasPlaceholder": "Digite o alias",
|
||||
"linkReady": "Seu link de compartilhamento está pronto:",
|
||||
"generateButton": "Gerar Link",
|
||||
"updateButton": "Atualizar Link",
|
||||
"copyButton": "Copiar Link",
|
||||
"success": "Link gerado com sucesso",
|
||||
"error": "Erro ao gerar link",
|
||||
"copied": "Link copiado para a área de transferência"
|
||||
},
|
||||
"shareActions": {
|
||||
"deleteTitle": "Excluir Compartilhamento",
|
||||
"deleteConfirmation": "Tem certeza que deseja excluir este compartilhamento? Esta ação não pode ser desfeita.",
|
||||
"editTitle": "Editar Compartilhamento",
|
||||
"nameLabel": "Nome do Compartilhamento",
|
||||
"expirationLabel": "Data de Expiração",
|
||||
"expirationPlaceholder": "DD/MM/AAAA HH:MM",
|
||||
"maxViewsLabel": "Máximo de Visualizações",
|
||||
"maxViewsPlaceholder": "Deixe vazio para ilimitado",
|
||||
"passwordProtection": "Protegido por Senha",
|
||||
"passwordLabel": "Senha",
|
||||
"passwordPlaceholder": "Digite a senha",
|
||||
"newPasswordLabel": "Nova Senha (deixe vazio para manter a atual)",
|
||||
"newPasswordPlaceholder": "Digite a nova senha",
|
||||
"manageFilesTitle": "Gerenciar Arquivos",
|
||||
"manageRecipientsTitle": "Gerenciar Destinatários",
|
||||
"editSuccess": "Compartilhamento atualizado com sucesso",
|
||||
"editError": "Falha ao atualizar compartilhamento"
|
||||
},
|
||||
"shareDetails": {
|
||||
"title": "Detalhes do Compartilhamento",
|
||||
"subtitle": "Informações detalhadas sobre este compartilhamento",
|
||||
"basicInfo": "Informações Básicas",
|
||||
"name": "Nome",
|
||||
"untitled": "Compartilhamento sem título",
|
||||
"views": "Visualizações",
|
||||
"dates": "Datas",
|
||||
"created": "Criado em: {{date}}",
|
||||
"expires": "Expira em: {{date}}",
|
||||
"never": "Nunca",
|
||||
"security": "Segurança",
|
||||
"passwordProtected": "Protegido por Senha",
|
||||
"publicAccess": "Acesso Público",
|
||||
"maxViews": "Máximo de Visualizações: {{count}}",
|
||||
"files": "Arquivos ({{count}})",
|
||||
"recipients": "Destinatários ({{count}})",
|
||||
"notAvailable": "N/A",
|
||||
"invalidDate": "Data inválida",
|
||||
"loadError": "Falha ao carregar detalhes do compartilhamento"
|
||||
},
|
||||
"uploadFile": {
|
||||
"title": "Enviar Arquivo",
|
||||
"selectFile": "Clique para selecionar um arquivo",
|
||||
"preview": "Pré-visualização",
|
||||
"uploadProgress": "Progresso do upload",
|
||||
"upload": "Enviar",
|
||||
"success": "Arquivo enviado com sucesso",
|
||||
"error": "Falha ao enviar arquivo"
|
||||
},
|
||||
"filesTable": {
|
||||
"ariaLabel": "Tabela de arquivos",
|
||||
"columns": {
|
||||
"name": "NOME",
|
||||
"description": "DESCRIÇÃO",
|
||||
"size": "TAMANHO",
|
||||
"createdAt": "CRIADO EM",
|
||||
"updatedAt": "ATUALIZADO EM",
|
||||
"actions": "AÇÕES"
|
||||
},
|
||||
"actions": {
|
||||
"menu": "Menu de ações do arquivo",
|
||||
"preview": "Visualizar",
|
||||
"edit": "Editar",
|
||||
"download": "Baixar",
|
||||
"delete": "Excluir"
|
||||
}
|
||||
},
|
||||
"sharesTable": {
|
||||
"ariaLabel": "Tabela de compartilhamentos",
|
||||
"never": "Nunca",
|
||||
"columns": {
|
||||
"name": "NOME",
|
||||
"createdAt": "CRIADO EM",
|
||||
"expiresAt": "EXPIRA EM",
|
||||
"status": "STATUS",
|
||||
"security": "SEGURANÇA",
|
||||
"files": "ARQUIVOS",
|
||||
"recipients": "DESTINATÁRIOS",
|
||||
"actions": "AÇÕES"
|
||||
},
|
||||
"status": {
|
||||
"neverExpires": "Nunca Expira",
|
||||
"active": "Ativo",
|
||||
"expired": "Expirado"
|
||||
},
|
||||
"security": {
|
||||
"protected": "Protegido",
|
||||
"public": "Público"
|
||||
},
|
||||
"filesCount": "{{count}} arquivos",
|
||||
"recipientsCount": "{{count}} destinatários",
|
||||
"actions": {
|
||||
"menu": "Menu de ações do compartilhamento",
|
||||
"edit": "Editar",
|
||||
"manageFiles": "Gerenciar Arquivos",
|
||||
"manageRecipients": "Gerenciar Destinatários",
|
||||
"viewDetails": "Ver Detalhes",
|
||||
"generateLink": "Gerar Link",
|
||||
"editLink": "Editar Link",
|
||||
"copyLink": "Copiar Link",
|
||||
"notifyRecipients": "Notificar Destinatários",
|
||||
"delete": "Excluir"
|
||||
}
|
||||
},
|
||||
"footer": {
|
||||
"poweredBy": "Desenvolvido por",
|
||||
"kyanHomepage": "Página inicial da Kyantech"
|
||||
},
|
||||
"fileManager": {
|
||||
"downloadError": "Falha ao baixar arquivo",
|
||||
"updateSuccess": "Arquivo atualizado com sucesso",
|
||||
"updateError": "Falha ao atualizar arquivo",
|
||||
"deleteSuccess": "Arquivo excluído com sucesso",
|
||||
"deleteError": "Falha ao excluir arquivo"
|
||||
},
|
||||
"shareManager": {
|
||||
"deleteSuccess": "Compartilhamento excluído com sucesso",
|
||||
"deleteError": "Falha ao excluir compartilhamento",
|
||||
"updateSuccess": "Compartilhamento atualizado com sucesso",
|
||||
"updateError": "Falha ao atualizar compartilhamento",
|
||||
"filesUpdateSuccess": "Arquivos atualizados com sucesso",
|
||||
"filesUpdateError": "Falha ao atualizar arquivos",
|
||||
"recipientsUpdateSuccess": "Destinatários atualizados com sucesso",
|
||||
"recipientsUpdateError": "Falha ao atualizar destinatários",
|
||||
"linkGenerateSuccess": "Link de compartilhamento gerado com sucesso",
|
||||
"linkGenerateError": "Falha ao gerar link de compartilhamento",
|
||||
"notifyLoading": "Enviando notificações...",
|
||||
"notifySuccess": "Destinatários notificados com sucesso",
|
||||
"notifyError": "Falha ao notificar destinatários"
|
||||
},
|
||||
"quickAccess": {
|
||||
"files": {
|
||||
"title": "Meus Arquivos",
|
||||
"description": "Acesse e gerencie seus arquivos enviados"
|
||||
},
|
||||
"shares": {
|
||||
"title": "Meus Compartilhamentos",
|
||||
"description": "Visualize e gerencie seus arquivos compartilhados"
|
||||
}
|
||||
},
|
||||
"recentFiles": {
|
||||
"title": "Uploads Recentes",
|
||||
"viewAll": "Ver Todos",
|
||||
"uploadFile": "Enviar Arquivo",
|
||||
"noFiles": "Nenhum arquivo enviado ainda"
|
||||
},
|
||||
"recentShares": {
|
||||
"title": "Compartilhamentos Recentes",
|
||||
"viewAll": "Ver Todos",
|
||||
"createShare": "Criar Compartilhamento",
|
||||
"noShares": "Nenhum compartilhamento criado ainda",
|
||||
"createFirst": "Criar seu primeiro compartilhamento"
|
||||
},
|
||||
"storageUsage": {
|
||||
"title": "Uso de Armazenamento",
|
||||
"ariaLabel": "Barra de progresso do uso de armazenamento",
|
||||
"used": "{{size}} usado",
|
||||
"available": "{{size}} disponível"
|
||||
},
|
||||
"dashboard": {
|
||||
"loadError": "Falha ao carregar dados do painel",
|
||||
"linkCopied": "Link copiado para a área de transferência",
|
||||
"pageTitle": "Painel",
|
||||
"breadcrumb": "Painel"
|
||||
},
|
||||
"emptyState": {
|
||||
"noFiles": "Nenhum arquivo enviado ainda",
|
||||
"uploadFile": "Enviar Arquivo"
|
||||
},
|
||||
"files": {
|
||||
"title": "Todos os Arquivos",
|
||||
"uploadFile": "Enviar Arquivo",
|
||||
"loadError": "Falha ao carregar arquivos",
|
||||
"pageTitle": "Meus Arquivos",
|
||||
"breadcrumb": "Meus Arquivos"
|
||||
},
|
||||
"searchBar": {
|
||||
"placeholder": "Buscar arquivos...",
|
||||
"results": "Encontrados {{filtered}} de {{total}} arquivos"
|
||||
},
|
||||
"forgotPassword": {
|
||||
"emailLabel": "Endereço de Email",
|
||||
"emailPlaceholder": "Digite seu email",
|
||||
"sending": "Enviando...",
|
||||
"submit": "Enviar Instruções de Redefinição",
|
||||
"backToLogin": "Voltar ao Login",
|
||||
"title": "Esqueceu a Senha",
|
||||
"description": "Digite seu endereço de email e enviaremos instruções para redefinir sua senha.",
|
||||
"resetInstructions": "Instruções de redefinição enviadas para seu email",
|
||||
"pageTitle": "Esqueceu a Senha"
|
||||
},
|
||||
"home": {
|
||||
"description": "A alternativa open-source ao WeTransfer. Compartilhe arquivos com segurança, sem rastreamento ou limitações.",
|
||||
"documentation": "Documentação",
|
||||
"starOnGithub": "Estrela no GitHub",
|
||||
"privacyMessage": "Construído com privacidade em mente. Seus arquivos antes do upload são acessíveis apenas por aqueles com o link de compartilhamento. Para sempre gratuito e open source.",
|
||||
"header": {
|
||||
"fileSharing": "Compartilhamento de arquivos",
|
||||
"tagline": "simples e gratuito"
|
||||
},
|
||||
"pageTitle": "Início"
|
||||
},
|
||||
"profile": {
|
||||
"password": {
|
||||
"title": "Alterar Senha",
|
||||
"newPassword": "Nova Senha",
|
||||
"confirmPassword": "Confirmar Nova Senha",
|
||||
"updateButton": "Atualizar Senha"
|
||||
},
|
||||
"form": {
|
||||
"title": "Informações do Perfil",
|
||||
"firstName": "Nome",
|
||||
"lastName": "Sobrenome",
|
||||
"username": "Nome de Usuário",
|
||||
"email": "Email",
|
||||
"updateButton": "Atualizar Perfil"
|
||||
},
|
||||
"header": {
|
||||
"title": "Perfil",
|
||||
"subtitle": "Gerencie suas informações pessoais e senha"
|
||||
},
|
||||
"picture": {
|
||||
"title": "Foto do Perfil",
|
||||
"description": "Clique no ícone da câmera para alterar sua foto de perfil",
|
||||
"uploadPhoto": "Enviar Foto",
|
||||
"removePhoto": "Remover Foto"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "Falha ao carregar dados do usuário",
|
||||
"updateFailed": "Falha ao atualizar perfil",
|
||||
"passwordFailed": "Falha ao atualizar senha",
|
||||
"imageFailed": "Falha ao atualizar imagem",
|
||||
"imageRemoveFailed": "Falha ao remover imagem"
|
||||
},
|
||||
"messages": {
|
||||
"noChanges": "Nenhuma alteração para salvar",
|
||||
"updateSuccess": "Perfil atualizado com sucesso",
|
||||
"fillPasswords": "Por favor, preencha ambos os campos de senha",
|
||||
"passwordSuccess": "Senha atualizada com sucesso",
|
||||
"imageSuccess": "Imagem de perfil atualizada com sucesso",
|
||||
"imageRemoved": "Imagem de perfil removida com sucesso"
|
||||
},
|
||||
"pageTitle": "Perfil"
|
||||
},
|
||||
"resetPassword": {
|
||||
"pageTitle": "Redefinir Senha",
|
||||
"header": {
|
||||
"title": "Redefinir Senha",
|
||||
"description": "Digite sua nova senha abaixo"
|
||||
},
|
||||
"form": {
|
||||
"newPassword": "Nova Senha",
|
||||
"newPasswordPlaceholder": "Digite sua nova senha",
|
||||
"confirmPassword": "Confirmar Nova Senha",
|
||||
"confirmPasswordPlaceholder": "Confirme sua nova senha",
|
||||
"resetting": "Redefinindo Senha...",
|
||||
"submit": "Redefinir Senha",
|
||||
"backToLogin": "Voltar ao Login"
|
||||
},
|
||||
"messages": {
|
||||
"success": "Senha redefinida com sucesso"
|
||||
},
|
||||
"errors": {
|
||||
"serverError": "Falha ao redefinir senha. Tente novamente.",
|
||||
"invalidToken": "Token de redefinição inválido ou ausente"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"groups": {
|
||||
"defaultDescription": "Opções de configuração",
|
||||
"general": {
|
||||
"title": "Geral",
|
||||
"description": "Configurações básicas da aplicação"
|
||||
},
|
||||
"email": {
|
||||
"title": "Email",
|
||||
"description": "Configuração do servidor de email"
|
||||
},
|
||||
"security": {
|
||||
"title": "Segurança",
|
||||
"description": "Configurações de segurança e autenticação"
|
||||
},
|
||||
"storage": {
|
||||
"title": "Armazenamento",
|
||||
"description": "Configuração de armazenamento de arquivos"
|
||||
}
|
||||
},
|
||||
"fields": {
|
||||
"noDescription": "Sem descrição disponível",
|
||||
"appLogo": {
|
||||
"title": "Logo do Aplicativo",
|
||||
"description": "Imagem do logo do aplicativo"
|
||||
},
|
||||
"appName": {
|
||||
"title": "Nome do Aplicativo",
|
||||
"description": "Nome do aplicativo exibido para os usuários"
|
||||
},
|
||||
"appDescription": {
|
||||
"title": "Descrição do Aplicativo",
|
||||
"description": "Descrição breve do aplicativo"
|
||||
},
|
||||
"showHomePage": {
|
||||
"title": "Exibir Página Inicial",
|
||||
"description": "Exibe a página inicial após a instalação"
|
||||
},
|
||||
"smtpEnabled": {
|
||||
"title": "SMTP Habilitado",
|
||||
"description": "Ativa ou desativa a funcionalidade de e-mail via SMTP"
|
||||
},
|
||||
"smtpHost": {
|
||||
"title": "Servidor SMTP",
|
||||
"description": "Endereço do servidor SMTP"
|
||||
},
|
||||
"smtpPort": {
|
||||
"title": "Porta SMTP",
|
||||
"description": "Porta do servidor SMTP"
|
||||
},
|
||||
"smtpUser": {
|
||||
"title": "Usuário SMTP",
|
||||
"description": "Nome de usuário para autenticação SMTP"
|
||||
},
|
||||
"smtpPass": {
|
||||
"title": "Senha SMTP",
|
||||
"description": "Senha para autenticação SMTP"
|
||||
},
|
||||
"smtpFromName": {
|
||||
"title": "Nome do Remetente",
|
||||
"description": "Nome exibido para os e-mails enviados"
|
||||
},
|
||||
"smtpFromEmail": {
|
||||
"title": "E-mail do Remetente",
|
||||
"description": "Endereço de e-mail do remetente"
|
||||
},
|
||||
"maxLoginAttempts": {
|
||||
"title": "Número Máximo de Tentativas de Login",
|
||||
"description": "Número máximo de tentativas de login antes de bloquear"
|
||||
},
|
||||
"loginBlockDuration": {
|
||||
"title": "Duração do Bloqueio",
|
||||
"description": "Duração (em segundos) do bloqueio após exceder o número de tentativas"
|
||||
},
|
||||
"passwordMinLength": {
|
||||
"title": "Comprimento Mínimo da Senha",
|
||||
"description": "Número mínimo de caracteres para senhas"
|
||||
},
|
||||
"passwordResetTokenExpiration": {
|
||||
"title": "Expiração do Token de Redefinição",
|
||||
"description": "Tempo de validade (em segundos) para o token de redefinição de senha"
|
||||
},
|
||||
"maxFileSize": {
|
||||
"title": "Tamanho Máximo do Arquivo",
|
||||
"description": "Tamanho máximo permitido para uploads (em bytes)"
|
||||
},
|
||||
"maxTotalStoragePerUser": {
|
||||
"title": "Armazenamento Máximo por Usuário",
|
||||
"description": "Limite total de armazenamento por usuário (em bytes)"
|
||||
}
|
||||
},
|
||||
"buttons": {
|
||||
"save": "Salvar {{group}}"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "Falha ao carregar configurações",
|
||||
"updateFailed": "Falha ao atualizar configurações"
|
||||
},
|
||||
"messages": {
|
||||
"noChanges": "Nenhuma alteração para salvar",
|
||||
"updateSuccess": "Configurações de {{group}} atualizadas com sucesso"
|
||||
},
|
||||
"title": "Configurações",
|
||||
"breadcrumb": "Configurações",
|
||||
"pageTitle": "Configurações"
|
||||
},
|
||||
"share": {
|
||||
"errors": {
|
||||
"invalidPassword": "Senha inválida. Por favor, tente novamente.",
|
||||
"loadFailed": "Falha ao carregar compartilhamento",
|
||||
"downloadFailed": "Falha ao baixar arquivo"
|
||||
},
|
||||
"messages": {
|
||||
"downloadStarted": "Download iniciado",
|
||||
"password": {
|
||||
"title": "Compartilhamento Protegido por Senha",
|
||||
"protected": "Este compartilhamento está protegido por senha",
|
||||
"incorrect": "Senha incorreta. Por favor, tente novamente.",
|
||||
"label": "Senha",
|
||||
"placeholder": "Digite a senha do compartilhamento",
|
||||
"submit": "Enviar"
|
||||
},
|
||||
"details": {
|
||||
"untitled": "Compartilhamento sem título",
|
||||
"created": "Criado em: {{date}}",
|
||||
"expires": "Expira em: {{date}}"
|
||||
},
|
||||
"notFound": {
|
||||
"title": "Compartilhamento não Encontrado",
|
||||
"description": "Este compartilhamento pode ter sido excluído ou expirado."
|
||||
}
|
||||
},
|
||||
"pageTitle": "Compartilhamento"
|
||||
},
|
||||
"shares": {
|
||||
"errors": {
|
||||
"loadFailed": "Falha ao carregar compartilhamentos",
|
||||
"notifyFailed": "Falha ao notificar destinatários",
|
||||
"smtpConfigFailed": "Falha ao carregar configuração SMTP"
|
||||
},
|
||||
"messages": {
|
||||
"linkCopied": "Link copiado para a área de transferência",
|
||||
"recipientsNotified": "Destinatários notificados com sucesso"
|
||||
},
|
||||
"empty": {
|
||||
"message": "Nenhum compartilhamento criado ainda",
|
||||
"createButton": "Criar Compartilhamento"
|
||||
},
|
||||
"header": {
|
||||
"title": "Meus Compartilhamentos",
|
||||
"myShares": "Meus Compartilhamentos"
|
||||
},
|
||||
"search": {
|
||||
"title": "Todos os Compartilhamentos",
|
||||
"createButton": "Criar Compartilhamento",
|
||||
"placeholder": "Buscar compartilhamentos...",
|
||||
"results": "Encontrados {{filtered}} de {{total}} compartilhamentos"
|
||||
},
|
||||
"pageTitle": "Compartilhamentos"
|
||||
},
|
||||
"users": {
|
||||
"modes": {
|
||||
"create": "criar",
|
||||
"edit": "editar"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "Falha ao carregar usuários",
|
||||
"submitFailed": "Falha ao {{mode}} usuário",
|
||||
"deleteFailed": "Falha ao excluir usuário",
|
||||
"statusUpdateFailed": "Falha ao atualizar status do usuário"
|
||||
},
|
||||
"messages": {
|
||||
"createSuccess": "Usuário criado com sucesso",
|
||||
"updateSuccess": "Usuário atualizado com sucesso",
|
||||
"deleteSuccess": "Usuário excluído com sucesso",
|
||||
"activateSuccess": "Usuário ativado com sucesso",
|
||||
"deactivateSuccess": "Usuário desativado com sucesso"
|
||||
},
|
||||
"actions": {
|
||||
"edit": "Editar",
|
||||
"activate": "Ativar",
|
||||
"deactivate": "Desativar",
|
||||
"delete": "Excluir"
|
||||
},
|
||||
"delete": {
|
||||
"title": "Confirmar Exclusão de Usuário",
|
||||
"confirmation": "Tem certeza que deseja excluir o usuário {{firstName}} {{lastName}}? Esta ação não pode ser desfeita.",
|
||||
"confirm": "Excluir Usuário"
|
||||
},
|
||||
"form": {
|
||||
"titleCreate": "Adicionar Novo Usuário",
|
||||
"titleEdit": "Editar Usuário",
|
||||
"firstName": "Nome",
|
||||
"lastName": "Sobrenome",
|
||||
"username": "Nome de Usuário",
|
||||
"email": "Email",
|
||||
"password": "Senha",
|
||||
"newPassword": "Nova Senha (opcional)",
|
||||
"passwordPlaceholder": "Deixe em branco para manter a senha atual",
|
||||
"role": "Função",
|
||||
"roleUser": "Usuário",
|
||||
"roleAdmin": "Administrador",
|
||||
"create": "Criar",
|
||||
"save": "Salvar"
|
||||
},
|
||||
"status": {
|
||||
"title": "Confirmar Alteração de Status",
|
||||
"confirmation": "Tem certeza que deseja {{action}} o usuário {{firstName}} {{lastName}}?",
|
||||
"activate": "ativar",
|
||||
"deactivate": "desativar",
|
||||
"user": "Usuário"
|
||||
},
|
||||
"header": {
|
||||
"title": "Gerenciamento de Usuários",
|
||||
"addUser": "Adicionar Usuário",
|
||||
"management": "Gerenciamento de Usuários"
|
||||
},
|
||||
"table": {
|
||||
"user": "USUÁRIO",
|
||||
"email": "EMAIL",
|
||||
"status": "STATUS",
|
||||
"role": "FUNÇÃO",
|
||||
"actions": "AÇÕES",
|
||||
"active": "Ativo",
|
||||
"inactive": "Inativo",
|
||||
"admin": "Admin",
|
||||
"userr": "Usuário"
|
||||
}
|
||||
},
|
||||
"logo": {
|
||||
"labels": {
|
||||
"appLogo": "Logo do Aplicativo"
|
||||
},
|
||||
"buttons": {
|
||||
"upload": "Enviar Logo",
|
||||
"remove": "Remover Logo"
|
||||
},
|
||||
"messages": {
|
||||
"uploadSuccess": "Logo enviado com sucesso",
|
||||
"removeSuccess": "Logo removido com sucesso"
|
||||
},
|
||||
"errors": {
|
||||
"uploadFailed": "Falha ao enviar logo",
|
||||
"removeFailed": "Falha ao remover logo"
|
||||
}
|
||||
},
|
||||
"navbar": {
|
||||
"logoAlt": "Logo do Aplicativo",
|
||||
"profileMenu": "Menu do Perfil",
|
||||
"profile": "Perfil",
|
||||
"settings": "Configurações",
|
||||
"usersManagement": "Gerenciar Usuários",
|
||||
"logout": "Sair"
|
||||
}
|
||||
}
|
638
apps/app/messages/ru-RU.json
Normal file
638
apps/app/messages/ru-RU.json
Normal file
@@ -0,0 +1,638 @@
|
||||
{
|
||||
"login": {
|
||||
"welcome": "Добро пожаловать в",
|
||||
"signInToContinue": "Войдите, чтобы продолжить",
|
||||
"emailLabel": "Адрес электронной почты",
|
||||
"emailPlaceholder": "Введите вашу электронную почту",
|
||||
"passwordLabel": "Пароль",
|
||||
"passwordPlaceholder": "Введите ваш пароль",
|
||||
"signIn": "Войти",
|
||||
"signingIn": "Вход...",
|
||||
"forgotPassword": "Забыли пароль?",
|
||||
"pageTitle": "Вход"
|
||||
},
|
||||
"errors": {
|
||||
"invalidCredentials": "Неверный адрес электронной почты или пароль",
|
||||
"userNotFound": "Пользователь не найден",
|
||||
"accountLocked": "Аккаунт заблокирован. Пожалуйста, попробуйте позже",
|
||||
"unexpectedError": "Произошла непредвиденная ошибка. Пожалуйста, попробуйте еще раз"
|
||||
},
|
||||
"validation": {
|
||||
"invalidEmail": "Неверный адрес электронной почты",
|
||||
"passwordMinLength": "Пароль должен содержать не менее 6 символов",
|
||||
"firstNameRequired": "Имя обязательно",
|
||||
"lastNameRequired": "Фамилия обязательна",
|
||||
"usernameLength": "Имя пользователя должно содержать не менее 3 символов",
|
||||
"usernameSpaces": "Имя пользователя не может содержать пробелов",
|
||||
"passwordLength": "Пароль должен содержать не менее 8 символов",
|
||||
"passwordsMatch": "Пароли не совпадают",
|
||||
"emailRequired": "Требуется электронная почта",
|
||||
"passwordRequired": "Требуется пароль"
|
||||
},
|
||||
"fileSelector": {
|
||||
"availableFiles": "Доступные файлы ({{count}})",
|
||||
"shareFiles": "Поделиться файлами ({{count}})",
|
||||
"searchPlaceholder": "Поиск файлов...",
|
||||
"noMatchingFiles": "Нет файлов, соответствующих запросу",
|
||||
"noAvailableFiles": "Нет доступных файлов",
|
||||
"noFilesInShare": "Нет файлов для совместного использования",
|
||||
"saveChanges": "Сохранить изменения"
|
||||
},
|
||||
"recipientSelector": {
|
||||
"emailPlaceholder": "Введите электронную почту получателя",
|
||||
"add": "Добавить",
|
||||
"recipients": "Получатели ({{count}})",
|
||||
"notifyAll": "Уведомить всех",
|
||||
"noRecipients": "Пока нет добавленных получателей",
|
||||
"addSuccess": "Получатель успешно добавлен",
|
||||
"addError": "Не удалось добавить получателя",
|
||||
"removeSuccess": "Получатель успешно удалён",
|
||||
"removeError": "Не удалось удалить получателя",
|
||||
"sendingNotifications": "Отправка уведомлений...",
|
||||
"notifySuccess": "Получатели успешно уведомлены",
|
||||
"notifyError": "Не удалось уведомить получателей"
|
||||
},
|
||||
"navigation": {
|
||||
"dashboard": "Панель управления"
|
||||
},
|
||||
"common": {
|
||||
"loading": "Загрузка, пожалуйста, подождите...",
|
||||
"cancel": "Отмена",
|
||||
"save": "Сохранить",
|
||||
"delete": "Удалить",
|
||||
"close": "Закрыть",
|
||||
"download": "Скачать",
|
||||
"unexpectedError": "Произошла непредвиденная ошибка. Пожалуйста, попробуйте еще раз.",
|
||||
"yes": "Да",
|
||||
"no": "Нет",
|
||||
"dashboard": "Панель управления"
|
||||
},
|
||||
"createShare": {
|
||||
"title": "Создать общий доступ",
|
||||
"nameLabel": "Название общего доступа",
|
||||
"expirationLabel": "Дата истечения",
|
||||
"expirationPlaceholder": "MM/DD/YYYY ЧЧ:ММ",
|
||||
"maxViewsLabel": "Максимальное количество просмотров",
|
||||
"maxViewsPlaceholder": "Оставьте пустым для неограниченного доступа",
|
||||
"passwordProtection": "Защита паролем",
|
||||
"passwordLabel": "Пароль",
|
||||
"create": "Создать общий доступ",
|
||||
"success": "Общий доступ успешно создан",
|
||||
"error": "Не удалось создать общий доступ"
|
||||
},
|
||||
"fileActions": {
|
||||
"editFile": "Редактировать файл",
|
||||
"nameLabel": "Имя",
|
||||
"namePlaceholder": "Введите новое имя",
|
||||
"extension": "Расширение",
|
||||
"descriptionLabel": "Описание",
|
||||
"descriptionPlaceholder": "Введите описание файла",
|
||||
"deleteFile": "Удалить файл",
|
||||
"deleteConfirmation": "Вы уверены, что хотите удалить \"{{fileName}}\"?",
|
||||
"deleteWarning": "Это действие необратимо."
|
||||
},
|
||||
"filePreview": {
|
||||
"loading": "Загрузка предпросмотра...",
|
||||
"notAvailable": "Предпросмотр недоступен",
|
||||
"downloadToView": "Скачайте файл для просмотра содержимого",
|
||||
"audioNotSupported": "Ваш браузер не поддерживает аудиоэлемент",
|
||||
"videoNotSupported": "Ваш браузер не поддерживает видеоэлемент",
|
||||
"loadError": "Ошибка загрузки предпросмотра",
|
||||
"downloadError": "Ошибка скачивания файла"
|
||||
},
|
||||
"generateShareLink": {
|
||||
"generateTitle": "Создать ссылку для общего доступа",
|
||||
"updateTitle": "Обновить ссылку для общего доступа",
|
||||
"generateDescription": "Создайте ссылку для обмена файлами",
|
||||
"updateDescription": "Обновите псевдоним для этой ссылки",
|
||||
"aliasPlaceholder": "Введите псевдоним",
|
||||
"linkReady": "Ваша ссылка готова:",
|
||||
"generateButton": "Создать ссылку",
|
||||
"updateButton": "Обновить ссылку",
|
||||
"copyButton": "Скопировать ссылку",
|
||||
"success": "Ссылка успешно создана",
|
||||
"error": "Не удалось создать ссылку",
|
||||
"copied": "Ссылка скопирована в буфер обмена"
|
||||
},
|
||||
"shareActions": {
|
||||
"deleteTitle": "Удалить общий доступ",
|
||||
"deleteConfirmation": "Вы уверены, что хотите удалить этот общий доступ? Это действие необратимо.",
|
||||
"editTitle": "Редактировать общий доступ",
|
||||
"nameLabel": "Название общего доступа",
|
||||
"expirationLabel": "Дата истечения",
|
||||
"expirationPlaceholder": "MM/DD/YYYY ЧЧ:ММ",
|
||||
"maxViewsLabel": "Максимальное количество просмотров",
|
||||
"maxViewsPlaceholder": "Оставьте пустым для неограниченного доступа",
|
||||
"passwordProtection": "Защищено паролем",
|
||||
"passwordLabel": "Пароль",
|
||||
"passwordPlaceholder": "Введите пароль",
|
||||
"newPasswordLabel": "Новый пароль (оставьте пустым, чтобы сохранить текущий)",
|
||||
"newPasswordPlaceholder": "Введите новый пароль",
|
||||
"manageFilesTitle": "Управление файлами",
|
||||
"manageRecipientsTitle": "Управление получателями",
|
||||
"editSuccess": "Общий доступ успешно обновлён",
|
||||
"editError": "Ошибка при обновлении общего доступа"
|
||||
},
|
||||
"shareDetails": {
|
||||
"title": "Детали общего доступа",
|
||||
"subtitle": "Подробная информация об этом общем доступе",
|
||||
"basicInfo": "Основная информация",
|
||||
"name": "Название",
|
||||
"untitled": "Без названия",
|
||||
"views": "Просмотры",
|
||||
"dates": "Даты",
|
||||
"created": "Создано",
|
||||
"expires": "Истекает",
|
||||
"never": "Никогда",
|
||||
"security": "Безопасность",
|
||||
"passwordProtected": "Защищено паролем",
|
||||
"publicAccess": "Публичный доступ",
|
||||
"maxViews": "Максимум просмотров: {{count}}",
|
||||
"files": "Файлы ({{count}})",
|
||||
"recipients": "Получатели ({{count}})",
|
||||
"notAvailable": "Н/Д",
|
||||
"invalidDate": "Неверная дата",
|
||||
"loadError": "Ошибка загрузки деталей общего доступа"
|
||||
},
|
||||
"uploadFile": {
|
||||
"title": "Загрузить файл",
|
||||
"selectFile": "Нажмите, чтобы выбрать файл",
|
||||
"preview": "Предпросмотр",
|
||||
"uploadProgress": "Прогресс загрузки",
|
||||
"upload": "Загрузить",
|
||||
"success": "Файл успешно загружен",
|
||||
"error": "Не удалось загрузить файл"
|
||||
},
|
||||
"filesTable": {
|
||||
"ariaLabel": "Таблица файлов",
|
||||
"columns": {
|
||||
"name": "ИМЯ",
|
||||
"description": "ОПИСАНИЕ",
|
||||
"size": "РАЗМЕР",
|
||||
"createdAt": "СОЗДАНО",
|
||||
"updatedAt": "ОБНОВЛЕНО",
|
||||
"actions": "ДЕЙСТВИЯ"
|
||||
},
|
||||
"actions": {
|
||||
"menu": "Меню действий с файлом",
|
||||
"preview": "Предпросмотр",
|
||||
"edit": "Редактировать",
|
||||
"download": "Скачать",
|
||||
"delete": "Удалить"
|
||||
}
|
||||
},
|
||||
"sharesTable": {
|
||||
"ariaLabel": "Таблица общего доступа",
|
||||
"never": "Никогда",
|
||||
"columns": {
|
||||
"name": "ИМЯ",
|
||||
"createdAt": "СОЗДАНО",
|
||||
"expiresAt": "ИСТЕКАЕТ",
|
||||
"status": "СТАТУС",
|
||||
"security": "БЕЗОПАСНОСТЬ",
|
||||
"files": "ФАЙЛЫ",
|
||||
"recipients": "ПОЛУЧАТЕЛИ",
|
||||
"actions": "ДЕЙСТВИЯ"
|
||||
},
|
||||
"status": {
|
||||
"neverExpires": "Не истекает",
|
||||
"active": "Активно",
|
||||
"expired": "Истекло"
|
||||
},
|
||||
"security": {
|
||||
"protected": "Защищено",
|
||||
"public": "Публично"
|
||||
},
|
||||
"filesCount": "{{count}} файлов",
|
||||
"recipientsCount": "{{count}} получателей",
|
||||
"actions": {
|
||||
"menu": "Меню действий общего доступа",
|
||||
"edit": "Редактировать",
|
||||
"manageFiles": "Управление файлами",
|
||||
"manageRecipients": "Управление получателями",
|
||||
"viewDetails": "Просмотреть детали",
|
||||
"generateLink": "Создать ссылку",
|
||||
"editLink": "Редактировать ссылку",
|
||||
"copyLink": "Скопировать ссылку",
|
||||
"notifyRecipients": "Уведомить получателей",
|
||||
"delete": "Удалить"
|
||||
}
|
||||
},
|
||||
"footer": {
|
||||
"poweredBy": "При поддержке",
|
||||
"kyanHomepage": "Домашняя страница Kyantech"
|
||||
},
|
||||
"fileManager": {
|
||||
"downloadError": "Ошибка скачивания файла",
|
||||
"updateSuccess": "Файл успешно обновлен",
|
||||
"updateError": "Ошибка при обновлении файла",
|
||||
"deleteSuccess": "Файл успешно удален",
|
||||
"deleteError": "Ошибка при удалении файла"
|
||||
},
|
||||
"shareManager": {
|
||||
"deleteSuccess": "Общий доступ успешно удален",
|
||||
"deleteError": "Ошибка при удалении общего доступа",
|
||||
"updateSuccess": "Общий доступ успешно обновлен",
|
||||
"updateError": "Ошибка при обновлении общего доступа",
|
||||
"filesUpdateSuccess": "Файлы успешно обновлены",
|
||||
"filesUpdateError": "Ошибка при обновлении файлов",
|
||||
"recipientsUpdateSuccess": "Получатели успешно обновлены",
|
||||
"recipientsUpdateError": "Ошибка при обновлении получателей",
|
||||
"linkGenerateSuccess": "Ссылка для общего доступа успешно создана",
|
||||
"linkGenerateError": "Ошибка при создании ссылки для общего доступа",
|
||||
"notifyLoading": "Отправка уведомлений...",
|
||||
"notifySuccess": "Получатели успешно уведомлены",
|
||||
"notifyError": "Ошибка при уведомлении получателей"
|
||||
},
|
||||
"quickAccess": {
|
||||
"files": {
|
||||
"title": "Мои файлы",
|
||||
"description": "Доступ и управление загруженными файлами"
|
||||
},
|
||||
"shares": {
|
||||
"title": "Мои общие доступы",
|
||||
"description": "Просмотр и управление файлами для совместного использования"
|
||||
}
|
||||
},
|
||||
"recentFiles": {
|
||||
"title": "Последние загрузки",
|
||||
"viewAll": "Показать все",
|
||||
"uploadFile": "Загрузить файл",
|
||||
"noFiles": "Файлы еще не загружены"
|
||||
},
|
||||
"recentShares": {
|
||||
"title": "Последние общие доступы",
|
||||
"viewAll": "Показать все",
|
||||
"createShare": "Создать общий доступ",
|
||||
"noShares": "Общие доступы еще не созданы",
|
||||
"createFirst": "Создайте ваш первый общий доступ"
|
||||
},
|
||||
"storageUsage": {
|
||||
"title": "Использование хранилища",
|
||||
"ariaLabel": "Индикатор использования хранилища",
|
||||
"used": "Использовано: {{size}}",
|
||||
"available": "Доступно: {{size}}"
|
||||
},
|
||||
"dashboard": {
|
||||
"loadError": "Ошибка загрузки данных панели управления",
|
||||
"linkCopied": "Ссылка скопирована в буфер обмена",
|
||||
"pageTitle": "Панель управления",
|
||||
"breadcrumb": "Панель управления"
|
||||
},
|
||||
"emptyState": {
|
||||
"noFiles": "Файлы еще не загружены",
|
||||
"uploadFile": "Загрузить файл"
|
||||
},
|
||||
"files": {
|
||||
"title": "Все файлы",
|
||||
"uploadFile": "Загрузить файл",
|
||||
"loadError": "Ошибка загрузки файлов",
|
||||
"pageTitle": "Мои файлы",
|
||||
"breadcrumb": "Мои файлы"
|
||||
},
|
||||
"searchBar": {
|
||||
"placeholder": "Поиск файлов...",
|
||||
"results": "Найдено {{filtered}} из {{total}} файлов"
|
||||
},
|
||||
"forgotPassword": {
|
||||
"emailLabel": "Адрес электронной почты",
|
||||
"emailPlaceholder": "Введите ваш адрес электронной почты",
|
||||
"sending": "Отправка...",
|
||||
"submit": "Отправить инструкции по сбросу",
|
||||
"backToLogin": "Вернуться ко входу",
|
||||
"title": "Забыли пароль",
|
||||
"description": "Введите адрес электронной почты, и мы отправим вам инструкции по сбросу пароля.",
|
||||
"resetInstructions": "Инструкции по сбросу отправлены на вашу электронную почту",
|
||||
"pageTitle": "Забыли пароль"
|
||||
},
|
||||
"home": {
|
||||
"description": "Открытая альтернатива WeTransfer. Делитесь файлами безопасно, без отслеживания и ограничений.",
|
||||
"documentation": "Документация",
|
||||
"starOnGithub": "Оцените на GitHub",
|
||||
"privacyMessage": "Создано с учетом конфиденциальности. Ваши файлы до загрузки доступны только тем, у кого есть ссылка для доступа. Всегда бесплатно и с открытым исходным кодом.",
|
||||
"header": {
|
||||
"fileSharing": "Обмен файлами",
|
||||
"tagline": "просто и бесплатно"
|
||||
},
|
||||
"pageTitle": "Главная"
|
||||
},
|
||||
"profile": {
|
||||
"password": {
|
||||
"title": "Изменить пароль",
|
||||
"newPassword": "Новый пароль",
|
||||
"confirmPassword": "Подтвердите новый пароль",
|
||||
"updateButton": "Обновить пароль"
|
||||
},
|
||||
"form": {
|
||||
"title": "Информация профиля",
|
||||
"firstName": "Имя",
|
||||
"lastName": "Фамилия",
|
||||
"username": "Имя пользователя",
|
||||
"email": "Электронная почта",
|
||||
"updateButton": "Обновить профиль"
|
||||
},
|
||||
"header": {
|
||||
"title": "Профиль",
|
||||
"subtitle": "Управляйте вашей личной информацией и паролем"
|
||||
},
|
||||
"picture": {
|
||||
"title": "Изображение профиля",
|
||||
"description": "Нажмите на значок камеры, чтобы изменить изображение профиля",
|
||||
"uploadPhoto": "Загрузить фото",
|
||||
"removePhoto": "Удалить фото"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "Не удалось загрузить данные пользователя",
|
||||
"updateFailed": "Ошибка при обновлении профиля",
|
||||
"passwordFailed": "Ошибка при обновлении пароля",
|
||||
"imageFailed": "Ошибка при обновлении изображения профиля",
|
||||
"imageRemoveFailed": "Ошибка при удалении изображения профиля"
|
||||
},
|
||||
"messages": {
|
||||
"noChanges": "Изменений для сохранения нет",
|
||||
"updateSuccess": "Профиль успешно обновлен",
|
||||
"fillPasswords": "Пожалуйста, заполните оба поля пароля",
|
||||
"passwordSuccess": "Пароль успешно обновлен",
|
||||
"imageSuccess": "Изображение профиля успешно обновлено",
|
||||
"imageRemoved": "Изображение профиля успешно удалено"
|
||||
},
|
||||
"pageTitle": "Профиль"
|
||||
},
|
||||
"resetPassword": {
|
||||
"pageTitle": "Сбросить пароль",
|
||||
"header": {
|
||||
"title": "Сбросить пароль",
|
||||
"description": "Введите ваш новый пароль ниже"
|
||||
},
|
||||
"form": {
|
||||
"newPassword": "Новый пароль",
|
||||
"newPasswordPlaceholder": "Введите новый пароль",
|
||||
"confirmPassword": "Подтвердите новый пароль",
|
||||
"confirmPasswordPlaceholder": "Подтвердите новый пароль",
|
||||
"resetting": "Сброс пароля...",
|
||||
"submit": "Сбросить пароль",
|
||||
"backToLogin": "Вернуться ко входу"
|
||||
},
|
||||
"messages": {
|
||||
"success": "Пароль успешно сброшен"
|
||||
},
|
||||
"errors": {
|
||||
"serverError": "Не удалось сбросить пароль. Пожалуйста, попробуйте еще раз.",
|
||||
"invalidToken": "Неверный или отсутствующий токен сброса"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"groups": {
|
||||
"defaultDescription": "Настройки конфигурации",
|
||||
"general": {
|
||||
"title": "Общие",
|
||||
"description": "Основные настройки приложения"
|
||||
},
|
||||
"email": {
|
||||
"title": "Электронная почта",
|
||||
"description": "Настройки почтового сервера"
|
||||
},
|
||||
"security": {
|
||||
"title": "Безопасность",
|
||||
"description": "Настройки безопасности и аутентификации"
|
||||
},
|
||||
"storage": {
|
||||
"title": "Хранилище",
|
||||
"description": "Настройки хранения файлов"
|
||||
}
|
||||
},
|
||||
"fields": {
|
||||
"noDescription": "Описание отсутствует",
|
||||
"appLogo": {
|
||||
"title": "Логотип приложения",
|
||||
"description": "Изображение логотипа приложения"
|
||||
},
|
||||
"appName": {
|
||||
"title": "Название приложения",
|
||||
"description": "Название приложения, отображаемое пользователям"
|
||||
},
|
||||
"appDescription": {
|
||||
"title": "Описание приложения",
|
||||
"description": "Краткое описание приложения"
|
||||
},
|
||||
"showHomePage": {
|
||||
"title": "Показывать главную страницу",
|
||||
"description": "Показывать главную страницу после установки"
|
||||
},
|
||||
"smtpEnabled": {
|
||||
"title": "Включить SMTP",
|
||||
"description": "Включить или отключить функцию SMTP для отправки электронной почты"
|
||||
},
|
||||
"smtpHost": {
|
||||
"title": "SMTP-сервер",
|
||||
"description": "Адрес SMTP-сервера"
|
||||
},
|
||||
"smtpPort": {
|
||||
"title": "SMTP-порт",
|
||||
"description": "Порт SMTP-сервера"
|
||||
},
|
||||
"smtpUser": {
|
||||
"title": "SMTP-пользователь",
|
||||
"description": "Имя пользователя для SMTP-аутентификации"
|
||||
},
|
||||
"smtpPass": {
|
||||
"title": "SMTP-пароль",
|
||||
"description": "Пароль для SMTP-аутентификации"
|
||||
},
|
||||
"smtpFromName": {
|
||||
"title": "Имя отправителя",
|
||||
"description": "Имя, отображаемое в отправляемых письмах"
|
||||
},
|
||||
"smtpFromEmail": {
|
||||
"title": "Электронная почта отправителя",
|
||||
"description": "Адрес электронной почты отправителя"
|
||||
},
|
||||
"maxLoginAttempts": {
|
||||
"title": "Максимальное количество попыток входа",
|
||||
"description": "Максимальное количество попыток входа до блокировки"
|
||||
},
|
||||
"loginBlockDuration": {
|
||||
"title": "Время блокировки",
|
||||
"description": "Продолжительность блокировки (в секундах) после превышения лимита попыток"
|
||||
},
|
||||
"passwordMinLength": {
|
||||
"title": "Минимальная длина пароля",
|
||||
"description": "Минимальное количество символов в пароле"
|
||||
},
|
||||
"passwordResetTokenExpiration": {
|
||||
"title": "Время истечения токена сброса пароля",
|
||||
"description": "Время действия токена сброса пароля (в секундах)"
|
||||
},
|
||||
"maxFileSize": {
|
||||
"title": "Максимальный размер файла",
|
||||
"description": "Максимальный размер файла для загрузки (в байтах)"
|
||||
},
|
||||
"maxTotalStoragePerUser": {
|
||||
"title": "Максимальное хранилище для пользователя",
|
||||
"description": "Общий лимит хранилища для каждого пользователя (в байтах)"
|
||||
}
|
||||
},
|
||||
"buttons": {
|
||||
"save": "Сохранить {{group}}"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "Ошибка загрузки настроек",
|
||||
"updateFailed": "Ошибка обновления настроек"
|
||||
},
|
||||
"messages": {
|
||||
"noChanges": "Изменений для сохранения нет",
|
||||
"updateSuccess": "Настройки {{group}} успешно обновлены"
|
||||
},
|
||||
"title": "Настройки",
|
||||
"breadcrumb": "Настройки",
|
||||
"pageTitle": "Настройки"
|
||||
},
|
||||
"share": {
|
||||
"errors": {
|
||||
"invalidPassword": "Неверный пароль. Пожалуйста, попробуйте еще раз.",
|
||||
"loadFailed": "Ошибка загрузки общего доступа",
|
||||
"downloadFailed": "Ошибка скачивания файла"
|
||||
},
|
||||
"messages": {
|
||||
"downloadStarted": "Скачивание начато"
|
||||
},
|
||||
"password": {
|
||||
"title": "Общий доступ, защищенный паролем",
|
||||
"protected": "Этот общий доступ защищен паролем",
|
||||
"incorrect": "Неверный пароль. Пожалуйста, попробуйте снова.",
|
||||
"label": "Пароль",
|
||||
"placeholder": "Введите пароль для общего доступа",
|
||||
"submit": "Отправить"
|
||||
},
|
||||
"details": {
|
||||
"untitled": "Без названия",
|
||||
"created": "Создано: {{date}}",
|
||||
"expires": "Истекает: {{date}}"
|
||||
},
|
||||
"notFound": {
|
||||
"title": "Общий доступ не найден",
|
||||
"description": "Этот общий доступ может быть удален или истек."
|
||||
},
|
||||
"pageTitle": "Общий доступ"
|
||||
},
|
||||
"shares": {
|
||||
"errors": {
|
||||
"loadFailed": "Ошибка загрузки общих доступов",
|
||||
"notifyFailed": "Ошибка уведомления получателей",
|
||||
"smtpConfigFailed": "Ошибка загрузки SMTP-настроек"
|
||||
},
|
||||
"messages": {
|
||||
"linkCopied": "Ссылка скопирована в буфер обмена",
|
||||
"recipientsNotified": "Получатели успешно уведомлены"
|
||||
},
|
||||
"empty": {
|
||||
"message": "Общие доступы еще не созданы",
|
||||
"createButton": "Создать общий доступ"
|
||||
},
|
||||
"header": {
|
||||
"title": "Мои общие доступы",
|
||||
"myShares": "Мои общие доступы"
|
||||
},
|
||||
"search": {
|
||||
"title": "Все общие доступы",
|
||||
"createButton": "Создать общий доступ",
|
||||
"placeholder": "Поиск общих доступов...",
|
||||
"results": "Найдено {{filtered}} из {{total}} общих доступов"
|
||||
},
|
||||
"pageTitle": "Общие доступы"
|
||||
},
|
||||
"users": {
|
||||
"modes": {
|
||||
"create": "создать",
|
||||
"edit": "редактировать"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "Ошибка загрузки пользователей",
|
||||
"submitFailed": "Ошибка при {{mode}} пользователя",
|
||||
"deleteFailed": "Ошибка при удалении пользователя",
|
||||
"statusUpdateFailed": "Ошибка обновления статуса пользователя"
|
||||
},
|
||||
"messages": {
|
||||
"createSuccess": "Пользователь успешно создан",
|
||||
"updateSuccess": "Пользователь успешно обновлен",
|
||||
"deleteSuccess": "Пользователь успешно удален",
|
||||
"activateSuccess": "Пользователь успешно активирован",
|
||||
"deactivateSuccess": "Пользователь успешно деактивирован"
|
||||
},
|
||||
"actions": {
|
||||
"edit": "Редактировать",
|
||||
"activate": "Активировать",
|
||||
"deactivate": "Деактивировать",
|
||||
"delete": "Удалить"
|
||||
},
|
||||
"delete": {
|
||||
"title": "Подтверждение удаления пользователя",
|
||||
"confirmation": "Вы уверены, что хотите удалить пользователя {{firstName}} {{lastName}}? Это действие нельзя отменить.",
|
||||
"confirm": "Удалить пользователя"
|
||||
},
|
||||
"form": {
|
||||
"titleCreate": "Добавить нового пользователя",
|
||||
"titleEdit": "Редактировать пользователя",
|
||||
"firstName": "Имя",
|
||||
"lastName": "Фамилия",
|
||||
"username": "Имя пользователя",
|
||||
"email": "Электронная почта",
|
||||
"password": "Пароль",
|
||||
"newPassword": "Новый пароль (необязательно)",
|
||||
"passwordPlaceholder": "Оставьте пустым, чтобы сохранить текущий пароль",
|
||||
"role": "Роль",
|
||||
"roleUser": "Пользователь",
|
||||
"roleAdmin": "Администратор",
|
||||
"create": "Создать",
|
||||
"save": "Сохранить"
|
||||
},
|
||||
"status": {
|
||||
"title": "Подтверждение изменения статуса",
|
||||
"confirmation": "Вы уверены, что хотите {{action}} пользователя {{firstName}} {{lastName}}?",
|
||||
"activate": "активировать",
|
||||
"deactivate": "деактивировать",
|
||||
"user": "Пользователь"
|
||||
},
|
||||
"header": {
|
||||
"title": "Управление пользователями",
|
||||
"addUser": "Добавить пользователя",
|
||||
"management": "Управление пользователями"
|
||||
},
|
||||
"table": {
|
||||
"user": "ПОЛЬЗОВАТЕЛЬ",
|
||||
"email": "ЭЛЕКТРОННАЯ ПОЧТА",
|
||||
"status": "СТАТУС",
|
||||
"role": "РОЛЬ",
|
||||
"actions": "ДЕЙСТВИЯ",
|
||||
"active": "Активен",
|
||||
"inactive": "Неактивен",
|
||||
"admin": "Администратор",
|
||||
"userr": "Пользователь"
|
||||
}
|
||||
},
|
||||
"logo": {
|
||||
"labels": {
|
||||
"appLogo": "Логотип приложения"
|
||||
},
|
||||
"buttons": {
|
||||
"upload": "Загрузить логотип",
|
||||
"remove": "Удалить логотип"
|
||||
},
|
||||
"messages": {
|
||||
"uploadSuccess": "Логотип успешно загружен",
|
||||
"removeSuccess": "Логотип успешно удален"
|
||||
},
|
||||
"errors": {
|
||||
"uploadFailed": "Ошибка загрузки логотипа",
|
||||
"removeFailed": "Ошибка удаления логотипа"
|
||||
}
|
||||
},
|
||||
"navbar": {
|
||||
"logoAlt": "Логотип приложения",
|
||||
"profileMenu": "Меню профиля",
|
||||
"profile": "Профиль",
|
||||
"settings": "Настройки",
|
||||
"usersManagement": "Управление пользователями",
|
||||
"logout": "Выйти"
|
||||
}
|
||||
}
|
638
apps/app/messages/tr-TR.json
Normal file
638
apps/app/messages/tr-TR.json
Normal file
@@ -0,0 +1,638 @@
|
||||
{
|
||||
"login": {
|
||||
"welcome": "Hoş geldiniz'e",
|
||||
"signInToContinue": "Devam etmek için oturum açın",
|
||||
"emailLabel": "E-posta Adresi",
|
||||
"emailPlaceholder": "E-posta adresinizi girin",
|
||||
"passwordLabel": "Şifre",
|
||||
"passwordPlaceholder": "Şifrenizi girin",
|
||||
"signIn": "Oturum Aç",
|
||||
"signingIn": "Oturum açılıyor...",
|
||||
"forgotPassword": "Şifrenizi mi unuttunuz?",
|
||||
"pageTitle": "Giriş"
|
||||
},
|
||||
"errors": {
|
||||
"invalidCredentials": "Geçersiz e-posta veya şifre",
|
||||
"userNotFound": "Kullanıcı bulunamadı",
|
||||
"accountLocked": "Hesap kilitlendi. Lütfen daha sonra tekrar deneyin",
|
||||
"unexpectedError": "Beklenmeyen bir hata oluştu. Lütfen tekrar deneyin"
|
||||
},
|
||||
"validation": {
|
||||
"invalidEmail": "Geçersiz e-posta adresi",
|
||||
"passwordMinLength": "Şifre en az 6 karakter olmalıdır",
|
||||
"firstNameRequired": "Ad gerekli",
|
||||
"lastNameRequired": "Soyad gerekli",
|
||||
"usernameLength": "Kullanıcı adı en az 3 karakter olmalıdır",
|
||||
"usernameSpaces": "Kullanıcı adında boşluk olamaz",
|
||||
"passwordLength": "Şifre en az 8 karakter olmalıdır",
|
||||
"passwordsMatch": "Şifreler eşleşmiyor",
|
||||
"emailRequired": "E-posta gerekli",
|
||||
"passwordRequired": "Şifre gerekli"
|
||||
},
|
||||
"fileSelector": {
|
||||
"availableFiles": "Kullanılabilir Dosyalar ({{count}})",
|
||||
"shareFiles": "Dosyaları Paylaş ({{count}})",
|
||||
"searchPlaceholder": "Dosya ara...",
|
||||
"noMatchingFiles": "Eşleşen dosya bulunamadı",
|
||||
"noAvailableFiles": "Kullanılabilir dosya yok",
|
||||
"noFilesInShare": "Paylaşımda dosya yok",
|
||||
"saveChanges": "Değişiklikleri Kaydet"
|
||||
},
|
||||
"recipientSelector": {
|
||||
"emailPlaceholder": "Alıcının e-postasını girin",
|
||||
"add": "Ekle",
|
||||
"recipients": "Alıcılar ({{count}})",
|
||||
"notifyAll": "Hepsini Bildir",
|
||||
"noRecipients": "Henüz alıcı eklenmedi",
|
||||
"addSuccess": "Alıcı başarıyla eklendi",
|
||||
"addError": "Alıcı eklenemedi",
|
||||
"removeSuccess": "Alıcı başarıyla kaldırıldı",
|
||||
"removeError": "Alıcı kaldırılamadı",
|
||||
"sendingNotifications": "Bildirimler gönderiliyor...",
|
||||
"notifySuccess": "Alıcılar başarıyla bildirildi",
|
||||
"notifyError": "Alıcılara bildirim gönderilemedi"
|
||||
},
|
||||
"navigation": {
|
||||
"dashboard": "Gösterge Paneli"
|
||||
},
|
||||
"common": {
|
||||
"loading": "Yükleniyor, lütfen bekleyin...",
|
||||
"cancel": "İptal",
|
||||
"save": "Kaydet",
|
||||
"delete": "Sil",
|
||||
"close": "Kapat",
|
||||
"download": "İndir",
|
||||
"unexpectedError": "Beklenmeyen bir hata oluştu. Lütfen tekrar deneyin.",
|
||||
"yes": "Evet",
|
||||
"no": "Hayır",
|
||||
"dashboard": "Gösterge Paneli"
|
||||
},
|
||||
"createShare": {
|
||||
"title": "Paylaşım Oluştur",
|
||||
"nameLabel": "Paylaşım Adı",
|
||||
"expirationLabel": "Son Kullanma Tarihi",
|
||||
"expirationPlaceholder": "MM/GG/YYYY SS:DD",
|
||||
"maxViewsLabel": "Maksimum Görüntüleme",
|
||||
"maxViewsPlaceholder": "Sınırsız için boş bırakın",
|
||||
"passwordProtection": "Şifre Koruması",
|
||||
"passwordLabel": "Şifre",
|
||||
"create": "Paylaşım Oluştur",
|
||||
"success": "Paylaşım başarıyla oluşturuldu",
|
||||
"error": "Paylaşım oluşturulamadı"
|
||||
},
|
||||
"fileActions": {
|
||||
"editFile": "Dosyayı Düzenle",
|
||||
"nameLabel": "Ad",
|
||||
"namePlaceholder": "Yeni ad girin",
|
||||
"extension": "Uzantı",
|
||||
"descriptionLabel": "Açıklama",
|
||||
"descriptionPlaceholder": "Dosya açıklamasını girin",
|
||||
"deleteFile": "Dosyayı Sil",
|
||||
"deleteConfirmation": "\"{{fileName}}\" dosyasını silmek istediğinize emin misiniz?",
|
||||
"deleteWarning": "Bu işlem geri alınamaz."
|
||||
},
|
||||
"filePreview": {
|
||||
"loading": "Önizleme yükleniyor...",
|
||||
"notAvailable": "Önizleme mevcut değil",
|
||||
"downloadToView": "İçeriği görüntülemek için dosyayı indirin",
|
||||
"audioNotSupported": "Tarayıcınız ses öğesini desteklemiyor",
|
||||
"videoNotSupported": "Tarayıcınız video öğesini desteklemiyor",
|
||||
"loadError": "Önizleme yüklenemedi",
|
||||
"downloadError": "Dosya indirilemedi"
|
||||
},
|
||||
"generateShareLink": {
|
||||
"generateTitle": "Paylaşım Bağlantısı Oluştur",
|
||||
"updateTitle": "Paylaşım Bağlantısını Güncelle",
|
||||
"generateDescription": "Dosyalarınızı paylaşmak için bir bağlantı oluşturun",
|
||||
"updateDescription": "Bu paylaşım bağlantısı için takma ad güncelleyin",
|
||||
"aliasPlaceholder": "Takma ad girin",
|
||||
"linkReady": "Paylaşım bağlantınız hazır:",
|
||||
"generateButton": "Bağlantıyı Oluştur",
|
||||
"updateButton": "Bağlantıyı Güncelle",
|
||||
"copyButton": "Bağlantıyı Kopyala",
|
||||
"success": "Bağlantı başarıyla oluşturuldu",
|
||||
"error": "Bağlantı oluşturulamadı",
|
||||
"copied": "Bağlantı panoya kopyalandı"
|
||||
},
|
||||
"shareActions": {
|
||||
"deleteTitle": "Paylaşımı Sil",
|
||||
"deleteConfirmation": "Bu paylaşımı silmek istediğinize emin misiniz? Bu işlem geri alınamaz.",
|
||||
"editTitle": "Paylaşımı Düzenle",
|
||||
"nameLabel": "Paylaşım Adı",
|
||||
"expirationLabel": "Son Kullanma Tarihi",
|
||||
"expirationPlaceholder": "MM/GG/YYYY SS:DD",
|
||||
"maxViewsLabel": "Maksimum Görüntüleme",
|
||||
"maxViewsPlaceholder": "Sınırsız için boş bırakın",
|
||||
"passwordProtection": "Şifre Korumalı",
|
||||
"passwordLabel": "Şifre",
|
||||
"passwordPlaceholder": "Şifreyi girin",
|
||||
"newPasswordLabel": "Yeni Şifre (mevcut şifreyi korumak için boş bırakın)",
|
||||
"newPasswordPlaceholder": "Yeni şifreyi girin",
|
||||
"manageFilesTitle": "Dosyaları Yönet",
|
||||
"manageRecipientsTitle": "Alıcıları Yönet",
|
||||
"editSuccess": "Paylaşım başarıyla güncellendi",
|
||||
"editError": "Paylaşım güncellenemedi"
|
||||
},
|
||||
"shareDetails": {
|
||||
"title": "Paylaşım Detayları",
|
||||
"subtitle": "Bu paylaşım hakkında ayrıntılı bilgi",
|
||||
"basicInfo": "Temel Bilgiler",
|
||||
"name": "Ad",
|
||||
"untitled": "Adsız",
|
||||
"views": "Görüntüleme",
|
||||
"dates": "Tarihler",
|
||||
"created": "Oluşturuldu",
|
||||
"expires": "Sona Eriyor",
|
||||
"never": "Asla",
|
||||
"security": "Güvenlik",
|
||||
"passwordProtected": "Şifre ile Korunuyor",
|
||||
"publicAccess": "Genel Erişim",
|
||||
"maxViews": "Maksimum Görüntüleme: {{count}}",
|
||||
"files": "Dosyalar ({{count}})",
|
||||
"recipients": "Alıcılar ({{count}})",
|
||||
"notAvailable": "Mevcut Değil",
|
||||
"invalidDate": "Geçersiz tarih",
|
||||
"loadError": "Paylaşım detayları yüklenemedi"
|
||||
},
|
||||
"uploadFile": {
|
||||
"title": "Dosya Yükle",
|
||||
"selectFile": "Dosya seçmek için tıklayın",
|
||||
"preview": "Önizleme",
|
||||
"uploadProgress": "Yükleme İlerlemesi",
|
||||
"upload": "Yükle",
|
||||
"success": "Dosya başarıyla yüklendi",
|
||||
"error": "Dosya yüklenemedi"
|
||||
},
|
||||
"filesTable": {
|
||||
"ariaLabel": "Dosya Tablosu",
|
||||
"columns": {
|
||||
"name": "Ad",
|
||||
"description": "Açıklama",
|
||||
"size": "Boyut",
|
||||
"createdAt": "Oluşturulma Tarihi",
|
||||
"updatedAt": "Güncellenme Tarihi",
|
||||
"actions": "İşlemler"
|
||||
},
|
||||
"actions": {
|
||||
"menu": "Dosya İşlem Menüsü",
|
||||
"preview": "Önizleme",
|
||||
"edit": "Düzenle",
|
||||
"download": "İndir",
|
||||
"delete": "Sil"
|
||||
}
|
||||
},
|
||||
"sharesTable": {
|
||||
"ariaLabel": "Paylaşım Tablosu",
|
||||
"never": "Asla",
|
||||
"columns": {
|
||||
"name": "Ad",
|
||||
"createdAt": "Oluşturulma Tarihi",
|
||||
"expiresAt": "Son Kullanma Tarihi",
|
||||
"status": "Durum",
|
||||
"security": "Güvenlik",
|
||||
"files": "Dosyalar",
|
||||
"recipients": "Alıcılar",
|
||||
"actions": "İşlemler"
|
||||
},
|
||||
"status": {
|
||||
"neverExpires": "Sona Ermez",
|
||||
"active": "Aktif",
|
||||
"expired": "Sona Erdi"
|
||||
},
|
||||
"security": {
|
||||
"protected": "Korunuyor",
|
||||
"public": "Genel"
|
||||
},
|
||||
"filesCount": "{{count}} dosya",
|
||||
"recipientsCount": "{{count}} alıcı",
|
||||
"actions": {
|
||||
"menu": "Paylaşım İşlem Menüsü",
|
||||
"edit": "Düzenle",
|
||||
"manageFiles": "Dosyaları Yönet",
|
||||
"manageRecipients": "Alıcıları Yönet",
|
||||
"viewDetails": "Detayları Görüntüle",
|
||||
"generateLink": "Bağlantı Oluştur",
|
||||
"editLink": "Bağlantıyı Düzenle",
|
||||
"copyLink": "Bağlantıyı Kopyala",
|
||||
"notifyRecipients": "Alıcıları Bildir",
|
||||
"delete": "Sil"
|
||||
}
|
||||
},
|
||||
"footer": {
|
||||
"poweredBy": "Tarafından destekleniyor:",
|
||||
"kyanHomepage": "Kyantech Ana Sayfası"
|
||||
},
|
||||
"fileManager": {
|
||||
"downloadError": "Dosya indirilemedi",
|
||||
"updateSuccess": "Dosya başarıyla güncellendi",
|
||||
"updateError": "Dosya güncellenemedi",
|
||||
"deleteSuccess": "Dosya başarıyla silindi",
|
||||
"deleteError": "Dosya silinemedi"
|
||||
},
|
||||
"shareManager": {
|
||||
"deleteSuccess": "Paylaşım başarıyla silindi",
|
||||
"deleteError": "Paylaşım silinemedi",
|
||||
"updateSuccess": "Paylaşım başarıyla güncellendi",
|
||||
"updateError": "Paylaşım güncellenemedi",
|
||||
"filesUpdateSuccess": "Dosyalar başarıyla güncellendi",
|
||||
"filesUpdateError": "Dosyalar güncellenemedi",
|
||||
"recipientsUpdateSuccess": "Alıcılar başarıyla güncellendi",
|
||||
"recipientsUpdateError": "Alıcılar güncellenemedi",
|
||||
"linkGenerateSuccess": "Paylaşım bağlantısı başarıyla oluşturuldu",
|
||||
"linkGenerateError": "Paylaşım bağlantısı oluşturulamadı",
|
||||
"notifyLoading": "Bildirimler gönderiliyor...",
|
||||
"notifySuccess": "Alıcılara başarıyla bildirildi",
|
||||
"notifyError": "Alıcılara bildirim gönderilemedi"
|
||||
},
|
||||
"quickAccess": {
|
||||
"files": {
|
||||
"title": "Benim Dosyalarım",
|
||||
"description": "Yüklenen dosyalara erişin ve yönetin"
|
||||
},
|
||||
"shares": {
|
||||
"title": "Benim Paylaşımlarım",
|
||||
"description": "Paylaşılan dosyaları görüntüleyin ve yönetin"
|
||||
}
|
||||
},
|
||||
"recentFiles": {
|
||||
"title": "Son Yüklemeler",
|
||||
"viewAll": "Tümünü Görüntüle",
|
||||
"uploadFile": "Dosya Yükle",
|
||||
"noFiles": "Henüz dosya yüklenmedi"
|
||||
},
|
||||
"recentShares": {
|
||||
"title": "Son Paylaşımlar",
|
||||
"viewAll": "Tümünü Görüntüle",
|
||||
"createShare": "Paylaşım Oluştur",
|
||||
"noShares": "Henüz paylaşım oluşturulmadı",
|
||||
"createFirst": "İlk paylaşımınızı oluşturun"
|
||||
},
|
||||
"storageUsage": {
|
||||
"title": "Depolama Kullanımı",
|
||||
"ariaLabel": "Depolama kullanım ilerleme çubuğu",
|
||||
"used": "{{size}} kullanıldı",
|
||||
"available": "{{size}} kullanılabilir"
|
||||
},
|
||||
"dashboard": {
|
||||
"loadError": "Gösterge paneli verileri yüklenemedi",
|
||||
"linkCopied": "Bağlantı panoya kopyalandı",
|
||||
"pageTitle": "Gösterge Paneli",
|
||||
"breadcrumb": "Gösterge Paneli"
|
||||
},
|
||||
"emptyState": {
|
||||
"noFiles": "Henüz dosya yüklenmedi",
|
||||
"uploadFile": "Dosya Yükle"
|
||||
},
|
||||
"files": {
|
||||
"title": "Tüm Dosyalar",
|
||||
"uploadFile": "Dosya Yükle",
|
||||
"loadError": "Dosyalar yüklenemedi",
|
||||
"pageTitle": "Benim Dosyalarım",
|
||||
"breadcrumb": "Benim Dosyalarım"
|
||||
},
|
||||
"searchBar": {
|
||||
"placeholder": "Dosya ara...",
|
||||
"results": "Toplam {{total}} dosya içinde {{filtered}} dosya bulundu"
|
||||
},
|
||||
"forgotPassword": {
|
||||
"emailLabel": "E-posta Adresi",
|
||||
"emailPlaceholder": "E-posta adresinizi girin",
|
||||
"sending": "Gönderiliyor...",
|
||||
"submit": "Şifre Sıfırlama Talimatlarını Gönder",
|
||||
"backToLogin": "Girişe Geri Dön",
|
||||
"title": "Şifrenizi mi Unuttunuz?",
|
||||
"description": "E-posta adresinizi girin, şifre sıfırlama talimatlarını göndereceğiz.",
|
||||
"resetInstructions": "Şifre sıfırlama talimatları e-posta adresinize gönderildi",
|
||||
"pageTitle": "Şifrenizi mi Unuttunuz?"
|
||||
},
|
||||
"home": {
|
||||
"description": "WeTransfer'e açık kaynaklı alternatif. Takip veya kısıtlama olmadan dosyalarınızı güvenle paylaşın.",
|
||||
"documentation": "Belgelendirme",
|
||||
"starOnGithub": "GitHub'da Yıldız Verin",
|
||||
"privacyMessage": "Gizlilik göz önünde bulundurularak tasarlanmıştır. Yüklemeden önceki dosyalar, yalnızca paylaşım bağlantısına sahip olanlar tarafından erişilebilir. Her zaman ücretsiz ve açık kaynaktır.",
|
||||
"header": {
|
||||
"fileSharing": "Dosya Paylaşımı",
|
||||
"tagline": "Basit ve Ücretsiz"
|
||||
},
|
||||
"pageTitle": "Ana Sayfa"
|
||||
},
|
||||
"profile": {
|
||||
"password": {
|
||||
"title": "Şifreyi Değiştir",
|
||||
"newPassword": "Yeni Şifre",
|
||||
"confirmPassword": "Yeni Şifreyi Onayla",
|
||||
"updateButton": "Şifreyi Güncelle"
|
||||
},
|
||||
"form": {
|
||||
"title": "Profil Bilgileri",
|
||||
"firstName": "Ad",
|
||||
"lastName": "Soyad",
|
||||
"username": "Kullanıcı Adı",
|
||||
"email": "E-posta",
|
||||
"updateButton": "Profili Güncelle"
|
||||
},
|
||||
"header": {
|
||||
"title": "Profil",
|
||||
"subtitle": "Kişisel bilgilerinizi ve şifrenizi yönetin"
|
||||
},
|
||||
"picture": {
|
||||
"title": "Profil Resmi",
|
||||
"description": "Profil resmini değiştirmek için kamera simgesine tıklayın",
|
||||
"uploadPhoto": "Fotoğraf Yükle",
|
||||
"removePhoto": "Fotoğrafı Kaldır"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "Kullanıcı verileri yüklenemedi",
|
||||
"updateFailed": "Profil güncellenemedi",
|
||||
"passwordFailed": "Şifre güncellenemedi",
|
||||
"imageFailed": "Profil resmi güncellenemedi",
|
||||
"imageRemoveFailed": "Profil resmi kaldırılamadı"
|
||||
},
|
||||
"messages": {
|
||||
"noChanges": "Kaydedilecek değişiklik yok",
|
||||
"updateSuccess": "Profil başarıyla güncellendi",
|
||||
"fillPasswords": "Lütfen her iki şifre alanını da doldurun",
|
||||
"passwordSuccess": "Şifre başarıyla güncellendi",
|
||||
"imageSuccess": "Profil resmi başarıyla güncellendi",
|
||||
"imageRemoved": "Profil resmi başarıyla kaldırıldı"
|
||||
},
|
||||
"pageTitle": "Profil"
|
||||
},
|
||||
"resetPassword": {
|
||||
"pageTitle": "Şifreyi Sıfırla",
|
||||
"header": {
|
||||
"title": "Şifreyi Sıfırla",
|
||||
"description": "Aşağıya yeni şifrenizi girin"
|
||||
},
|
||||
"form": {
|
||||
"newPassword": "Yeni Şifre",
|
||||
"newPasswordPlaceholder": "Yeni şifrenizi girin",
|
||||
"confirmPassword": "Yeni Şifreyi Onayla",
|
||||
"confirmPasswordPlaceholder": "Yeni şifrenizi tekrar girin",
|
||||
"resetting": "Şifre sıfırlanıyor...",
|
||||
"submit": "Şifreyi Sıfırla",
|
||||
"backToLogin": "Girişe Geri Dön"
|
||||
},
|
||||
"messages": {
|
||||
"success": "Şifre başarıyla sıfırlandı"
|
||||
},
|
||||
"errors": {
|
||||
"serverError": "Şifre sıfırlama başarısız. Lütfen tekrar deneyin.",
|
||||
"invalidToken": "Geçersiz veya eksik sıfırlama belirteci"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"groups": {
|
||||
"defaultDescription": "Yapılandırma seçenekleri",
|
||||
"general": {
|
||||
"title": "Genel",
|
||||
"description": "Uygulamanın temel ayarları"
|
||||
},
|
||||
"email": {
|
||||
"title": "E-posta",
|
||||
"description": "E-posta sunucusu yapılandırması"
|
||||
},
|
||||
"security": {
|
||||
"title": "Güvenlik",
|
||||
"description": "Güvenlik ve kimlik doğrulama ayarları"
|
||||
},
|
||||
"storage": {
|
||||
"title": "Depolama",
|
||||
"description": "Dosya depolama yapılandırması"
|
||||
}
|
||||
},
|
||||
"fields": {
|
||||
"noDescription": "Açıklama mevcut değil",
|
||||
"appLogo": {
|
||||
"title": "Uygulama Logosu",
|
||||
"description": "Uygulama logosu resmi"
|
||||
},
|
||||
"appName": {
|
||||
"title": "Uygulama Adı",
|
||||
"description": "Kullanıcılara gösterilen uygulama adı"
|
||||
},
|
||||
"appDescription": {
|
||||
"title": "Uygulama Açıklaması",
|
||||
"description": "Uygulama hakkında kısa açıklama"
|
||||
},
|
||||
"showHomePage": {
|
||||
"title": "Ana Sayfayı Göster",
|
||||
"description": "Kurulumdan sonra ana sayfayı göster"
|
||||
},
|
||||
"smtpEnabled": {
|
||||
"title": "SMTP Etkin",
|
||||
"description": "SMTP e-posta işlevini etkinleştir veya devre dışı bırak"
|
||||
},
|
||||
"smtpHost": {
|
||||
"title": "SMTP Sunucusu",
|
||||
"description": "SMTP sunucusunun adresi"
|
||||
},
|
||||
"smtpPort": {
|
||||
"title": "SMTP Portu",
|
||||
"description": "SMTP sunucu portu"
|
||||
},
|
||||
"smtpUser": {
|
||||
"title": "SMTP Kullanıcısı",
|
||||
"description": "SMTP kimlik doğrulaması için kullanıcı adı"
|
||||
},
|
||||
"smtpPass": {
|
||||
"title": "SMTP Şifresi",
|
||||
"description": "SMTP kimlik doğrulaması için şifre"
|
||||
},
|
||||
"smtpFromName": {
|
||||
"title": "Gönderen Adı",
|
||||
"description": "Gönderilen e-postalarda görüntülenecek isim"
|
||||
},
|
||||
"smtpFromEmail": {
|
||||
"title": "Gönderen E-postası",
|
||||
"description": "Gönderenin e-posta adresi"
|
||||
},
|
||||
"maxLoginAttempts": {
|
||||
"title": "Maksimum Giriş Denemesi",
|
||||
"description": "Engelleme öncesi maksimum giriş denemesi sayısı"
|
||||
},
|
||||
"loginBlockDuration": {
|
||||
"title": "Giriş Engelleme Süresi",
|
||||
"description": "Deneme sayısı aşıldıktan sonra engelleme süresi (saniye cinsinden)"
|
||||
},
|
||||
"passwordMinLength": {
|
||||
"title": "Minimum Şifre Uzunluğu",
|
||||
"description": "Şifre için gereken minimum karakter sayısı"
|
||||
},
|
||||
"passwordResetTokenExpiration": {
|
||||
"title": "Şifre Sıfırlama Belirtecinin Süresi",
|
||||
"description": "Şifre sıfırlama belirtecinin geçerlilik süresi (saniye cinsinden)"
|
||||
},
|
||||
"maxFileSize": {
|
||||
"title": "Maksimum Dosya Boyutu",
|
||||
"description": "Yüklemeye izin verilen maksimum dosya boyutu (bayt cinsinden)"
|
||||
},
|
||||
"maxTotalStoragePerUser": {
|
||||
"title": "Kullanıcı Başına Maksimum Depolama",
|
||||
"description": "Kullanıcı başına toplam depolama sınırı (bayt cinsinden)"
|
||||
}
|
||||
},
|
||||
"buttons": {
|
||||
"save": "{{group}} Kaydet"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "Ayarlar yüklenemedi",
|
||||
"updateFailed": "Ayarlar güncellenemedi"
|
||||
},
|
||||
"messages": {
|
||||
"noChanges": "Kaydedilecek değişiklik yok",
|
||||
"updateSuccess": "{{group}} ayarları başarıyla güncellendi"
|
||||
},
|
||||
"title": "Ayarlar",
|
||||
"breadcrumb": "Ayarlar",
|
||||
"pageTitle": "Ayarlar"
|
||||
},
|
||||
"share": {
|
||||
"errors": {
|
||||
"invalidPassword": "Geçersiz şifre. Lütfen tekrar deneyin.",
|
||||
"loadFailed": "Paylaşım yüklenemedi",
|
||||
"downloadFailed": "Dosya indirilemedi"
|
||||
},
|
||||
"messages": {
|
||||
"downloadStarted": "İndirme başladı"
|
||||
},
|
||||
"password": {
|
||||
"title": "Şifre Korumalı Paylaşım",
|
||||
"protected": "Bu paylaşım şifre ile korunuyor",
|
||||
"incorrect": "Şifre yanlış. Lütfen tekrar deneyin.",
|
||||
"label": "Şifre",
|
||||
"placeholder": "Paylaşım şifresini girin",
|
||||
"submit": "Gönder"
|
||||
},
|
||||
"details": {
|
||||
"untitled": "Adsız",
|
||||
"created": "Oluşturulma: {{date}}",
|
||||
"expires": "Son Kullanma: {{date}}"
|
||||
},
|
||||
"notFound": {
|
||||
"title": "Paylaşım Bulunamadı",
|
||||
"description": "Bu paylaşım silinmiş veya süresi dolmuş olabilir."
|
||||
},
|
||||
"pageTitle": "Paylaşım"
|
||||
},
|
||||
"shares": {
|
||||
"errors": {
|
||||
"loadFailed": "Paylaşımlar yüklenemedi",
|
||||
"notifyFailed": "Alıcılara bildirim gönderilemedi",
|
||||
"smtpConfigFailed": "SMTP ayarları yüklenemedi"
|
||||
},
|
||||
"messages": {
|
||||
"linkCopied": "Bağlantı panoya kopyalandı",
|
||||
"recipientsNotified": "Alıcılar başarıyla bildirildi"
|
||||
},
|
||||
"empty": {
|
||||
"message": "Henüz paylaşım oluşturulmadı",
|
||||
"createButton": "Paylaşım Oluştur"
|
||||
},
|
||||
"header": {
|
||||
"title": "Benim Paylaşımlarım",
|
||||
"myShares": "Benim Paylaşımlarım"
|
||||
},
|
||||
"search": {
|
||||
"title": "Tüm Paylaşımlar",
|
||||
"createButton": "Paylaşım Oluştur",
|
||||
"placeholder": "Paylaşım ara...",
|
||||
"results": "Toplam {{total}} paylaşım arasında {{filtered}} paylaşım bulundu"
|
||||
},
|
||||
"pageTitle": "Paylaşımlar"
|
||||
},
|
||||
"users": {
|
||||
"modes": {
|
||||
"create": "Oluştur",
|
||||
"edit": "Düzenle"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "Kullanıcılar yüklenemedi",
|
||||
"submitFailed": "Kullanıcı {{mode}} edilemedi",
|
||||
"deleteFailed": "Kullanıcı silinemedi",
|
||||
"statusUpdateFailed": "Kullanıcı durumu güncellenemedi"
|
||||
},
|
||||
"messages": {
|
||||
"createSuccess": "Kullanıcı başarıyla oluşturuldu",
|
||||
"updateSuccess": "Kullanıcı başarıyla güncellendi",
|
||||
"deleteSuccess": "Kullanıcı başarıyla silindi",
|
||||
"activateSuccess": "Kullanıcı başarıyla etkinleştirildi",
|
||||
"deactivateSuccess": "Kullanıcı başarıyla devre dışı bırakıldı"
|
||||
},
|
||||
"actions": {
|
||||
"edit": "Düzenle",
|
||||
"activate": "Etkinleştir",
|
||||
"deactivate": "Devre Dışı Bırak",
|
||||
"delete": "Sil"
|
||||
},
|
||||
"delete": {
|
||||
"title": "Kullanıcı Silmeyi Onayla",
|
||||
"confirmation": "{{firstName}} {{lastName}} adlı kullanıcıyı silmek istediğinize emin misiniz? Bu işlem geri alınamaz.",
|
||||
"confirm": "Kullanıcıyı Sil"
|
||||
},
|
||||
"form": {
|
||||
"titleCreate": "Yeni Kullanıcı Ekle",
|
||||
"titleEdit": "Kullanıcıyı Düzenle",
|
||||
"firstName": "Ad",
|
||||
"lastName": "Soyad",
|
||||
"username": "Kullanıcı Adı",
|
||||
"email": "E-posta",
|
||||
"password": "Şifre",
|
||||
"newPassword": "Yeni Şifre (Opsiyonel)",
|
||||
"passwordPlaceholder": "Mevcut şifreyi korumak için boş bırakın",
|
||||
"role": "Rol",
|
||||
"roleUser": "Kullanıcı",
|
||||
"roleAdmin": "Yönetici",
|
||||
"create": "Oluştur",
|
||||
"save": "Kaydet"
|
||||
},
|
||||
"status": {
|
||||
"title": "Durum Değişikliğini Onayla",
|
||||
"confirmation": "{{firstName}} {{lastName}} adlı kullanıcıyı {{action}} etmek istediğinize emin misiniz?",
|
||||
"activate": "Etkinleştir",
|
||||
"deactivate": "Devre Dışı Bırak",
|
||||
"user": "Kullanıcı"
|
||||
},
|
||||
"header": {
|
||||
"title": "Kullanıcı Yönetimi",
|
||||
"addUser": "Kullanıcı Ekle",
|
||||
"management": "Kullanıcı Yönetimi"
|
||||
},
|
||||
"table": {
|
||||
"user": "Kullanıcı",
|
||||
"email": "E-posta",
|
||||
"status": "Durum",
|
||||
"role": "Rol",
|
||||
"actions": "İşlemler",
|
||||
"active": "Etkin",
|
||||
"inactive": "Devre Dışı",
|
||||
"admin": "Yönetici",
|
||||
"userr": "Kullanıcı"
|
||||
}
|
||||
},
|
||||
"logo": {
|
||||
"labels": {
|
||||
"appLogo": "Uygulama Logosu"
|
||||
},
|
||||
"buttons": {
|
||||
"upload": "Logoyu Yükle",
|
||||
"remove": "Logoyu Kaldır"
|
||||
},
|
||||
"messages": {
|
||||
"uploadSuccess": "Logo başarıyla yüklendi",
|
||||
"removeSuccess": "Logo başarıyla kaldırıldı"
|
||||
},
|
||||
"errors": {
|
||||
"uploadFailed": "Logo yüklenemedi",
|
||||
"removeFailed": "Logo kaldırılamadı"
|
||||
}
|
||||
},
|
||||
"navbar": {
|
||||
"logoAlt": "Uygulama Logosu",
|
||||
"profileMenu": "Profil Menüsü",
|
||||
"profile": "Profil",
|
||||
"settings": "Ayarlar",
|
||||
"usersManagement": "Kullanıcı Yönetimi",
|
||||
"logout": "Oturumu Kapat"
|
||||
}
|
||||
}
|
638
apps/app/messages/zh-CN.json
Normal file
638
apps/app/messages/zh-CN.json
Normal file
@@ -0,0 +1,638 @@
|
||||
{
|
||||
"login": {
|
||||
"welcome": "欢迎您",
|
||||
"signInToContinue": "请登录以继续",
|
||||
"emailLabel": "电子邮件地址",
|
||||
"emailPlaceholder": "请输入您的电子邮件",
|
||||
"passwordLabel": "密码",
|
||||
"passwordPlaceholder": "请输入您的密码",
|
||||
"signIn": "登录",
|
||||
"signingIn": "正在登录...",
|
||||
"forgotPassword": "忘记密码?",
|
||||
"pageTitle": "登录"
|
||||
},
|
||||
"errors": {
|
||||
"invalidCredentials": "电子邮件或密码错误",
|
||||
"userNotFound": "未找到用户",
|
||||
"accountLocked": "账户已锁定。请稍后再试",
|
||||
"unexpectedError": "发生意外错误。请重试"
|
||||
},
|
||||
"validation": {
|
||||
"invalidEmail": "无效的电子邮件地址",
|
||||
"passwordMinLength": "密码至少需要6个字符",
|
||||
"firstNameRequired": "名字为必填项",
|
||||
"lastNameRequired": "姓氏为必填项",
|
||||
"usernameLength": "用户名至少需要3个字符",
|
||||
"usernameSpaces": "用户名不能包含空格",
|
||||
"passwordLength": "密码至少需要8个字符",
|
||||
"passwordsMatch": "密码不匹配",
|
||||
"emailRequired": "电子邮件为必填项",
|
||||
"passwordRequired": "密码为必填项"
|
||||
},
|
||||
"fileSelector": {
|
||||
"availableFiles": "可用文件 ({{count}})",
|
||||
"shareFiles": "共享文件 ({{count}})",
|
||||
"searchPlaceholder": "搜索文件...",
|
||||
"noMatchingFiles": "没有匹配的文件",
|
||||
"noAvailableFiles": "没有可用的文件",
|
||||
"noFilesInShare": "共享中没有文件",
|
||||
"saveChanges": "保存更改"
|
||||
},
|
||||
"recipientSelector": {
|
||||
"emailPlaceholder": "请输入收件人电子邮件",
|
||||
"add": "添加",
|
||||
"recipients": "收件人 ({{count}})",
|
||||
"notifyAll": "通知所有人",
|
||||
"noRecipients": "还没有添加收件人",
|
||||
"addSuccess": "收件人添加成功",
|
||||
"addError": "添加收件人失败",
|
||||
"removeSuccess": "收件人删除成功",
|
||||
"removeError": "删除收件人失败",
|
||||
"sendingNotifications": "正在发送通知...",
|
||||
"notifySuccess": "收件人通知成功",
|
||||
"notifyError": "通知收件人失败"
|
||||
},
|
||||
"navigation": {
|
||||
"dashboard": "仪表盘"
|
||||
},
|
||||
"common": {
|
||||
"loading": "加载中,请稍候...",
|
||||
"cancel": "取消",
|
||||
"save": "保存",
|
||||
"delete": "删除",
|
||||
"close": "关闭",
|
||||
"download": "下载",
|
||||
"unexpectedError": "发生意外错误。请重试。",
|
||||
"yes": "是",
|
||||
"no": "否",
|
||||
"dashboard": "仪表盘"
|
||||
},
|
||||
"createShare": {
|
||||
"title": "创建共享",
|
||||
"nameLabel": "共享名称",
|
||||
"expirationLabel": "过期日期",
|
||||
"expirationPlaceholder": "MM/DD/YYYY HH:MM",
|
||||
"maxViewsLabel": "最大查看次数",
|
||||
"maxViewsPlaceholder": "留空表示无限",
|
||||
"passwordProtection": "密码保护",
|
||||
"passwordLabel": "密码",
|
||||
"create": "创建共享",
|
||||
"success": "共享创建成功",
|
||||
"error": "创建共享失败"
|
||||
},
|
||||
"fileActions": {
|
||||
"editFile": "编辑文件",
|
||||
"nameLabel": "名称",
|
||||
"namePlaceholder": "请输入新名称",
|
||||
"extension": "扩展名",
|
||||
"descriptionLabel": "描述",
|
||||
"descriptionPlaceholder": "请输入文件描述",
|
||||
"deleteFile": "删除文件",
|
||||
"deleteConfirmation": "您确定要删除“{{fileName}}”吗?",
|
||||
"deleteWarning": "此操作不可撤销。"
|
||||
},
|
||||
"filePreview": {
|
||||
"loading": "正在加载预览...",
|
||||
"notAvailable": "预览不可用",
|
||||
"downloadToView": "下载文件以查看内容",
|
||||
"audioNotSupported": "您的浏览器不支持音频元素",
|
||||
"videoNotSupported": "您的浏览器不支持视频元素",
|
||||
"loadError": "加载预览失败",
|
||||
"downloadError": "下载文件失败"
|
||||
},
|
||||
"generateShareLink": {
|
||||
"generateTitle": "生成共享链接",
|
||||
"updateTitle": "更新共享链接",
|
||||
"generateDescription": "生成用于共享文件的链接",
|
||||
"updateDescription": "更新此共享链接的别名",
|
||||
"aliasPlaceholder": "请输入别名",
|
||||
"linkReady": "您的共享链接已准备好:",
|
||||
"generateButton": "生成链接",
|
||||
"updateButton": "更新链接",
|
||||
"copyButton": "复制链接",
|
||||
"success": "链接生成成功",
|
||||
"error": "生成链接失败",
|
||||
"copied": "链接已复制到剪贴板"
|
||||
},
|
||||
"shareActions": {
|
||||
"deleteTitle": "删除共享",
|
||||
"deleteConfirmation": "您确定要删除此共享吗?此操作不可撤销。",
|
||||
"editTitle": "编辑共享",
|
||||
"nameLabel": "共享名称",
|
||||
"expirationLabel": "过期日期",
|
||||
"expirationPlaceholder": "MM/DD/YYYY HH:MM",
|
||||
"maxViewsLabel": "最大查看次数",
|
||||
"maxViewsPlaceholder": "留空表示无限",
|
||||
"passwordProtection": "密码保护",
|
||||
"passwordLabel": "密码",
|
||||
"passwordPlaceholder": "请输入密码",
|
||||
"newPasswordLabel": "新密码(留空表示保持当前密码)",
|
||||
"newPasswordPlaceholder": "请输入新密码",
|
||||
"manageFilesTitle": "管理文件",
|
||||
"manageRecipientsTitle": "管理收件人",
|
||||
"editSuccess": "共享更新成功",
|
||||
"editError": "更新共享失败"
|
||||
},
|
||||
"shareDetails": {
|
||||
"title": "共享详情",
|
||||
"subtitle": "关于此共享的详细信息",
|
||||
"basicInfo": "基本信息",
|
||||
"name": "名称",
|
||||
"untitled": "未命名",
|
||||
"views": "查看次数",
|
||||
"dates": "日期",
|
||||
"created": "创建于",
|
||||
"expires": "过期于",
|
||||
"never": "从不",
|
||||
"security": "安全性",
|
||||
"passwordProtected": "受密码保护",
|
||||
"publicAccess": "公开访问",
|
||||
"maxViews": "最大查看次数:{{count}}",
|
||||
"files": "文件 ({{count}})",
|
||||
"recipients": "收件人 ({{count}})",
|
||||
"notAvailable": "不适用",
|
||||
"invalidDate": "无效的日期",
|
||||
"loadError": "加载共享详情失败"
|
||||
},
|
||||
"uploadFile": {
|
||||
"title": "上传文件",
|
||||
"selectFile": "点击选择文件",
|
||||
"preview": "预览",
|
||||
"uploadProgress": "上传进度",
|
||||
"upload": "上传",
|
||||
"success": "文件上传成功",
|
||||
"error": "文件上传失败"
|
||||
},
|
||||
"filesTable": {
|
||||
"ariaLabel": "文件表格",
|
||||
"columns": {
|
||||
"name": "名称",
|
||||
"description": "描述",
|
||||
"size": "大小",
|
||||
"createdAt": "创建时间",
|
||||
"updatedAt": "更新时间",
|
||||
"actions": "操作"
|
||||
},
|
||||
"actions": {
|
||||
"menu": "文件操作菜单",
|
||||
"preview": "预览",
|
||||
"edit": "编辑",
|
||||
"download": "下载",
|
||||
"delete": "删除"
|
||||
}
|
||||
},
|
||||
"sharesTable": {
|
||||
"ariaLabel": "共享表格",
|
||||
"never": "从不",
|
||||
"columns": {
|
||||
"name": "名称",
|
||||
"createdAt": "创建时间",
|
||||
"expiresAt": "过期时间",
|
||||
"status": "状态",
|
||||
"security": "安全性",
|
||||
"files": "文件",
|
||||
"recipients": "收件人",
|
||||
"actions": "操作"
|
||||
},
|
||||
"status": {
|
||||
"neverExpires": "永不过期",
|
||||
"active": "活跃",
|
||||
"expired": "已过期"
|
||||
},
|
||||
"security": {
|
||||
"protected": "受保护",
|
||||
"public": "公开"
|
||||
},
|
||||
"filesCount": "{{count}} 个文件",
|
||||
"recipientsCount": "{{count}} 个收件人",
|
||||
"actions": {
|
||||
"menu": "共享操作菜单",
|
||||
"edit": "编辑",
|
||||
"manageFiles": "管理文件",
|
||||
"manageRecipients": "管理收件人",
|
||||
"viewDetails": "查看详情",
|
||||
"generateLink": "生成链接",
|
||||
"editLink": "编辑链接",
|
||||
"copyLink": "复制链接",
|
||||
"notifyRecipients": "通知收件人",
|
||||
"delete": "删除"
|
||||
}
|
||||
},
|
||||
"footer": {
|
||||
"poweredBy": "技术支持:",
|
||||
"kyanHomepage": "Kyantech 主页"
|
||||
},
|
||||
"fileManager": {
|
||||
"downloadError": "文件下载失败",
|
||||
"updateSuccess": "文件更新成功",
|
||||
"updateError": "文件更新失败",
|
||||
"deleteSuccess": "文件删除成功",
|
||||
"deleteError": "文件删除失败"
|
||||
},
|
||||
"shareManager": {
|
||||
"deleteSuccess": "共享删除成功",
|
||||
"deleteError": "共享删除失败",
|
||||
"updateSuccess": "共享更新成功",
|
||||
"updateError": "共享更新失败",
|
||||
"filesUpdateSuccess": "文件更新成功",
|
||||
"filesUpdateError": "文件更新失败",
|
||||
"recipientsUpdateSuccess": "收件人更新成功",
|
||||
"recipientsUpdateError": "收件人更新失败",
|
||||
"linkGenerateSuccess": "共享链接生成成功",
|
||||
"linkGenerateError": "共享链接生成失败",
|
||||
"notifyLoading": "正在发送通知...",
|
||||
"notifySuccess": "通知收件人成功",
|
||||
"notifyError": "通知收件人失败"
|
||||
},
|
||||
"quickAccess": {
|
||||
"files": {
|
||||
"title": "我的文件",
|
||||
"description": "访问和管理您上传的文件"
|
||||
},
|
||||
"shares": {
|
||||
"title": "我的共享",
|
||||
"description": "查看和管理您共享的文件"
|
||||
}
|
||||
},
|
||||
"recentFiles": {
|
||||
"title": "最近上传",
|
||||
"viewAll": "查看全部",
|
||||
"uploadFile": "上传文件",
|
||||
"noFiles": "尚未上传文件"
|
||||
},
|
||||
"recentShares": {
|
||||
"title": "最近共享",
|
||||
"viewAll": "查看全部",
|
||||
"createShare": "创建共享",
|
||||
"noShares": "尚未创建共享",
|
||||
"createFirst": "请创建您的第一个共享"
|
||||
},
|
||||
"storageUsage": {
|
||||
"title": "存储使用情况",
|
||||
"ariaLabel": "存储使用进度条",
|
||||
"used": "已使用:{{size}}",
|
||||
"available": "可用:{{size}}"
|
||||
},
|
||||
"dashboard": {
|
||||
"loadError": "加载仪表盘数据失败",
|
||||
"linkCopied": "链接已复制到剪贴板",
|
||||
"pageTitle": "仪表盘",
|
||||
"breadcrumb": "仪表盘"
|
||||
},
|
||||
"emptyState": {
|
||||
"noFiles": "尚未上传任何文件",
|
||||
"uploadFile": "上传文件"
|
||||
},
|
||||
"files": {
|
||||
"title": "所有文件",
|
||||
"uploadFile": "上传文件",
|
||||
"loadError": "加载文件失败",
|
||||
"pageTitle": "我的文件",
|
||||
"breadcrumb": "我的文件"
|
||||
},
|
||||
"searchBar": {
|
||||
"placeholder": "搜索文件...",
|
||||
"results": "共{{total}}个文件,找到{{filtered}}个"
|
||||
},
|
||||
"forgotPassword": {
|
||||
"emailLabel": "电子邮件地址",
|
||||
"emailPlaceholder": "请输入您的电子邮件",
|
||||
"sending": "正在发送...",
|
||||
"submit": "发送密码重置指令",
|
||||
"backToLogin": "返回登录",
|
||||
"title": "忘记密码?",
|
||||
"description": "请输入您的电子邮件,我们将发送密码重置指令给您。",
|
||||
"resetInstructions": "密码重置指令已发送到您的电子邮件",
|
||||
"pageTitle": "忘记密码?"
|
||||
},
|
||||
"home": {
|
||||
"description": "WeTransfer的开源替代方案。安全分享文件,无需跟踪或限制。",
|
||||
"documentation": "文档",
|
||||
"starOnGithub": "在GitHub上点赞",
|
||||
"privacyMessage": "本应用注重隐私。在上传前,您的文件仅对拥有共享链接的人可见。永远免费且开源。",
|
||||
"header": {
|
||||
"fileSharing": "文件共享",
|
||||
"tagline": "简单且免费"
|
||||
},
|
||||
"pageTitle": "首页"
|
||||
},
|
||||
"profile": {
|
||||
"password": {
|
||||
"title": "修改密码",
|
||||
"newPassword": "新密码",
|
||||
"confirmPassword": "确认新密码",
|
||||
"updateButton": "更新密码"
|
||||
},
|
||||
"form": {
|
||||
"title": "个人资料信息",
|
||||
"firstName": "名字",
|
||||
"lastName": "姓氏",
|
||||
"username": "用户名",
|
||||
"email": "电子邮件",
|
||||
"updateButton": "更新资料"
|
||||
},
|
||||
"header": {
|
||||
"title": "个人资料",
|
||||
"subtitle": "管理您的个人信息和密码"
|
||||
},
|
||||
"picture": {
|
||||
"title": "个人头像",
|
||||
"description": "点击相机图标以更换头像",
|
||||
"uploadPhoto": "上传照片",
|
||||
"removePhoto": "移除照片"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "加载用户数据失败",
|
||||
"updateFailed": "更新个人资料失败",
|
||||
"passwordFailed": "更新密码失败",
|
||||
"imageFailed": "更新头像失败",
|
||||
"imageRemoveFailed": "移除头像失败"
|
||||
},
|
||||
"messages": {
|
||||
"noChanges": "没有可保存的更改",
|
||||
"updateSuccess": "个人资料更新成功",
|
||||
"fillPasswords": "请填写两个密码字段",
|
||||
"passwordSuccess": "密码更新成功",
|
||||
"imageSuccess": "头像更新成功",
|
||||
"imageRemoved": "头像移除成功"
|
||||
},
|
||||
"pageTitle": "个人资料"
|
||||
},
|
||||
"resetPassword": {
|
||||
"pageTitle": "重置密码",
|
||||
"header": {
|
||||
"title": "重置密码",
|
||||
"description": "在下方输入您的新密码"
|
||||
},
|
||||
"form": {
|
||||
"newPassword": "新密码",
|
||||
"newPasswordPlaceholder": "请输入新密码",
|
||||
"confirmPassword": "确认新密码",
|
||||
"confirmPasswordPlaceholder": "请再次输入新密码",
|
||||
"resetting": "正在重置密码...",
|
||||
"submit": "重置密码",
|
||||
"backToLogin": "返回登录"
|
||||
},
|
||||
"messages": {
|
||||
"success": "密码重置成功"
|
||||
},
|
||||
"errors": {
|
||||
"serverError": "密码重置失败,请重试。",
|
||||
"invalidToken": "无效或缺失重置令牌"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"groups": {
|
||||
"defaultDescription": "配置选项",
|
||||
"general": {
|
||||
"title": "通用",
|
||||
"description": "基本的应用设置"
|
||||
},
|
||||
"email": {
|
||||
"title": "电子邮件",
|
||||
"description": "电子邮件服务器配置"
|
||||
},
|
||||
"security": {
|
||||
"title": "安全性",
|
||||
"description": "安全与认证设置"
|
||||
},
|
||||
"storage": {
|
||||
"title": "存储",
|
||||
"description": "文件存储配置"
|
||||
}
|
||||
},
|
||||
"fields": {
|
||||
"noDescription": "暂无描述",
|
||||
"appLogo": {
|
||||
"title": "应用Logo",
|
||||
"description": "应用的Logo图片"
|
||||
},
|
||||
"appName": {
|
||||
"title": "应用名称",
|
||||
"description": "显示给用户的应用名称"
|
||||
},
|
||||
"appDescription": {
|
||||
"title": "应用描述",
|
||||
"description": "对应用的简短描述"
|
||||
},
|
||||
"showHomePage": {
|
||||
"title": "显示首页",
|
||||
"description": "安装后显示首页"
|
||||
},
|
||||
"smtpEnabled": {
|
||||
"title": "启用SMTP",
|
||||
"description": "启用或禁用SMTP邮件功能"
|
||||
},
|
||||
"smtpHost": {
|
||||
"title": "SMTP服务器",
|
||||
"description": "SMTP服务器地址"
|
||||
},
|
||||
"smtpPort": {
|
||||
"title": "SMTP端口",
|
||||
"description": "SMTP服务器端口"
|
||||
},
|
||||
"smtpUser": {
|
||||
"title": "SMTP用户名",
|
||||
"description": "用于SMTP认证的用户名"
|
||||
},
|
||||
"smtpPass": {
|
||||
"title": "SMTP密码",
|
||||
"description": "用于SMTP认证的密码"
|
||||
},
|
||||
"smtpFromName": {
|
||||
"title": "发件人姓名",
|
||||
"description": "发送邮件时显示的名称"
|
||||
},
|
||||
"smtpFromEmail": {
|
||||
"title": "发件人电子邮件",
|
||||
"description": "发件人的电子邮件地址"
|
||||
},
|
||||
"maxLoginAttempts": {
|
||||
"title": "最大登录尝试次数",
|
||||
"description": "达到限制前允许的最大登录尝试次数"
|
||||
},
|
||||
"loginBlockDuration": {
|
||||
"title": "登录阻止时长",
|
||||
"description": "超过尝试次数后的阻止时长(以秒为单位)"
|
||||
},
|
||||
"passwordMinLength": {
|
||||
"title": "最小密码长度",
|
||||
"description": "密码所需的最小字符数"
|
||||
},
|
||||
"passwordResetTokenExpiration": {
|
||||
"title": "密码重置令牌有效期",
|
||||
"description": "密码重置令牌的有效时长(以秒为单位)"
|
||||
},
|
||||
"maxFileSize": {
|
||||
"title": "最大文件大小",
|
||||
"description": "允许上传的最大文件大小(以字节为单位)"
|
||||
},
|
||||
"maxTotalStoragePerUser": {
|
||||
"title": "每个用户的最大存储量",
|
||||
"description": "每个用户的总存储限制(以字节为单位)"
|
||||
}
|
||||
},
|
||||
"buttons": {
|
||||
"save": "保存 {{group}}"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "加载设置失败",
|
||||
"updateFailed": "更新设置失败"
|
||||
},
|
||||
"messages": {
|
||||
"noChanges": "没有需要保存的更改",
|
||||
"updateSuccess": "{{group}}设置更新成功"
|
||||
},
|
||||
"title": "设置",
|
||||
"breadcrumb": "设置",
|
||||
"pageTitle": "设置"
|
||||
},
|
||||
"share": {
|
||||
"errors": {
|
||||
"invalidPassword": "无效的密码。请重试。",
|
||||
"loadFailed": "加载共享失败",
|
||||
"downloadFailed": "下载文件失败"
|
||||
},
|
||||
"messages": {
|
||||
"downloadStarted": "下载已开始"
|
||||
},
|
||||
"password": {
|
||||
"title": "密码保护的共享",
|
||||
"protected": "此共享受密码保护",
|
||||
"incorrect": "密码不正确。请重试。",
|
||||
"label": "密码",
|
||||
"placeholder": "请输入共享密码",
|
||||
"submit": "提交"
|
||||
},
|
||||
"details": {
|
||||
"untitled": "未命名",
|
||||
"created": "创建于:{{date}}",
|
||||
"expires": "过期于:{{date}}"
|
||||
},
|
||||
"notFound": {
|
||||
"title": "未找到共享",
|
||||
"description": "该共享可能已被删除或已过期。"
|
||||
},
|
||||
"pageTitle": "共享"
|
||||
},
|
||||
"shares": {
|
||||
"errors": {
|
||||
"loadFailed": "加载共享失败",
|
||||
"notifyFailed": "通知收件人失败",
|
||||
"smtpConfigFailed": "加载SMTP配置失败"
|
||||
},
|
||||
"messages": {
|
||||
"linkCopied": "链接已复制到剪贴板",
|
||||
"recipientsNotified": "收件人已成功通知"
|
||||
},
|
||||
"empty": {
|
||||
"message": "尚未创建共享",
|
||||
"createButton": "创建共享"
|
||||
},
|
||||
"header": {
|
||||
"title": "我的共享",
|
||||
"myShares": "我的共享"
|
||||
},
|
||||
"search": {
|
||||
"title": "所有共享",
|
||||
"createButton": "创建共享",
|
||||
"placeholder": "搜索共享...",
|
||||
"results": "在总共{{total}}个共享中找到了{{filtered}}个"
|
||||
},
|
||||
"pageTitle": "共享"
|
||||
},
|
||||
"users": {
|
||||
"modes": {
|
||||
"create": "创建",
|
||||
"edit": "编辑"
|
||||
},
|
||||
"errors": {
|
||||
"loadFailed": "加载用户失败",
|
||||
"submitFailed": "用户{{mode}}失败",
|
||||
"deleteFailed": "删除用户失败",
|
||||
"statusUpdateFailed": "更新用户状态失败"
|
||||
},
|
||||
"messages": {
|
||||
"createSuccess": "用户创建成功",
|
||||
"updateSuccess": "用户更新成功",
|
||||
"deleteSuccess": "用户删除成功",
|
||||
"activateSuccess": "用户已成功激活",
|
||||
"deactivateSuccess": "用户已成功停用"
|
||||
},
|
||||
"actions": {
|
||||
"edit": "编辑",
|
||||
"activate": "激活",
|
||||
"deactivate": "停用",
|
||||
"delete": "删除"
|
||||
},
|
||||
"delete": {
|
||||
"title": "确认删除用户",
|
||||
"confirmation": "您确定要删除{{firstName}} {{lastName}}吗?此操作不可撤销。",
|
||||
"confirm": "删除用户"
|
||||
},
|
||||
"form": {
|
||||
"titleCreate": "添加新用户",
|
||||
"titleEdit": "编辑用户",
|
||||
"firstName": "名字",
|
||||
"lastName": "姓氏",
|
||||
"username": "用户名",
|
||||
"email": "电子邮件",
|
||||
"password": "密码",
|
||||
"newPassword": "新密码(可选)",
|
||||
"passwordPlaceholder": "留空以保留当前密码",
|
||||
"role": "角色",
|
||||
"roleUser": "用户",
|
||||
"roleAdmin": "管理员",
|
||||
"create": "创建",
|
||||
"save": "保存"
|
||||
},
|
||||
"status": {
|
||||
"title": "确认状态更改",
|
||||
"confirmation": "您确定要{{action}}{{firstName}} {{lastName}}吗?",
|
||||
"activate": "激活",
|
||||
"deactivate": "停用",
|
||||
"user": "用户"
|
||||
},
|
||||
"header": {
|
||||
"title": "用户管理",
|
||||
"addUser": "添加用户",
|
||||
"management": "用户管理"
|
||||
},
|
||||
"table": {
|
||||
"user": "用户",
|
||||
"email": "电子邮件",
|
||||
"status": "状态",
|
||||
"role": "角色",
|
||||
"actions": "操作",
|
||||
"active": "激活",
|
||||
"inactive": "停用",
|
||||
"admin": "管理员",
|
||||
"userr": "用户"
|
||||
}
|
||||
},
|
||||
"logo": {
|
||||
"labels": {
|
||||
"appLogo": "应用Logo"
|
||||
},
|
||||
"buttons": {
|
||||
"upload": "上传Logo",
|
||||
"remove": "删除Logo"
|
||||
},
|
||||
"messages": {
|
||||
"uploadSuccess": "Logo上传成功",
|
||||
"removeSuccess": "Logo删除成功"
|
||||
},
|
||||
"errors": {
|
||||
"uploadFailed": "Logo上传失败",
|
||||
"removeFailed": "Logo删除失败"
|
||||
}
|
||||
},
|
||||
"navbar": {
|
||||
"logoAlt": "应用Logo",
|
||||
"profileMenu": "个人菜单",
|
||||
"profile": "个人资料",
|
||||
"settings": "设置",
|
||||
"usersManagement": "用户管理",
|
||||
"logout": "退出登录"
|
||||
}
|
||||
}
|
7
apps/app/next.config.ts
Normal file
7
apps/app/next.config.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { NextConfig } from "next";
|
||||
import createNextIntlPlugin from "next-intl/plugin";
|
||||
|
||||
const nextConfig: NextConfig = {};
|
||||
|
||||
const withNextIntl = createNextIntlPlugin();
|
||||
export default withNextIntl(nextConfig);
|
58
apps/app/package.json
Normal file
58
apps/app/package.json
Normal file
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"name": "palmr-app-v2",
|
||||
"version": "2.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev --turbopack",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "eslint \"src/**/*.+(ts|tsx)\"",
|
||||
"lint:fix": "eslint \"src/**/*.+(ts|tsx)\" --fix",
|
||||
"format": "prettier . --write",
|
||||
"format:check": "prettier . --check"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hookform/resolvers": "^5.0.1",
|
||||
"@radix-ui/react-dialog": "^1.1.6",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.6",
|
||||
"@radix-ui/react-label": "^2.1.2",
|
||||
"@radix-ui/react-slot": "^1.1.2",
|
||||
"@tabler/icons-react": "^3.31.0",
|
||||
"axios": "^1.8.4",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"framer-motion": "^12.6.3",
|
||||
"lucide-react": "^0.487.0",
|
||||
"next": "15.2.4",
|
||||
"next-intl": "^4.0.2",
|
||||
"next-themes": "^0.4.6",
|
||||
"nookies": "^2.5.2",
|
||||
"react": "^19.1.0",
|
||||
"react-country-flag": "^3.1.0",
|
||||
"react-dom": "^19.1.0",
|
||||
"react-hook-form": "^7.55.0",
|
||||
"tailwind-merge": "^3.1.0",
|
||||
"tw-animate-css": "^1.2.5",
|
||||
"zod": "^3.24.2",
|
||||
"zustand": "^5.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/eslintrc": "3.3.1",
|
||||
"@eslint/js": "9.23.0",
|
||||
"@ianvs/prettier-plugin-sort-imports": "4.4.1",
|
||||
"@tailwindcss/postcss": "4.1.2",
|
||||
"@types/node": "22.14.0",
|
||||
"@types/react": "19.1.0",
|
||||
"@types/react-dom": "19.1.1",
|
||||
"@typescript-eslint/eslint-plugin": "8.29.0",
|
||||
"@typescript-eslint/parser": "8.29.0",
|
||||
"eslint": "9.23.0",
|
||||
"eslint-config-next": "15.2.4",
|
||||
"eslint-config-prettier": "9.1.0",
|
||||
"eslint-plugin-prettier": "5.2.6",
|
||||
"prettier": "3.5.3",
|
||||
"prettier-plugin-sort-json": "4.1.1",
|
||||
"tailwindcss": "4.1.2",
|
||||
"typescript": "5.8.2"
|
||||
}
|
||||
}
|
4902
apps/app/pnpm-lock.yaml
generated
Normal file
4902
apps/app/pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
5
apps/app/postcss.config.mjs
Normal file
5
apps/app/postcss.config.mjs
Normal file
@@ -0,0 +1,5 @@
|
||||
const config = {
|
||||
plugins: ["@tailwindcss/postcss"],
|
||||
};
|
||||
|
||||
export default config;
|
1
apps/app/public/file.svg
Normal file
1
apps/app/public/file.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>
|
After Width: | Height: | Size: 391 B |
1
apps/app/public/globe.svg
Normal file
1
apps/app/public/globe.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>
|
After Width: | Height: | Size: 1.0 KiB |
1
apps/app/public/next.svg
Normal file
1
apps/app/public/next.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
|
After Width: | Height: | Size: 1.3 KiB |
1
apps/app/public/vercel.svg
Normal file
1
apps/app/public/vercel.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1155 1000"><path d="m577.3 0 577.4 1000H0z" fill="#fff"/></svg>
|
After Width: | Height: | Size: 128 B |
1
apps/app/public/window.svg
Normal file
1
apps/app/public/window.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2.5h13v10a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1zM0 1h16v11.5a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 0 12.5zm3.75 4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5M7 4.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0m1.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5" fill="#666"/></svg>
|
After Width: | Height: | Size: 385 B |
75
apps/app/src/app/(home)/components/home-content.tsx
Normal file
75
apps/app/src/app/(home)/components/home-content.tsx
Normal file
@@ -0,0 +1,75 @@
|
||||
import Link from "next/link";
|
||||
import { IconBrandGithubFilled } from "@tabler/icons-react";
|
||||
import { motion } from "framer-motion";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { siteConfig } from "@/config/site";
|
||||
import { HomeContentProps } from "../types";
|
||||
import { BackgroundLights } from "../../../components/ui/background-lights";
|
||||
import { HomeHeader } from "./home-header";
|
||||
|
||||
const fadeInAnimation = {
|
||||
animate: { opacity: 1 },
|
||||
initial: { opacity: 0 },
|
||||
transition: { duration: 0.5 }
|
||||
};
|
||||
|
||||
const fadeInUpAnimation = {
|
||||
animate: { opacity: 1, y: 0 },
|
||||
initial: { opacity: 0, y: 20 },
|
||||
transition: { duration: 0.5 }
|
||||
};
|
||||
|
||||
function ActionButtons({ t }: { t: (key: string) => string }) {
|
||||
return (
|
||||
<div className="flex gap-3">
|
||||
<Button asChild variant="ghost">
|
||||
<Link href={siteConfig.links.docs} target="_blank" rel="noopener noreferrer">
|
||||
{t("home.documentation")}
|
||||
</Link>
|
||||
</Button>
|
||||
<Button asChild variant="outline">
|
||||
<Link href={siteConfig.links.github} target="_blank" rel="noopener noreferrer">
|
||||
<IconBrandGithubFilled className="size-5" />
|
||||
{t("home.starOnGithub")}
|
||||
</Link>
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function HomeContent({ isLoading }: HomeContentProps) {
|
||||
const t = useTranslations();
|
||||
|
||||
if (isLoading) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="container mx-auto max-w-7xl px-6 flex-grow">
|
||||
<BackgroundLights />
|
||||
<section className="relative flex flex-col items-center justify-center gap-6 m-auto h-full">
|
||||
<HomeHeader title="🌴 Palmr." />
|
||||
<motion.div
|
||||
{...fadeInAnimation}
|
||||
className="w-full text-lg lg:text-xl text-default-600 mt-4 text-center whitespace-normal"
|
||||
transition={{ delay: 0.6, ...fadeInAnimation.transition }}
|
||||
>
|
||||
{t("home.description")}
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
{...fadeInUpAnimation}
|
||||
className="flex flex-col items-center gap-6 mt-8"
|
||||
transition={{ delay: 0.8, ...fadeInUpAnimation.transition }}
|
||||
>
|
||||
<ActionButtons t={t} />
|
||||
<p className="text-sm opacity-70 max-w-md text-center">
|
||||
{t("home.privacyMessage")}
|
||||
</p>
|
||||
</motion.div>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
56
apps/app/src/app/(home)/components/home-header.tsx
Normal file
56
apps/app/src/app/(home)/components/home-header.tsx
Normal file
@@ -0,0 +1,56 @@
|
||||
import { motion } from "framer-motion";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
import { HomeHeaderProps } from "../types";
|
||||
|
||||
const fadeInUpAnimation = {
|
||||
animate: { opacity: 1, y: 0 },
|
||||
initial: { opacity: 0, y: 20 },
|
||||
transition: { duration: 0.5 }
|
||||
};
|
||||
|
||||
const titleAnimation = {
|
||||
animate: { scale: 1 },
|
||||
initial: { scale: 0.9 },
|
||||
transition: { duration: 0.3 }
|
||||
};
|
||||
|
||||
const slideInAnimation = (delay: number, direction: -1 | 1) => ({
|
||||
animate: { opacity: 1, x: 0 },
|
||||
initial: { opacity: 0, x: 20 * direction },
|
||||
transition: { delay, duration: 0.5 }
|
||||
});
|
||||
|
||||
export function HomeHeader({ title }: HomeHeaderProps) {
|
||||
const t = useTranslations();
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
{...fadeInUpAnimation}
|
||||
className="inline-block max-w-xl text-center justify-center"
|
||||
>
|
||||
<div className="flex flex-col gap-8">
|
||||
<motion.span
|
||||
{...titleAnimation}
|
||||
className="text-4xl lg:text-6xl font-extrabold tracking-tight"
|
||||
>
|
||||
{title}
|
||||
</motion.span>
|
||||
<div className="flex flex-col gap-2">
|
||||
<motion.span
|
||||
{...slideInAnimation(0.2, -1)}
|
||||
className="text-4xl lg:text-5xl font-semibold tracking-tight text-primary"
|
||||
>
|
||||
{t("home.header.fileSharing")}
|
||||
</motion.span>
|
||||
<motion.span
|
||||
{...slideInAnimation(0.4, 1)}
|
||||
className="text-[2.3rem] lg:text-5xl leading-9 font-semibold tracking-tight"
|
||||
>
|
||||
{t("home.header.tagline")}
|
||||
</motion.span>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
}
|
92
apps/app/src/app/(home)/components/navbar.tsx
Normal file
92
apps/app/src/app/(home)/components/navbar.tsx
Normal file
@@ -0,0 +1,92 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect } from "react";
|
||||
import { useState } from "react";
|
||||
import Link from "next/link";
|
||||
import { IconHeart, IconMenu2 } from "@tabler/icons-react";
|
||||
|
||||
import { LanguageSwitcher } from "@/components/general/language-switcher";
|
||||
import { ModeToggle } from "@/components/mode-toggle";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Sheet, SheetContent, SheetTrigger } from "@/components/ui/sheet";
|
||||
import { siteConfig } from "@/config/site";
|
||||
import { useAppInfo } from "@/contexts/app-info-context";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
export function Navbar() {
|
||||
const { appName, appLogo, refreshAppInfo } = useAppInfo();
|
||||
const [isMenuOpen, setIsMenuOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
refreshAppInfo();
|
||||
}, [refreshAppInfo]);
|
||||
|
||||
return (
|
||||
<header className="sticky top-0 z-40 w-full border-b border-border/50 bg-background/70 backdrop-blur-sm px-6">
|
||||
<div className="container flex h-16 max-w-screen-xl items-center mx-auto">
|
||||
<div className="flex flex-1 items-center justify-between">
|
||||
<div className="flex items-center gap-3">
|
||||
<Link href="/" className="flex items-center gap-2">
|
||||
{appLogo && <img alt="App Logo" className="h-8 w-8 object-contain" src={appLogo} />}
|
||||
<p className="font-bold text-2xl">{appName}</p>
|
||||
</Link>
|
||||
<nav className="hidden lg:flex ml-2 gap-4">
|
||||
{siteConfig.navItems.map((item) => (
|
||||
<Link
|
||||
key={item.href}
|
||||
href={item.href}
|
||||
className={cn(
|
||||
"text-sm font-medium transition-colors hover:text-foreground/80",
|
||||
"data-[active=true]:text-primary data-[active=true]:font-medium"
|
||||
)}
|
||||
>
|
||||
{item.label}
|
||||
</Link>
|
||||
))}
|
||||
</nav>
|
||||
</div>
|
||||
<div className="hidden md:flex items-center gap-2">
|
||||
<LanguageSwitcher />
|
||||
<ModeToggle />
|
||||
|
||||
<Button asChild variant="ghost" className="text-sm font-normal">
|
||||
<Link href={siteConfig.links.sponsor} target="_blank" rel="noopener noreferrer">
|
||||
<IconHeart className="h-4 w-4 text-destructive" />
|
||||
Sponsor
|
||||
</Link>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2 sm:hidden">
|
||||
<LanguageSwitcher />
|
||||
<ModeToggle />
|
||||
<Sheet open={isMenuOpen} onOpenChange={setIsMenuOpen}>
|
||||
<SheetTrigger asChild>
|
||||
<Button variant="ghost" size="icon" className="h-9 w-9 p-0">
|
||||
<IconMenu2 className="h-5 w-5" />
|
||||
<span className="sr-only">Toggle menu</span>
|
||||
</Button>
|
||||
</SheetTrigger>
|
||||
<SheetContent side="right">
|
||||
<div className="grid gap-6 pt-6">
|
||||
<div className="flex flex-col gap-4">
|
||||
{siteConfig.navMenuItems.map((item, index) => (
|
||||
<Link
|
||||
key={`${item}-${index}`}
|
||||
href={item.href}
|
||||
className="text-foreground text-lg font-medium"
|
||||
onClick={() => setIsMenuOpen(false)}
|
||||
>
|
||||
{item.label}
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</SheetContent>
|
||||
</Sheet>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
}
|
52
apps/app/src/app/(home)/hooks/use-home.ts
Normal file
52
apps/app/src/app/(home)/hooks/use-home.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { create } from 'zustand';
|
||||
import { getAllConfigs } from "@/http/endpoints";
|
||||
|
||||
interface Config {
|
||||
key: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
interface HomeStore {
|
||||
isLoading: boolean;
|
||||
checkHomePageAccess: () => Promise<boolean>;
|
||||
}
|
||||
|
||||
const useHomeStore = create<HomeStore>((set) => ({
|
||||
isLoading: true,
|
||||
checkHomePageAccess: async () => {
|
||||
try {
|
||||
const response = await getAllConfigs();
|
||||
const showHomePage = response.data.configs.find(
|
||||
(config: Config) => config.key === "showHomePage"
|
||||
)?.value === "true";
|
||||
|
||||
set({ isLoading: false });
|
||||
return showHomePage;
|
||||
} catch (error) {
|
||||
console.error("Failed to check homepage access:", error);
|
||||
set({ isLoading: false });
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
export function useHome() {
|
||||
const router = useRouter();
|
||||
const { isLoading, checkHomePageAccess } = useHomeStore();
|
||||
|
||||
useEffect(() => {
|
||||
checkHomePageAccess().then(hasAccess => {
|
||||
if (!hasAccess) {
|
||||
router.push("/login");
|
||||
}
|
||||
});
|
||||
}, [router, checkHomePageAccess]);
|
||||
|
||||
return {
|
||||
isLoading,
|
||||
};
|
||||
}
|
18
apps/app/src/app/(home)/layout.tsx
Normal file
18
apps/app/src/app/(home)/layout.tsx
Normal file
@@ -0,0 +1,18 @@
|
||||
import { Metadata } from 'next'
|
||||
import { getTranslations } from 'next-intl/server'
|
||||
|
||||
export async function generateMetadata(): Promise<Metadata> {
|
||||
const t = await getTranslations()
|
||||
|
||||
return {
|
||||
title: t('home.pageTitle'),
|
||||
}
|
||||
}
|
||||
|
||||
export default function HomeLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
}) {
|
||||
return <>{children}</>
|
||||
}
|
23
apps/app/src/app/(home)/page.tsx
Normal file
23
apps/app/src/app/(home)/page.tsx
Normal file
@@ -0,0 +1,23 @@
|
||||
"use client";
|
||||
|
||||
import { LoadingScreen } from "@/components/layout/loading-screen";
|
||||
import { DefaultFooter } from "@/components/ui/default-footer";
|
||||
import { HomeContent } from "./components/home-content";
|
||||
import { Navbar } from "./components/navbar";
|
||||
import { useHome } from "./hooks/use-home";
|
||||
|
||||
export default function HomePage() {
|
||||
const { isLoading } = useHome();
|
||||
|
||||
if (isLoading) {
|
||||
return <LoadingScreen />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="relative flex flex-col h-screen">
|
||||
<Navbar />
|
||||
<HomeContent isLoading={isLoading} />
|
||||
<DefaultFooter />
|
||||
</div>
|
||||
);
|
||||
}
|
7
apps/app/src/app/(home)/types/index.ts
Normal file
7
apps/app/src/app/(home)/types/index.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export interface HomeContentProps {
|
||||
isLoading: boolean;
|
||||
}
|
||||
|
||||
export interface HomeHeaderProps {
|
||||
title: string;
|
||||
}
|
BIN
apps/app/src/app/favicon.ico
Normal file
BIN
apps/app/src/app/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 165 KiB |
122
apps/app/src/app/globals.css
Normal file
122
apps/app/src/app/globals.css
Normal file
@@ -0,0 +1,122 @@
|
||||
@import "tailwindcss";
|
||||
@import "tw-animate-css";
|
||||
|
||||
@custom-variant dark (&:is(.dark *));
|
||||
|
||||
@theme inline {
|
||||
--color-background: var(--background);
|
||||
--color-foreground: var(--foreground);
|
||||
--font-sans: var(--font-geist-sans);
|
||||
--font-mono: var(--font-geist-mono);
|
||||
--color-sidebar-ring: var(--sidebar-ring);
|
||||
--color-sidebar-border: var(--sidebar-border);
|
||||
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
||||
--color-sidebar-accent: var(--sidebar-accent);
|
||||
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
||||
--color-sidebar-primary: var(--sidebar-primary);
|
||||
--color-sidebar-foreground: var(--sidebar-foreground);
|
||||
--color-sidebar: var(--sidebar);
|
||||
--color-chart-5: var(--chart-5);
|
||||
--color-chart-4: var(--chart-4);
|
||||
--color-chart-3: var(--chart-3);
|
||||
--color-chart-2: var(--chart-2);
|
||||
--color-chart-1: var(--chart-1);
|
||||
--color-ring: var(--ring);
|
||||
--color-input: var(--input);
|
||||
--color-border: var(--border);
|
||||
--color-destructive: var(--destructive);
|
||||
--color-accent-foreground: var(--accent-foreground);
|
||||
--color-accent: var(--accent);
|
||||
--color-muted-foreground: var(--muted-foreground);
|
||||
--color-muted: var(--muted);
|
||||
--color-secondary-foreground: var(--secondary-foreground);
|
||||
--color-secondary: var(--secondary);
|
||||
--color-primary-foreground: var(--primary-foreground);
|
||||
--color-primary: var(--primary);
|
||||
--color-popover-foreground: var(--popover-foreground);
|
||||
--color-popover: var(--popover);
|
||||
--color-card-foreground: var(--card-foreground);
|
||||
--color-card: var(--card);
|
||||
--radius-sm: calc(var(--radius) - 4px);
|
||||
--radius-md: calc(var(--radius) - 2px);
|
||||
--radius-lg: var(--radius);
|
||||
--radius-xl: calc(var(--radius) + 4px);
|
||||
}
|
||||
|
||||
:root {
|
||||
--radius: 0.75rem;
|
||||
--background: oklch(1 0 0);
|
||||
--foreground: oklch(0.141 0.005 285.823);
|
||||
--card: oklch(1 0 0);
|
||||
--card-foreground: oklch(0.141 0.005 285.823);
|
||||
--popover: oklch(1 0 0);
|
||||
--popover-foreground: oklch(0.141 0.005 285.823);
|
||||
--primary: oklch(0.723 0.219 149.579);
|
||||
--primary-foreground: oklch(0.982 0.018 155.826);
|
||||
--secondary: oklch(0.967 0.001 286.375);
|
||||
--secondary-foreground: oklch(0.21 0.006 285.885);
|
||||
--muted: oklch(0.967 0.001 286.375);
|
||||
--muted-foreground: oklch(0.552 0.016 285.938);
|
||||
--accent: oklch(0.967 0.001 286.375);
|
||||
--accent-foreground: oklch(0.21 0.006 285.885);
|
||||
--destructive: oklch(0.577 0.245 27.325);
|
||||
--border: oklch(0.92 0.004 286.32);
|
||||
--input: oklch(0.92 0.004 286.32);
|
||||
--ring: oklch(0.723 0.219 149.579);
|
||||
--chart-1: oklch(0.646 0.222 41.116);
|
||||
--chart-2: oklch(0.6 0.118 184.704);
|
||||
--chart-3: oklch(0.398 0.07 227.392);
|
||||
--chart-4: oklch(0.828 0.189 84.429);
|
||||
--chart-5: oklch(0.769 0.188 70.08);
|
||||
--sidebar: oklch(0.985 0 0);
|
||||
--sidebar-foreground: oklch(0.141 0.005 285.823);
|
||||
--sidebar-primary: oklch(0.723 0.219 149.579);
|
||||
--sidebar-primary-foreground: oklch(0.982 0.018 155.826);
|
||||
--sidebar-accent: oklch(0.967 0.001 286.375);
|
||||
--sidebar-accent-foreground: oklch(0.21 0.006 285.885);
|
||||
--sidebar-border: oklch(0.92 0.004 286.32);
|
||||
--sidebar-ring: oklch(0.723 0.219 149.579);
|
||||
}
|
||||
|
||||
.dark {
|
||||
--background: oklch(0.141 0.005 285.823);
|
||||
--foreground: oklch(0.985 0 0);
|
||||
--card: oklch(0.21 0.006 285.885);
|
||||
--card-foreground: oklch(0.985 0 0);
|
||||
--popover: oklch(0.21 0.006 285.885);
|
||||
--popover-foreground: oklch(0.985 0 0);
|
||||
--primary: oklch(0.696 0.17 162.48);
|
||||
--primary-foreground: oklch(0.393 0.095 152.535);
|
||||
--secondary: oklch(0.274 0.006 286.033);
|
||||
--secondary-foreground: oklch(0.985 0 0);
|
||||
--muted: oklch(0.274 0.006 286.033);
|
||||
--muted-foreground: oklch(0.705 0.015 286.067);
|
||||
--accent: oklch(0.274 0.006 286.033);
|
||||
--accent-foreground: oklch(0.985 0 0);
|
||||
--destructive: oklch(0.704 0.191 22.216);
|
||||
--border: oklch(1 0 0 / 10%);
|
||||
--input: oklch(1 0 0 / 15%);
|
||||
--ring: oklch(0.527 0.154 150.069);
|
||||
--chart-1: oklch(0.488 0.243 264.376);
|
||||
--chart-2: oklch(0.696 0.17 162.48);
|
||||
--chart-3: oklch(0.769 0.188 70.08);
|
||||
--chart-4: oklch(0.627 0.265 303.9);
|
||||
--chart-5: oklch(0.645 0.246 16.439);
|
||||
--sidebar: oklch(0.21 0.006 285.885);
|
||||
--sidebar-foreground: oklch(0.985 0 0);
|
||||
--sidebar-primary: oklch(0.696 0.17 162.48);
|
||||
--sidebar-primary-foreground: oklch(0.393 0.095 152.535);
|
||||
--sidebar-accent: oklch(0.274 0.006 286.033);
|
||||
--sidebar-accent-foreground: oklch(0.985 0 0);
|
||||
--sidebar-border: oklch(1 0 0 / 10%);
|
||||
--sidebar-ring: oklch(0.527 0.154 150.069);
|
||||
}
|
||||
|
||||
@layer base {
|
||||
* {
|
||||
@apply border-border outline-ring/50;
|
||||
}
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
}
|
||||
}
|
52
apps/app/src/app/layout.tsx
Normal file
52
apps/app/src/app/layout.tsx
Normal file
@@ -0,0 +1,52 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Geist, Geist_Mono } from "next/font/google";
|
||||
import { NextIntlClientProvider } from "next-intl";
|
||||
import { getLocale } from "next-intl/server";
|
||||
|
||||
import "./globals.css";
|
||||
|
||||
import { useAppInfo } from "@/contexts/app-info-context";
|
||||
import { ThemeProvider } from "../providers/theme-provider";
|
||||
import { AuthProvider } from "@/contexts/auth-context";
|
||||
|
||||
const geistSans = Geist({
|
||||
variable: "--font-geist-sans",
|
||||
subsets: ["latin"],
|
||||
});
|
||||
|
||||
const geistMono = Geist_Mono({
|
||||
variable: "--font-geist-mono",
|
||||
subsets: ["latin"],
|
||||
});
|
||||
|
||||
// !TODO: CHANGE METADATA BASED ON API RESPONSE
|
||||
export const metadata: Metadata = {
|
||||
title: "Create Next App",
|
||||
description: "Generated by create next app",
|
||||
};
|
||||
|
||||
export default async function RootLayout({
|
||||
children,
|
||||
}: Readonly<{
|
||||
children: React.ReactNode;
|
||||
}>) {
|
||||
const locale = await getLocale();
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
useAppInfo.getState().refreshAppInfo();
|
||||
}
|
||||
|
||||
return (
|
||||
<html lang={locale} suppressHydrationWarning>
|
||||
<body className={`${geistSans.variable} ${geistMono.variable} antialiased`}>
|
||||
<NextIntlClientProvider>
|
||||
<ThemeProvider attribute="class" defaultTheme="system" enableSystem disableTransitionOnChange>
|
||||
<AuthProvider>
|
||||
{children}
|
||||
</AuthProvider>
|
||||
</ThemeProvider>
|
||||
</NextIntlClientProvider>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
112
apps/app/src/app/login/components/login-form.tsx
Normal file
112
apps/app/src/app/login/components/login-form.tsx
Normal file
@@ -0,0 +1,112 @@
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
||||
import Link from "next/link";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { createLoginSchema, type LoginFormValues } from "../schemas/schema";
|
||||
import { PasswordVisibilityToggle } from "./password-visibility-toggle";
|
||||
|
||||
interface LoginFormProps {
|
||||
error?: string;
|
||||
isVisible: boolean;
|
||||
onToggleVisibility: () => void;
|
||||
onSubmit: (data: LoginFormValues) => Promise<void>;
|
||||
}
|
||||
|
||||
export function LoginForm({ error, isVisible, onToggleVisibility, onSubmit }: LoginFormProps) {
|
||||
const t = useTranslations();
|
||||
const loginSchema = createLoginSchema(t);
|
||||
const form = useForm<LoginFormValues>({
|
||||
resolver: zodResolver(loginSchema),
|
||||
defaultValues: {
|
||||
email: "",
|
||||
password: "",
|
||||
},
|
||||
});
|
||||
|
||||
const isSubmitting = form.formState.isSubmitting;
|
||||
|
||||
const renderErrorMessage = () => (
|
||||
error && (
|
||||
<p className="text-destructive text-sm text-center bg-destructive/10 p-2 rounded-md">
|
||||
{error.replace('errors.', '')}
|
||||
</p>
|
||||
)
|
||||
);
|
||||
|
||||
const renderEmailField = () => (
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="email"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>{t("login.emailLabel")}</FormLabel>
|
||||
<FormControl className="-mb-1">
|
||||
<Input
|
||||
{...field}
|
||||
type="email"
|
||||
placeholder={t("login.emailPlaceholder")}
|
||||
disabled={isSubmitting}
|
||||
className="bg-transparent backdrop-blur-md"
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
|
||||
const renderPasswordField = () => (
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="password"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>{t("login.passwordLabel")}</FormLabel>
|
||||
<FormControl>
|
||||
<div className="relative">
|
||||
<Input
|
||||
{...field}
|
||||
type={isVisible ? "text" : "password"}
|
||||
placeholder={t("login.passwordPlaceholder")}
|
||||
disabled={isSubmitting}
|
||||
className="bg-transparent backdrop-blur-md pr-10"
|
||||
/>
|
||||
<PasswordVisibilityToggle
|
||||
isVisible={isVisible}
|
||||
onToggle={onToggleVisibility}
|
||||
/>
|
||||
</div>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
{renderErrorMessage()}
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className="flex flex-col gap-4">
|
||||
{renderEmailField()}
|
||||
{renderPasswordField()}
|
||||
<Button className="w-full mt-4 cursor-pointer" variant="default" size="lg" type="submit">
|
||||
{isSubmitting ? t("login.signingIn") : t("login.signIn")}
|
||||
</Button>
|
||||
</form>
|
||||
</Form>
|
||||
|
||||
<div className="flex w-full items-center justify-center px-1 mt-2">
|
||||
<Link
|
||||
className="text-muted-foreground hover:text-primary text-sm"
|
||||
href="/forgot-password"
|
||||
>
|
||||
{t("login.forgotPassword")}
|
||||
</Link>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
26
apps/app/src/app/login/components/login-header.tsx
Normal file
26
apps/app/src/app/login/components/login-header.tsx
Normal file
@@ -0,0 +1,26 @@
|
||||
import { useAppInfo } from "@/contexts/app-info-context";
|
||||
import { motion } from "framer-motion";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useEffect } from "react";
|
||||
|
||||
|
||||
export function LoginHeader() {
|
||||
const t = useTranslations();
|
||||
const { appName, refreshAppInfo } = useAppInfo();
|
||||
|
||||
useEffect(() => {
|
||||
refreshAppInfo();
|
||||
}, [refreshAppInfo]);
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
animate={{ opacity: 1 }}
|
||||
className="flex flex-col gap-1 flex-1 items-center justify-center text-center text-default-500 mb-4"
|
||||
initial={{ opacity: 0 }}
|
||||
transition={{ delay: 0.2, duration: 0.5 }}
|
||||
>
|
||||
<h1 className="text-2xl font-semibold tracking-tight text-center">{t("login.welcome")} {appName}</h1>
|
||||
<p className="text-default-500 text-sm">{t("login.signInToContinue")}</p>
|
||||
</motion.div>
|
||||
);
|
||||
}
|
@@ -0,0 +1,24 @@
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { IconEye, IconEyeClosed } from "@tabler/icons-react";
|
||||
|
||||
interface PasswordVisibilityToggleProps {
|
||||
isVisible: boolean;
|
||||
onToggle: () => void;
|
||||
}
|
||||
|
||||
export function PasswordVisibilityToggle({ isVisible, onToggle }: PasswordVisibilityToggleProps) {
|
||||
return (
|
||||
<Button
|
||||
type="button"
|
||||
variant="link"
|
||||
onClick={onToggle}
|
||||
className="absolute right-0 top-1/2 -translate-y-1/2 cursor-pointer"
|
||||
>
|
||||
{isVisible ? (
|
||||
<IconEye className="h-5 w-5 text-muted-foreground" />
|
||||
) : (
|
||||
<IconEyeClosed className="h-5 w-5 text-muted-foreground" />
|
||||
)}
|
||||
</Button>
|
||||
);
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
export const StaticBackgroundLights = () => {
|
||||
return (
|
||||
<div className="absolute inset-0 -z-10 overflow-hidden">
|
||||
<div className="absolute -top-[20%] -left-[20%] w-[140%] h-[140%] bg-[radial-gradient(circle,rgba(34,197,94,0.08)_0%,transparent_70%)] dark:opacity-70 opacity-30" />
|
||||
<div className="absolute -bottom-[20%] -right-[20%] w-[140%] h-[140%] bg-[radial-gradient(circle,rgba(34,197,94,0.08)_0%,transparent_70%)] dark:opacity-70 opacity-30" />
|
||||
</div>
|
||||
);
|
||||
};
|
77
apps/app/src/app/login/hooks/use-login.ts
Normal file
77
apps/app/src/app/login/hooks/use-login.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
"use client"
|
||||
|
||||
import { useAuth } from "@/contexts/auth-context";
|
||||
import { login, getCurrentUser } from "@/http/endpoints";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState, useEffect } from "react";
|
||||
import axios from "axios";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { LoginFormValues } from "../schemas/schema";
|
||||
|
||||
export function useLogin() {
|
||||
const router = useRouter();
|
||||
const t = useTranslations();
|
||||
const { isAuthenticated, setUser, setIsAdmin, setIsAuthenticated } = useAuth();
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
const [error, setError] = useState<string | undefined>();
|
||||
const [isInitialized, setIsInitialized] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const checkAuth = async () => {
|
||||
try {
|
||||
const userResponse = await getCurrentUser();
|
||||
if (!userResponse?.data?.user) {
|
||||
throw new Error("No user data");
|
||||
}
|
||||
|
||||
const { isAdmin, ...userData } = userResponse.data.user;
|
||||
setUser(userData);
|
||||
setIsAdmin(isAdmin);
|
||||
setIsAuthenticated(true);
|
||||
router.push("/dashboard");
|
||||
} catch (err) {
|
||||
setUser(null);
|
||||
setIsAdmin(false);
|
||||
setIsAuthenticated(false);
|
||||
} finally {
|
||||
setIsInitialized(true);
|
||||
}
|
||||
};
|
||||
|
||||
checkAuth();
|
||||
}, [router, setUser, setIsAdmin, setIsAuthenticated]);
|
||||
|
||||
const toggleVisibility = () => setIsVisible(!isVisible);
|
||||
|
||||
const onSubmit = async (data: LoginFormValues) => {
|
||||
setError(undefined);
|
||||
|
||||
try {
|
||||
await login(data);
|
||||
const userResponse = await getCurrentUser();
|
||||
const { isAdmin, ...userData } = userResponse.data.user;
|
||||
|
||||
setUser(userData);
|
||||
setIsAdmin(isAdmin);
|
||||
setIsAuthenticated(true);
|
||||
router.replace("/dashboard");
|
||||
} catch (err) {
|
||||
if (axios.isAxiosError(err) && err.response?.data?.error) {
|
||||
setError(t(`errors.${err.response.data.error}`));
|
||||
} else {
|
||||
setError(t("errors.unexpectedError"));
|
||||
}
|
||||
setIsAuthenticated(false);
|
||||
setUser(null);
|
||||
setIsAdmin(false);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
isAuthenticated: !isInitialized ? null : isAuthenticated,
|
||||
error,
|
||||
isVisible,
|
||||
toggleVisibility,
|
||||
onSubmit,
|
||||
};
|
||||
}
|
18
apps/app/src/app/login/layout.tsx
Normal file
18
apps/app/src/app/login/layout.tsx
Normal file
@@ -0,0 +1,18 @@
|
||||
import { Metadata } from 'next'
|
||||
import { getTranslations } from 'next-intl/server'
|
||||
|
||||
interface LayoutProps {
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
export async function generateMetadata(): Promise<Metadata> {
|
||||
const translate = await getTranslations()
|
||||
|
||||
return {
|
||||
title: translate('login.pageTitle'),
|
||||
}
|
||||
}
|
||||
|
||||
export default function LoginLayout({ children }: LayoutProps) {
|
||||
return <>{children}</>
|
||||
}
|
47
apps/app/src/app/login/page.tsx
Normal file
47
apps/app/src/app/login/page.tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
"use client"
|
||||
|
||||
import { LoginForm } from "./components/login-form";
|
||||
import { LoginHeader } from "./components/login-header";
|
||||
import { StaticBackgroundLights } from "./components/static-background-lights";
|
||||
import { useLogin } from "./hooks/use-login";
|
||||
import { LoadingScreen } from "@/components/layout/loading-screen";
|
||||
import { DefaultFooter } from "@/components/ui/default-footer";
|
||||
import { motion } from "framer-motion";
|
||||
import { LanguageSwitcher } from "@/components/general/language-switcher";
|
||||
|
||||
export default function LoginPage() {
|
||||
const login = useLogin();
|
||||
|
||||
if (login.isAuthenticated === null) {
|
||||
return <LoadingScreen />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="relative flex flex-col h-screen">
|
||||
<div className="fixed top-4 right-4 z-50">
|
||||
<LanguageSwitcher />
|
||||
</div>
|
||||
|
||||
<div className="container mx-auto max-w-7xl px-6 flex-grow">
|
||||
<StaticBackgroundLights />
|
||||
<div className="relative flex h-full w-full items-center justify-center">
|
||||
<motion.div
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
className="flex w-full max-w-sm flex-col gap-4 rounded-lg bg-background/80 backdrop-blur-md px-8 pb-10 pt-6 shadow-lg"
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
transition={{ duration: 0.5 }}
|
||||
>
|
||||
<LoginHeader />
|
||||
<LoginForm
|
||||
error={login.error}
|
||||
isVisible={login.isVisible}
|
||||
onSubmit={login.onSubmit}
|
||||
onToggleVisibility={login.toggleVisibility}
|
||||
/>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
<DefaultFooter />
|
||||
</div>
|
||||
);
|
||||
}
|
17
apps/app/src/app/login/schemas/schema.ts
Normal file
17
apps/app/src/app/login/schemas/schema.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import * as z from "zod";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
type TFunction = ReturnType<typeof useTranslations>;
|
||||
|
||||
export const createLoginSchema = (t: TFunction) =>
|
||||
z.object({
|
||||
email: z
|
||||
.string()
|
||||
.min(1, t("validation.emailRequired"))
|
||||
.email(t("validation.invalidEmail")),
|
||||
password: z
|
||||
.string()
|
||||
.min(1, t("validation.passwordRequired"))
|
||||
});
|
||||
|
||||
export type LoginFormValues = z.infer<ReturnType<typeof createLoginSchema>>;
|
10
apps/app/src/app/login/types/index.ts
Normal file
10
apps/app/src/app/login/types/index.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { LoginFormData } from "../hooks/use-login";
|
||||
import { UseFormReturn } from "react-hook-form";
|
||||
|
||||
export interface LoginFormProps {
|
||||
form: UseFormReturn<LoginFormData>;
|
||||
error: string | null;
|
||||
isVisible: boolean;
|
||||
onToggleVisibility: () => void;
|
||||
onSubmit: (data: LoginFormData) => Promise<void>;
|
||||
}
|
82
apps/app/src/components/general/language-switcher.tsx
Normal file
82
apps/app/src/components/general/language-switcher.tsx
Normal file
@@ -0,0 +1,82 @@
|
||||
import { useRouter } from "next/navigation";
|
||||
import { IconLanguage } from "@tabler/icons-react";
|
||||
import { useLocale } from "next-intl";
|
||||
import { setCookie } from "nookies";
|
||||
import ReactCountryFlag from "react-country-flag";
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
|
||||
const languages = {
|
||||
"en-US": "English",
|
||||
"pt-BR": "Português",
|
||||
"fr-FR": "Français",
|
||||
"es-ES": "Español",
|
||||
"de-DE": "Deutsch",
|
||||
"tr-TR": "Türkçe (Turkish)",
|
||||
"ru-RU": "Русский (Russian)",
|
||||
"hi-IN": "हिन्दी (Hindi)",
|
||||
"ar-SA": "العربية (Arabic)",
|
||||
"zh-CN": "中文 (Chinese)",
|
||||
"ja-JP": "日本語 (Japanese)",
|
||||
"ko-KR": "한국어 (Korean)",
|
||||
};
|
||||
|
||||
const COOKIE_LANG_KEY = "NEXT_LOCALE";
|
||||
const COOKIE_MAX_AGE = 365 * 24 * 60 * 60;
|
||||
|
||||
export function LanguageSwitcher() {
|
||||
const locale = useLocale();
|
||||
const router = useRouter();
|
||||
|
||||
const changeLanguage = (fullLocale: string) => {
|
||||
setCookie(null, COOKIE_LANG_KEY, fullLocale, {
|
||||
maxAge: COOKIE_MAX_AGE,
|
||||
path: "/",
|
||||
sameSite: "lax",
|
||||
secure: process.env.NODE_ENV === "production",
|
||||
});
|
||||
|
||||
router.refresh();
|
||||
};
|
||||
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="ghost" size="icon" className="h-9 w-9 p-0">
|
||||
<IconLanguage className="h-5 w-5" />
|
||||
<span className="sr-only">Change language</span>
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
{Object.entries(languages).map(([code, name]) => {
|
||||
const isCurrentLocale = locale === code.split("-")[0];
|
||||
|
||||
return (
|
||||
<DropdownMenuItem
|
||||
key={code}
|
||||
onClick={() => changeLanguage(code)}
|
||||
className={isCurrentLocale ? "bg-accent" : ""}
|
||||
>
|
||||
<ReactCountryFlag
|
||||
svg
|
||||
countryCode={code.split("-")[1]}
|
||||
style={{
|
||||
marginRight: "8px",
|
||||
width: "1em",
|
||||
height: "1em",
|
||||
}}
|
||||
/>
|
||||
{name}
|
||||
</DropdownMenuItem>
|
||||
);
|
||||
})}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
);
|
||||
}
|
27
apps/app/src/components/layout/loading-screen.tsx
Normal file
27
apps/app/src/components/layout/loading-screen.tsx
Normal file
@@ -0,0 +1,27 @@
|
||||
import { motion } from "framer-motion";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
import { BackgroundLights } from "@/components/ui/background-lights";
|
||||
|
||||
export function LoadingScreen() {
|
||||
const t = useTranslations();
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 bg-background">
|
||||
<BackgroundLights />
|
||||
<div className="relative flex flex-col items-center justify-center h-full">
|
||||
<motion.div
|
||||
animate={{ scale: [1, 1.1, 1] }}
|
||||
className="flex flex-col items-center gap-4"
|
||||
transition={{
|
||||
duration: 1.5,
|
||||
repeat: Infinity,
|
||||
ease: "easeInOut",
|
||||
}}
|
||||
>
|
||||
<span className="text-xl font-semibold text-primary">{t("common.loading")}</span>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
35
apps/app/src/components/mode-toggle.tsx
Normal file
35
apps/app/src/components/mode-toggle.tsx
Normal file
@@ -0,0 +1,35 @@
|
||||
// !!TODO: ADD TRANSLATION SUPPORT FOR THESE BUTTONS
|
||||
"use client";
|
||||
|
||||
import * as React from "react";
|
||||
import { IconMoon, IconSun } from "@tabler/icons-react";
|
||||
import { useTheme } from "next-themes";
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
|
||||
export function ModeToggle() {
|
||||
const { setTheme } = useTheme();
|
||||
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="ghost" size="icon">
|
||||
<IconSun className="h-4 w-4 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
|
||||
<IconMoon className="absolute h-4 w-4 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
|
||||
<span className="sr-only">Toggle theme</span>
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
<DropdownMenuItem onClick={() => setTheme("light")}>Light</DropdownMenuItem>
|
||||
<DropdownMenuItem onClick={() => setTheme("dark")}>Dark</DropdownMenuItem>
|
||||
<DropdownMenuItem onClick={() => setTheme("system")}>System</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
);
|
||||
}
|
33
apps/app/src/components/ui/background-lights.tsx
Normal file
33
apps/app/src/components/ui/background-lights.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
export function BackgroundLights() {
|
||||
return (
|
||||
<div className="absolute inset-0 -z-10 overflow-hidden">
|
||||
<motion.div
|
||||
animate={{
|
||||
scale: [1, 1.1, 1],
|
||||
opacity: [0.3, 0.5, 0.3],
|
||||
}}
|
||||
className="absolute -top-[20%] -left-[20%] w-[140%] h-[140%] bg-[radial-gradient(circle,rgba(34,197,94,0.15)_0%,transparent_70%)] dark:opacity-100 opacity-50"
|
||||
transition={{
|
||||
duration: 5,
|
||||
repeat: Infinity,
|
||||
ease: "easeInOut",
|
||||
}}
|
||||
/>
|
||||
<motion.div
|
||||
animate={{
|
||||
scale: [1, 1.1, 1],
|
||||
opacity: [0.3, 0.5, 0.3],
|
||||
}}
|
||||
className="absolute -bottom-[20%] -right-[20%] w-[140%] h-[140%] bg-[radial-gradient(circle,rgba(34,197,94,0.15)_0%,transparent_70%)] dark:opacity-100 opacity-50"
|
||||
transition={{
|
||||
duration: 5,
|
||||
repeat: Infinity,
|
||||
ease: "easeInOut",
|
||||
delay: 2.5,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
59
apps/app/src/components/ui/button.tsx
Normal file
59
apps/app/src/components/ui/button.tsx
Normal file
@@ -0,0 +1,59 @@
|
||||
import * as React from "react"
|
||||
import { Slot } from "@radix-ui/react-slot"
|
||||
import { cva, type VariantProps } from "class-variance-authority"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
const buttonVariants = cva(
|
||||
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
default:
|
||||
"bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
|
||||
destructive:
|
||||
"bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
|
||||
outline:
|
||||
"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
|
||||
secondary:
|
||||
"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
|
||||
ghost:
|
||||
"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
|
||||
link: "text-primary underline-offset-4 hover:underline",
|
||||
},
|
||||
size: {
|
||||
default: "h-9 px-4 py-2 has-[>svg]:px-3",
|
||||
sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
|
||||
lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
|
||||
icon: "size-9",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: "default",
|
||||
size: "default",
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
function Button({
|
||||
className,
|
||||
variant,
|
||||
size,
|
||||
asChild = false,
|
||||
...props
|
||||
}: React.ComponentProps<"button"> &
|
||||
VariantProps<typeof buttonVariants> & {
|
||||
asChild?: boolean
|
||||
}) {
|
||||
const Comp = asChild ? Slot : "button"
|
||||
|
||||
return (
|
||||
<Comp
|
||||
data-slot="button"
|
||||
className={cn(buttonVariants({ variant, size, className }))}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export { Button, buttonVariants }
|
25
apps/app/src/components/ui/default-footer.tsx
Normal file
25
apps/app/src/components/ui/default-footer.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import Link from "next/link";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
import { version } from "../../../package.json";
|
||||
|
||||
export function DefaultFooter() {
|
||||
const t = useTranslations();
|
||||
|
||||
return (
|
||||
<footer className="w-full flex items-center justify-center py-3 h-16">
|
||||
<div className="flex flex-col items-center">
|
||||
<Link
|
||||
target="_blank"
|
||||
className="flex items-center gap-1 text-current"
|
||||
href="https://kyantech.com.br"
|
||||
title={t("footer.kyanHomepage")}
|
||||
>
|
||||
<span className="text-default-600 text-xs sm:text-sm">{t("footer.poweredBy")}</span>
|
||||
<p className="text-green-700 text-xs sm:text-sm">Kyantech Solutions</p>
|
||||
</Link>
|
||||
<span className="text-default-500 text-[11px] mt-1">v{version}-beta</span>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
}
|
257
apps/app/src/components/ui/dropdown-menu.tsx
Normal file
257
apps/app/src/components/ui/dropdown-menu.tsx
Normal file
@@ -0,0 +1,257 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"
|
||||
import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
function DropdownMenu({
|
||||
...props
|
||||
}: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {
|
||||
return <DropdownMenuPrimitive.Root data-slot="dropdown-menu" {...props} />
|
||||
}
|
||||
|
||||
function DropdownMenuPortal({
|
||||
...props
|
||||
}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {
|
||||
return (
|
||||
<DropdownMenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />
|
||||
)
|
||||
}
|
||||
|
||||
function DropdownMenuTrigger({
|
||||
...props
|
||||
}: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {
|
||||
return (
|
||||
<DropdownMenuPrimitive.Trigger
|
||||
data-slot="dropdown-menu-trigger"
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
function DropdownMenuContent({
|
||||
className,
|
||||
sideOffset = 4,
|
||||
...props
|
||||
}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {
|
||||
return (
|
||||
<DropdownMenuPrimitive.Portal>
|
||||
<DropdownMenuPrimitive.Content
|
||||
data-slot="dropdown-menu-content"
|
||||
sideOffset={sideOffset}
|
||||
className={cn(
|
||||
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
</DropdownMenuPrimitive.Portal>
|
||||
)
|
||||
}
|
||||
|
||||
function DropdownMenuGroup({
|
||||
...props
|
||||
}: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {
|
||||
return (
|
||||
<DropdownMenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />
|
||||
)
|
||||
}
|
||||
|
||||
function DropdownMenuItem({
|
||||
className,
|
||||
inset,
|
||||
variant = "default",
|
||||
...props
|
||||
}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {
|
||||
inset?: boolean
|
||||
variant?: "default" | "destructive"
|
||||
}) {
|
||||
return (
|
||||
<DropdownMenuPrimitive.Item
|
||||
data-slot="dropdown-menu-item"
|
||||
data-inset={inset}
|
||||
data-variant={variant}
|
||||
className={cn(
|
||||
"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
function DropdownMenuCheckboxItem({
|
||||
className,
|
||||
children,
|
||||
checked,
|
||||
...props
|
||||
}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {
|
||||
return (
|
||||
<DropdownMenuPrimitive.CheckboxItem
|
||||
data-slot="dropdown-menu-checkbox-item"
|
||||
className={cn(
|
||||
"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
||||
className
|
||||
)}
|
||||
checked={checked}
|
||||
{...props}
|
||||
>
|
||||
<span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
|
||||
<DropdownMenuPrimitive.ItemIndicator>
|
||||
<CheckIcon className="size-4" />
|
||||
</DropdownMenuPrimitive.ItemIndicator>
|
||||
</span>
|
||||
{children}
|
||||
</DropdownMenuPrimitive.CheckboxItem>
|
||||
)
|
||||
}
|
||||
|
||||
function DropdownMenuRadioGroup({
|
||||
...props
|
||||
}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {
|
||||
return (
|
||||
<DropdownMenuPrimitive.RadioGroup
|
||||
data-slot="dropdown-menu-radio-group"
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
function DropdownMenuRadioItem({
|
||||
className,
|
||||
children,
|
||||
...props
|
||||
}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {
|
||||
return (
|
||||
<DropdownMenuPrimitive.RadioItem
|
||||
data-slot="dropdown-menu-radio-item"
|
||||
className={cn(
|
||||
"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
|
||||
<DropdownMenuPrimitive.ItemIndicator>
|
||||
<CircleIcon className="size-2 fill-current" />
|
||||
</DropdownMenuPrimitive.ItemIndicator>
|
||||
</span>
|
||||
{children}
|
||||
</DropdownMenuPrimitive.RadioItem>
|
||||
)
|
||||
}
|
||||
|
||||
function DropdownMenuLabel({
|
||||
className,
|
||||
inset,
|
||||
...props
|
||||
}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {
|
||||
inset?: boolean
|
||||
}) {
|
||||
return (
|
||||
<DropdownMenuPrimitive.Label
|
||||
data-slot="dropdown-menu-label"
|
||||
data-inset={inset}
|
||||
className={cn(
|
||||
"px-2 py-1.5 text-sm font-medium data-[inset]:pl-8",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
function DropdownMenuSeparator({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {
|
||||
return (
|
||||
<DropdownMenuPrimitive.Separator
|
||||
data-slot="dropdown-menu-separator"
|
||||
className={cn("bg-border -mx-1 my-1 h-px", className)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
function DropdownMenuShortcut({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<"span">) {
|
||||
return (
|
||||
<span
|
||||
data-slot="dropdown-menu-shortcut"
|
||||
className={cn(
|
||||
"text-muted-foreground ml-auto text-xs tracking-widest",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
function DropdownMenuSub({
|
||||
...props
|
||||
}: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {
|
||||
return <DropdownMenuPrimitive.Sub data-slot="dropdown-menu-sub" {...props} />
|
||||
}
|
||||
|
||||
function DropdownMenuSubTrigger({
|
||||
className,
|
||||
inset,
|
||||
children,
|
||||
...props
|
||||
}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {
|
||||
inset?: boolean
|
||||
}) {
|
||||
return (
|
||||
<DropdownMenuPrimitive.SubTrigger
|
||||
data-slot="dropdown-menu-sub-trigger"
|
||||
data-inset={inset}
|
||||
className={cn(
|
||||
"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
<ChevronRightIcon className="ml-auto size-4" />
|
||||
</DropdownMenuPrimitive.SubTrigger>
|
||||
)
|
||||
}
|
||||
|
||||
function DropdownMenuSubContent({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {
|
||||
return (
|
||||
<DropdownMenuPrimitive.SubContent
|
||||
data-slot="dropdown-menu-sub-content"
|
||||
className={cn(
|
||||
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export {
|
||||
DropdownMenu,
|
||||
DropdownMenuPortal,
|
||||
DropdownMenuTrigger,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuGroup,
|
||||
DropdownMenuLabel,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuCheckboxItem,
|
||||
DropdownMenuRadioGroup,
|
||||
DropdownMenuRadioItem,
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuShortcut,
|
||||
DropdownMenuSub,
|
||||
DropdownMenuSubTrigger,
|
||||
DropdownMenuSubContent,
|
||||
}
|
167
apps/app/src/components/ui/form.tsx
Normal file
167
apps/app/src/components/ui/form.tsx
Normal file
@@ -0,0 +1,167 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import * as LabelPrimitive from "@radix-ui/react-label"
|
||||
import { Slot } from "@radix-ui/react-slot"
|
||||
import {
|
||||
Controller,
|
||||
FormProvider,
|
||||
useFormContext,
|
||||
useFormState,
|
||||
type ControllerProps,
|
||||
type FieldPath,
|
||||
type FieldValues,
|
||||
} from "react-hook-form"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
import { Label } from "@/components/ui/label"
|
||||
|
||||
const Form = FormProvider
|
||||
|
||||
type FormFieldContextValue<
|
||||
TFieldValues extends FieldValues = FieldValues,
|
||||
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
|
||||
> = {
|
||||
name: TName
|
||||
}
|
||||
|
||||
const FormFieldContext = React.createContext<FormFieldContextValue>(
|
||||
{} as FormFieldContextValue
|
||||
)
|
||||
|
||||
const FormField = <
|
||||
TFieldValues extends FieldValues = FieldValues,
|
||||
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
|
||||
>({
|
||||
...props
|
||||
}: ControllerProps<TFieldValues, TName>) => {
|
||||
return (
|
||||
<FormFieldContext.Provider value={{ name: props.name }}>
|
||||
<Controller {...props} />
|
||||
</FormFieldContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
const useFormField = () => {
|
||||
const fieldContext = React.useContext(FormFieldContext)
|
||||
const itemContext = React.useContext(FormItemContext)
|
||||
const { getFieldState } = useFormContext()
|
||||
const formState = useFormState({ name: fieldContext.name })
|
||||
const fieldState = getFieldState(fieldContext.name, formState)
|
||||
|
||||
if (!fieldContext) {
|
||||
throw new Error("useFormField should be used within <FormField>")
|
||||
}
|
||||
|
||||
const { id } = itemContext
|
||||
|
||||
return {
|
||||
id,
|
||||
name: fieldContext.name,
|
||||
formItemId: `${id}-form-item`,
|
||||
formDescriptionId: `${id}-form-item-description`,
|
||||
formMessageId: `${id}-form-item-message`,
|
||||
...fieldState,
|
||||
}
|
||||
}
|
||||
|
||||
type FormItemContextValue = {
|
||||
id: string
|
||||
}
|
||||
|
||||
const FormItemContext = React.createContext<FormItemContextValue>(
|
||||
{} as FormItemContextValue
|
||||
)
|
||||
|
||||
function FormItem({ className, ...props }: React.ComponentProps<"div">) {
|
||||
const id = React.useId()
|
||||
|
||||
return (
|
||||
<FormItemContext.Provider value={{ id }}>
|
||||
<div
|
||||
data-slot="form-item"
|
||||
className={cn("grid gap-2", className)}
|
||||
{...props}
|
||||
/>
|
||||
</FormItemContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
function FormLabel({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<typeof LabelPrimitive.Root>) {
|
||||
const { error, formItemId } = useFormField()
|
||||
|
||||
return (
|
||||
<Label
|
||||
data-slot="form-label"
|
||||
data-error={!!error}
|
||||
className={cn("data-[error=true]:text-destructive", className)}
|
||||
htmlFor={formItemId}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
function FormControl({ ...props }: React.ComponentProps<typeof Slot>) {
|
||||
const { error, formItemId, formDescriptionId, formMessageId } = useFormField()
|
||||
|
||||
return (
|
||||
<Slot
|
||||
data-slot="form-control"
|
||||
id={formItemId}
|
||||
aria-describedby={
|
||||
!error
|
||||
? `${formDescriptionId}`
|
||||
: `${formDescriptionId} ${formMessageId}`
|
||||
}
|
||||
aria-invalid={!!error}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
function FormDescription({ className, ...props }: React.ComponentProps<"p">) {
|
||||
const { formDescriptionId } = useFormField()
|
||||
|
||||
return (
|
||||
<p
|
||||
data-slot="form-description"
|
||||
id={formDescriptionId}
|
||||
className={cn("text-muted-foreground text-sm", className)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
function FormMessage({ className, ...props }: React.ComponentProps<"p">) {
|
||||
const { error, formMessageId } = useFormField()
|
||||
const body = error ? String(error?.message ?? "") : props.children
|
||||
|
||||
if (!body) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<p
|
||||
data-slot="form-message"
|
||||
id={formMessageId}
|
||||
className={cn("text-destructive text-xs", className)}
|
||||
{...props}
|
||||
>
|
||||
{body}
|
||||
</p>
|
||||
)
|
||||
}
|
||||
|
||||
export {
|
||||
useFormField,
|
||||
Form,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormControl,
|
||||
FormDescription,
|
||||
FormMessage,
|
||||
FormField,
|
||||
}
|
21
apps/app/src/components/ui/input.tsx
Normal file
21
apps/app/src/components/ui/input.tsx
Normal file
@@ -0,0 +1,21 @@
|
||||
import * as React from "react"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
function Input({ className, type, ...props }: React.ComponentProps<"input">) {
|
||||
return (
|
||||
<input
|
||||
type={type}
|
||||
data-slot="input"
|
||||
className={cn(
|
||||
"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
||||
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
||||
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export { Input }
|
24
apps/app/src/components/ui/label.tsx
Normal file
24
apps/app/src/components/ui/label.tsx
Normal file
@@ -0,0 +1,24 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import * as LabelPrimitive from "@radix-ui/react-label"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
function Label({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<typeof LabelPrimitive.Root>) {
|
||||
return (
|
||||
<LabelPrimitive.Root
|
||||
data-slot="label"
|
||||
className={cn(
|
||||
"flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export { Label }
|
139
apps/app/src/components/ui/sheet.tsx
Normal file
139
apps/app/src/components/ui/sheet.tsx
Normal file
@@ -0,0 +1,139 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import * as SheetPrimitive from "@radix-ui/react-dialog"
|
||||
import { XIcon } from "lucide-react"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
function Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {
|
||||
return <SheetPrimitive.Root data-slot="sheet" {...props} />
|
||||
}
|
||||
|
||||
function SheetTrigger({
|
||||
...props
|
||||
}: React.ComponentProps<typeof SheetPrimitive.Trigger>) {
|
||||
return <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} />
|
||||
}
|
||||
|
||||
function SheetClose({
|
||||
...props
|
||||
}: React.ComponentProps<typeof SheetPrimitive.Close>) {
|
||||
return <SheetPrimitive.Close data-slot="sheet-close" {...props} />
|
||||
}
|
||||
|
||||
function SheetPortal({
|
||||
...props
|
||||
}: React.ComponentProps<typeof SheetPrimitive.Portal>) {
|
||||
return <SheetPrimitive.Portal data-slot="sheet-portal" {...props} />
|
||||
}
|
||||
|
||||
function SheetOverlay({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<typeof SheetPrimitive.Overlay>) {
|
||||
return (
|
||||
<SheetPrimitive.Overlay
|
||||
data-slot="sheet-overlay"
|
||||
className={cn(
|
||||
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
function SheetContent({
|
||||
className,
|
||||
children,
|
||||
side = "right",
|
||||
...props
|
||||
}: React.ComponentProps<typeof SheetPrimitive.Content> & {
|
||||
side?: "top" | "right" | "bottom" | "left"
|
||||
}) {
|
||||
return (
|
||||
<SheetPortal>
|
||||
<SheetOverlay />
|
||||
<SheetPrimitive.Content
|
||||
data-slot="sheet-content"
|
||||
className={cn(
|
||||
"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
|
||||
side === "right" &&
|
||||
"data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm",
|
||||
side === "left" &&
|
||||
"data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm",
|
||||
side === "top" &&
|
||||
"data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b",
|
||||
side === "bottom" &&
|
||||
"data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 h-auto border-t",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
<SheetPrimitive.Close className="ring-offset-background focus:ring-ring data-[state=open]:bg-secondary absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none">
|
||||
<XIcon className="size-4" />
|
||||
<span className="sr-only">Close</span>
|
||||
</SheetPrimitive.Close>
|
||||
</SheetPrimitive.Content>
|
||||
</SheetPortal>
|
||||
)
|
||||
}
|
||||
|
||||
function SheetHeader({ className, ...props }: React.ComponentProps<"div">) {
|
||||
return (
|
||||
<div
|
||||
data-slot="sheet-header"
|
||||
className={cn("flex flex-col gap-1.5 p-4", className)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
function SheetFooter({ className, ...props }: React.ComponentProps<"div">) {
|
||||
return (
|
||||
<div
|
||||
data-slot="sheet-footer"
|
||||
className={cn("mt-auto flex flex-col gap-2 p-4", className)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
function SheetTitle({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<typeof SheetPrimitive.Title>) {
|
||||
return (
|
||||
<SheetPrimitive.Title
|
||||
data-slot="sheet-title"
|
||||
className={cn("text-foreground font-semibold", className)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
function SheetDescription({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<typeof SheetPrimitive.Description>) {
|
||||
return (
|
||||
<SheetPrimitive.Description
|
||||
data-slot="sheet-description"
|
||||
className={cn("text-muted-foreground text-sm", className)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export {
|
||||
Sheet,
|
||||
SheetTrigger,
|
||||
SheetClose,
|
||||
SheetContent,
|
||||
SheetHeader,
|
||||
SheetFooter,
|
||||
SheetTitle,
|
||||
SheetDescription,
|
||||
}
|
11
apps/app/src/config/axios.ts
Normal file
11
apps/app/src/config/axios.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import axios from "axios";
|
||||
|
||||
const axiosInstance = axios.create({
|
||||
baseURL: process.env.NEXT_PUBLIC_API_URL,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
withCredentials: true,
|
||||
});
|
||||
|
||||
export default axiosInstance;
|
29
apps/app/src/config/site.ts
Normal file
29
apps/app/src/config/site.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
export type SiteConfig = typeof siteConfig;
|
||||
|
||||
export const siteConfig = {
|
||||
navItems: [
|
||||
{
|
||||
label: "Login",
|
||||
href: "/login",
|
||||
},
|
||||
{
|
||||
label: "Docs",
|
||||
href: "https://palmr-docs.kyantech.com.br",
|
||||
},
|
||||
],
|
||||
navMenuItems: [
|
||||
{
|
||||
label: "Login",
|
||||
href: "/login",
|
||||
},
|
||||
{
|
||||
label: "Docs",
|
||||
href: "https://palmr-docs.kyantech.com.br",
|
||||
},
|
||||
],
|
||||
links: {
|
||||
github: "https://github.com/kyantech/Palmr",
|
||||
docs: "https://palmr-docs.kyantech.com.br",
|
||||
sponsor: "https://github.com/sponsors/kyantech",
|
||||
},
|
||||
};
|
63
apps/app/src/contexts/app-info-context.tsx
Normal file
63
apps/app/src/contexts/app-info-context.tsx
Normal file
@@ -0,0 +1,63 @@
|
||||
import { create } from 'zustand'
|
||||
import { getAppInfo } from "@/http/endpoints";
|
||||
|
||||
interface AppInfoStore {
|
||||
appName: string;
|
||||
appLogo: string;
|
||||
setAppName: (name: string) => void;
|
||||
setAppLogo: (logo: string) => void;
|
||||
refreshAppInfo: () => Promise<void>;
|
||||
}
|
||||
|
||||
const updateFavicon = (logo: string) => {
|
||||
const link = document.querySelector<HTMLLinkElement>("link[rel*='icon']") || document.createElement("link");
|
||||
link.type = "image/x-icon";
|
||||
link.rel = "shortcut icon";
|
||||
link.href = logo || "/favicon.ico";
|
||||
document.head.appendChild(link);
|
||||
};
|
||||
|
||||
const updateTitle = (name: string) => {
|
||||
document.title = name;
|
||||
};
|
||||
|
||||
export const useAppInfo = create<AppInfoStore>((set) => {
|
||||
if (typeof window !== 'undefined') {
|
||||
getAppInfo().then((response) => {
|
||||
set({
|
||||
appName: response.data.appName,
|
||||
appLogo: response.data.appLogo,
|
||||
});
|
||||
updateTitle(response.data.appName);
|
||||
updateFavicon(response.data.appLogo);
|
||||
}).catch((error) => {
|
||||
console.error("Failed to fetch app info:", error);
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
appName: "",
|
||||
appLogo: "",
|
||||
setAppName: (name: string) => {
|
||||
set({ appName: name });
|
||||
updateTitle(name);
|
||||
},
|
||||
setAppLogo: (logo: string) => {
|
||||
set({ appLogo: logo });
|
||||
updateFavicon(logo);
|
||||
},
|
||||
refreshAppInfo: async () => {
|
||||
try {
|
||||
const response = await getAppInfo();
|
||||
set({
|
||||
appName: response.data.appName,
|
||||
appLogo: response.data.appLogo,
|
||||
});
|
||||
updateTitle(response.data.appName);
|
||||
updateFavicon(response.data.appLogo);
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch app info:", error);
|
||||
}
|
||||
},
|
||||
};
|
||||
});
|
75
apps/app/src/contexts/auth-context.tsx
Normal file
75
apps/app/src/contexts/auth-context.tsx
Normal file
@@ -0,0 +1,75 @@
|
||||
"use client"
|
||||
|
||||
import { getCurrentUser } from "@/http/endpoints";
|
||||
import type { GetCurrentUser200User } from "@/http/models";
|
||||
import { createContext, useContext, useEffect, useState } from "react";
|
||||
|
||||
type AuthUser = Omit<GetCurrentUser200User, "isAdmin">;
|
||||
|
||||
type AuthContextType = {
|
||||
user: AuthUser | null;
|
||||
setUser: (user: AuthUser | null) => void;
|
||||
isAuthenticated: boolean | null;
|
||||
setIsAuthenticated: (value: boolean) => void;
|
||||
isAdmin: boolean | null;
|
||||
setIsAdmin: (value: boolean) => void;
|
||||
logout: () => void;
|
||||
};
|
||||
|
||||
const AuthContext = createContext<AuthContextType>({
|
||||
user: null,
|
||||
setUser: () => {},
|
||||
isAuthenticated: null,
|
||||
setIsAuthenticated: () => {},
|
||||
isAdmin: null,
|
||||
setIsAdmin: () => {},
|
||||
logout: () => {},
|
||||
});
|
||||
|
||||
export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
const [isAuthenticated, setIsAuthenticated] = useState<boolean | null>(null);
|
||||
const [user, setUser] = useState<AuthUser | null>(null);
|
||||
const [isAdmin, setIsAdmin] = useState<boolean | null>(null);
|
||||
|
||||
const logout = () => {
|
||||
setUser(null);
|
||||
setIsAdmin(false);
|
||||
setIsAuthenticated(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const checkAuth = async () => {
|
||||
try {
|
||||
const response = await getCurrentUser();
|
||||
const { isAdmin, ...userData } = response.data.user;
|
||||
|
||||
setUser(userData);
|
||||
setIsAdmin(isAdmin);
|
||||
setIsAuthenticated(true);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
logout();
|
||||
}
|
||||
};
|
||||
|
||||
checkAuth();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<AuthContext.Provider
|
||||
value={{
|
||||
user,
|
||||
setUser,
|
||||
isAuthenticated,
|
||||
setIsAuthenticated,
|
||||
isAdmin,
|
||||
setIsAdmin,
|
||||
logout,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</AuthContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export const useAuth = () => useContext(AuthContext);
|
81
apps/app/src/http/endpoints/app/index.ts
Normal file
81
apps/app/src/http/endpoints/app/index.ts
Normal file
@@ -0,0 +1,81 @@
|
||||
import type {
|
||||
GetAppInfoResult,
|
||||
UploadLogoResult,
|
||||
RemoveLogoResult,
|
||||
CheckHealthResult,
|
||||
GetDiskSpaceResult,
|
||||
CheckUploadAllowedResult,
|
||||
UploadLogoBody,
|
||||
CheckUploadAllowedParams,
|
||||
} from "./types";
|
||||
import axiosInstance from "@/config/axios";
|
||||
import type { AxiosRequestConfig } from "axios";
|
||||
|
||||
/**
|
||||
* Get application base information
|
||||
* @summary Get application base information
|
||||
*/
|
||||
export const getAppInfo = <TData = GetAppInfoResult>(options?: AxiosRequestConfig): Promise<TData> => {
|
||||
return axiosInstance.get(`/app/info`, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Upload a new app logo (admin only)
|
||||
* @summary Upload app logo
|
||||
*/
|
||||
export const uploadLogo = <TData = UploadLogoResult>(
|
||||
uploadLogoBody: UploadLogoBody,
|
||||
options?: AxiosRequestConfig
|
||||
): Promise<TData> => {
|
||||
const formData = new FormData();
|
||||
|
||||
if (uploadLogoBody.file !== undefined) {
|
||||
formData.append("file", uploadLogoBody.file as Blob);
|
||||
}
|
||||
|
||||
return axiosInstance.post(`/app/logo`, formData, {
|
||||
...options,
|
||||
headers: {
|
||||
...options?.headers,
|
||||
"Content-Type": "multipart/form-data",
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove the current app logo (admin only)
|
||||
* @summary Remove app logo
|
||||
*/
|
||||
export const removeLogo = <TData = RemoveLogoResult>(options?: AxiosRequestConfig): Promise<TData> => {
|
||||
return axiosInstance.delete(`/app/logo`, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the health status of the API
|
||||
* @summary Check API Health
|
||||
*/
|
||||
export const checkHealth = <TData = CheckHealthResult>(options?: AxiosRequestConfig): Promise<TData> => {
|
||||
return axiosInstance.get(`/health`, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get server disk space information
|
||||
* @summary Get server disk space information
|
||||
*/
|
||||
export const getDiskSpace = <TData = GetDiskSpaceResult>(options?: AxiosRequestConfig): Promise<TData> => {
|
||||
return axiosInstance.get(`/storage/disk-space`, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if file upload is allowed based on available space (fileSize in bytes)
|
||||
* @summary Check if file upload is allowed
|
||||
*/
|
||||
export const checkUploadAllowed = <TData = CheckUploadAllowedResult>(
|
||||
params: CheckUploadAllowedParams,
|
||||
options?: AxiosRequestConfig
|
||||
): Promise<TData> => {
|
||||
return axiosInstance.get(`/storage/check-upload`, {
|
||||
...options,
|
||||
params: { ...params, ...options?.params },
|
||||
});
|
||||
};
|
20
apps/app/src/http/endpoints/app/types.ts
Normal file
20
apps/app/src/http/endpoints/app/types.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import type {
|
||||
GetAppInfo200,
|
||||
UploadLogo200,
|
||||
UploadLogoBody,
|
||||
RemoveLogo200,
|
||||
CheckHealth200,
|
||||
GetDiskSpace200,
|
||||
CheckUploadAllowed200,
|
||||
CheckUploadAllowedParams,
|
||||
} from "../../models";
|
||||
import type { AxiosResponse } from "axios";
|
||||
|
||||
export type GetAppInfoResult = AxiosResponse<GetAppInfo200>;
|
||||
export type UploadLogoResult = AxiosResponse<UploadLogo200>;
|
||||
export type RemoveLogoResult = AxiosResponse<RemoveLogo200>;
|
||||
export type CheckHealthResult = AxiosResponse<CheckHealth200>;
|
||||
export type GetDiskSpaceResult = AxiosResponse<GetDiskSpace200>;
|
||||
export type CheckUploadAllowedResult = AxiosResponse<CheckUploadAllowed200>;
|
||||
|
||||
export type { UploadLogoBody, CheckUploadAllowedParams };
|
38
apps/app/src/http/endpoints/auth/index.ts
Normal file
38
apps/app/src/http/endpoints/auth/index.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import type {
|
||||
LoginResult,
|
||||
LogoutResult,
|
||||
RequestPasswordResetResult,
|
||||
ResetPasswordResult,
|
||||
GetCurrentUserResult,
|
||||
LoginBody,
|
||||
RequestPasswordResetBody,
|
||||
ResetPasswordBody,
|
||||
} from "./types";
|
||||
import axiosInstance from "@/config/axios";
|
||||
import type { AxiosRequestConfig } from "axios";
|
||||
|
||||
export const login = <TData = LoginResult>(loginBody: LoginBody, options?: AxiosRequestConfig): Promise<TData> => {
|
||||
return axiosInstance.post(`/auth/login`, loginBody, options);
|
||||
};
|
||||
|
||||
export const logout = <TData = LogoutResult>(options?: AxiosRequestConfig): Promise<TData> => {
|
||||
return axiosInstance.post(`/auth/logout`, undefined, options);
|
||||
};
|
||||
|
||||
export const requestPasswordReset = <TData = RequestPasswordResetResult>(
|
||||
requestPasswordResetBody: RequestPasswordResetBody,
|
||||
options?: AxiosRequestConfig
|
||||
): Promise<TData> => {
|
||||
return axiosInstance.post(`/auth/forgot-password`, requestPasswordResetBody, options);
|
||||
};
|
||||
|
||||
export const resetPassword = <TData = ResetPasswordResult>(
|
||||
resetPasswordBody: ResetPasswordBody,
|
||||
options?: AxiosRequestConfig
|
||||
): Promise<TData> => {
|
||||
return axiosInstance.post(`/auth/reset-password`, resetPasswordBody, options);
|
||||
};
|
||||
|
||||
export const getCurrentUser = <TData = GetCurrentUserResult>(options?: AxiosRequestConfig): Promise<TData> => {
|
||||
return axiosInstance.get(`/auth/me`, options);
|
||||
};
|
19
apps/app/src/http/endpoints/auth/types.ts
Normal file
19
apps/app/src/http/endpoints/auth/types.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import type {
|
||||
Login200,
|
||||
LoginBody,
|
||||
Logout200,
|
||||
RequestPasswordReset200,
|
||||
RequestPasswordResetBody,
|
||||
ResetPassword200,
|
||||
ResetPasswordBody,
|
||||
GetCurrentUser200,
|
||||
} from "../../models";
|
||||
import type { AxiosResponse } from "axios";
|
||||
|
||||
export type LoginResult = AxiosResponse<Login200>;
|
||||
export type LogoutResult = AxiosResponse<Logout200>;
|
||||
export type RequestPasswordResetResult = AxiosResponse<RequestPasswordReset200>;
|
||||
export type ResetPasswordResult = AxiosResponse<ResetPassword200>;
|
||||
export type GetCurrentUserResult = AxiosResponse<GetCurrentUser200>;
|
||||
|
||||
export type { LoginBody, RequestPasswordResetBody, ResetPasswordBody };
|
40
apps/app/src/http/endpoints/config/index.ts
Normal file
40
apps/app/src/http/endpoints/config/index.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import type {
|
||||
UpdateConfigResult,
|
||||
GetAllConfigsResult,
|
||||
BulkUpdateConfigsResult,
|
||||
UpdateConfigBody,
|
||||
BulkUpdateConfigsBodyItem,
|
||||
} from "./types";
|
||||
import axiosInstance from "@/config/axios";
|
||||
import type { AxiosRequestConfig } from "axios";
|
||||
|
||||
/**
|
||||
* Update a configuration value (admin only)
|
||||
* @summary Update a configuration value
|
||||
*/
|
||||
export const updateConfig = <TData = UpdateConfigResult>(
|
||||
key: string,
|
||||
updateConfigBody: UpdateConfigBody,
|
||||
options?: AxiosRequestConfig
|
||||
): Promise<TData> => {
|
||||
return axiosInstance.patch(`/app/configs/${key}`, updateConfigBody, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* List all configurations (admin only)
|
||||
* @summary List all configurations
|
||||
*/
|
||||
export const getAllConfigs = <TData = GetAllConfigsResult>(options?: AxiosRequestConfig): Promise<TData> => {
|
||||
return axiosInstance.get(`/app/configs`, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Bulk update configuration values (admin only)
|
||||
* @summary Bulk update configuration values
|
||||
*/
|
||||
export const bulkUpdateConfigs = <TData = BulkUpdateConfigsResult>(
|
||||
bulkUpdateConfigsBodyItem: BulkUpdateConfigsBodyItem[],
|
||||
options?: AxiosRequestConfig
|
||||
): Promise<TData> => {
|
||||
return axiosInstance.patch(`/app/configs`, bulkUpdateConfigsBodyItem, options);
|
||||
};
|
14
apps/app/src/http/endpoints/config/types.ts
Normal file
14
apps/app/src/http/endpoints/config/types.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import type {
|
||||
UpdateConfig200,
|
||||
UpdateConfigBody,
|
||||
GetAllConfigs200,
|
||||
BulkUpdateConfigs200,
|
||||
BulkUpdateConfigsBodyItem,
|
||||
} from "../../models";
|
||||
import type { AxiosResponse } from "axios";
|
||||
|
||||
export type UpdateConfigResult = AxiosResponse<UpdateConfig200>;
|
||||
export type GetAllConfigsResult = AxiosResponse<GetAllConfigs200>;
|
||||
export type BulkUpdateConfigsResult = AxiosResponse<BulkUpdateConfigs200>;
|
||||
|
||||
export type { UpdateConfigBody, BulkUpdateConfigsBodyItem };
|
77
apps/app/src/http/endpoints/files/index.ts
Normal file
77
apps/app/src/http/endpoints/files/index.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
import type {
|
||||
GetPresignedUrlResult,
|
||||
RegisterFileResult,
|
||||
ListFilesResult,
|
||||
GetDownloadUrlResult,
|
||||
DeleteFileResult,
|
||||
UpdateFileResult,
|
||||
GetPresignedUrlParams,
|
||||
RegisterFileBody,
|
||||
UpdateFileBody,
|
||||
} from "./types";
|
||||
import axiosInstance from "@/config/axios";
|
||||
import type { AxiosRequestConfig } from "axios";
|
||||
|
||||
/**
|
||||
* Generates a pre-signed URL for direct upload to MinIO
|
||||
* @summary Get Presigned URL
|
||||
*/
|
||||
export const getPresignedUrl = <TData = GetPresignedUrlResult>(
|
||||
params: GetPresignedUrlParams,
|
||||
options?: AxiosRequestConfig
|
||||
): Promise<TData> => {
|
||||
return axiosInstance.get(`/files/presigned-url`, {
|
||||
...options,
|
||||
params: { ...params, ...options?.params },
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Registers file metadata in the database
|
||||
* @summary Register File Metadata
|
||||
*/
|
||||
export const registerFile = <TData = RegisterFileResult>(
|
||||
registerFileBody: RegisterFileBody,
|
||||
options?: AxiosRequestConfig
|
||||
): Promise<TData> => {
|
||||
return axiosInstance.post(`/files`, registerFileBody, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Lists user files
|
||||
* @summary List Files
|
||||
*/
|
||||
export const listFiles = <TData = ListFilesResult>(options?: AxiosRequestConfig): Promise<TData> => {
|
||||
return axiosInstance.get(`/files`, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Generates a pre-signed URL for downloading a private file
|
||||
* @summary Get Download URL
|
||||
*/
|
||||
export const getDownloadUrl = <TData = GetDownloadUrlResult>(
|
||||
objectName: string,
|
||||
options?: AxiosRequestConfig
|
||||
): Promise<TData> => {
|
||||
return axiosInstance.get(`/files/${objectName}/download`, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Deletes a user file
|
||||
* @summary Delete File
|
||||
*/
|
||||
export const deleteFile = <TData = DeleteFileResult>(id: string, options?: AxiosRequestConfig): Promise<TData> => {
|
||||
return axiosInstance.delete(`/files/${id}`, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates file metadata in the database
|
||||
* @summary Update File Metadata
|
||||
*/
|
||||
export const updateFile = <TData = UpdateFileResult>(
|
||||
id: string,
|
||||
updateFileBody: UpdateFileBody,
|
||||
options?: AxiosRequestConfig
|
||||
): Promise<TData> => {
|
||||
return axiosInstance.patch(`/files/${id}`, updateFileBody, options);
|
||||
};
|
21
apps/app/src/http/endpoints/files/types.ts
Normal file
21
apps/app/src/http/endpoints/files/types.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import type {
|
||||
GetPresignedUrl200,
|
||||
GetPresignedUrlParams,
|
||||
RegisterFile201,
|
||||
RegisterFileBody,
|
||||
ListFiles200,
|
||||
GetDownloadUrl200,
|
||||
DeleteFile200,
|
||||
UpdateFile200,
|
||||
UpdateFileBody,
|
||||
} from "../../models";
|
||||
import type { AxiosResponse } from "axios";
|
||||
|
||||
export type GetPresignedUrlResult = AxiosResponse<GetPresignedUrl200>;
|
||||
export type RegisterFileResult = AxiosResponse<RegisterFile201>;
|
||||
export type ListFilesResult = AxiosResponse<ListFiles200>;
|
||||
export type GetDownloadUrlResult = AxiosResponse<GetDownloadUrl200>;
|
||||
export type DeleteFileResult = AxiosResponse<DeleteFile200>;
|
||||
export type UpdateFileResult = AxiosResponse<UpdateFile200>;
|
||||
|
||||
export type { GetPresignedUrlParams, RegisterFileBody, UpdateFileBody };
|
6
apps/app/src/http/endpoints/index.ts
Normal file
6
apps/app/src/http/endpoints/index.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export * from "./auth";
|
||||
export * from "./users";
|
||||
export * from "./files";
|
||||
export * from "./shares";
|
||||
export * from "./config";
|
||||
export * from "./app";
|
180
apps/app/src/http/endpoints/shares/index.ts
Normal file
180
apps/app/src/http/endpoints/shares/index.ts
Normal file
@@ -0,0 +1,180 @@
|
||||
import type {
|
||||
CreateShareResult,
|
||||
UpdateShareResult,
|
||||
ListUserSharesResult,
|
||||
GetShareResult,
|
||||
DeleteShareResult,
|
||||
UpdateSharePasswordResult,
|
||||
AddFilesResult,
|
||||
RemoveFilesResult,
|
||||
AddRecipientsResult,
|
||||
RemoveRecipientsResult,
|
||||
CreateShareAliasResult,
|
||||
GetShareByAliasResult,
|
||||
NotifyRecipientsResult,
|
||||
CreateShareBody,
|
||||
UpdateShareBody,
|
||||
GetShareParams,
|
||||
UpdateSharePasswordBody,
|
||||
AddFilesBody,
|
||||
RemoveFilesBody,
|
||||
AddRecipientsBody,
|
||||
RemoveRecipientsBody,
|
||||
CreateShareAliasBody,
|
||||
GetShareByAliasParams,
|
||||
NotifyRecipientsBody,
|
||||
} from "./types";
|
||||
import axiosInstance from "@/config/axios";
|
||||
import type { AxiosRequestConfig } from "axios";
|
||||
|
||||
/**
|
||||
* Create a new share
|
||||
* @summary Create a new share
|
||||
*/
|
||||
export const createShare = <TData = CreateShareResult>(
|
||||
createShareBody: CreateShareBody,
|
||||
options?: AxiosRequestConfig
|
||||
): Promise<TData> => {
|
||||
return axiosInstance.post(`/shares`, createShareBody, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Update a share
|
||||
* @summary Update a share
|
||||
*/
|
||||
export const updateShare = <TData = UpdateShareResult>(
|
||||
updateShareBody: UpdateShareBody,
|
||||
options?: AxiosRequestConfig
|
||||
): Promise<TData> => {
|
||||
return axiosInstance.put(`/shares`, updateShareBody, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* List all shares created by the authenticated user
|
||||
* @summary List all shares created by the authenticated user
|
||||
*/
|
||||
export const listUserShares = <TData = ListUserSharesResult>(options?: AxiosRequestConfig): Promise<TData> => {
|
||||
return axiosInstance.get(`/shares/me`, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a share by ID
|
||||
* @summary Get a share by ID
|
||||
*/
|
||||
export const getShare = <TData = GetShareResult>(
|
||||
shareId: string,
|
||||
params?: GetShareParams,
|
||||
options?: AxiosRequestConfig
|
||||
): Promise<TData> => {
|
||||
return axiosInstance.get(`/shares/${shareId}`, {
|
||||
...options,
|
||||
params: { ...params, ...options?.params },
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete a share
|
||||
* @summary Delete a share
|
||||
*/
|
||||
export const deleteShare = <TData = DeleteShareResult>(id: string, options?: AxiosRequestConfig): Promise<TData> => {
|
||||
return axiosInstance.delete(`/shares/${id}`, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* @summary Update share password
|
||||
*/
|
||||
export const updateSharePassword = <TData = UpdateSharePasswordResult>(
|
||||
shareId: string,
|
||||
updateSharePasswordBody: UpdateSharePasswordBody,
|
||||
options?: AxiosRequestConfig
|
||||
): Promise<TData> => {
|
||||
return axiosInstance.patch(`/shares/${shareId}/password`, updateSharePasswordBody, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* @summary Add files to share
|
||||
*/
|
||||
export const addFiles = <TData = AddFilesResult>(
|
||||
shareId: string,
|
||||
addFilesBody: AddFilesBody,
|
||||
options?: AxiosRequestConfig
|
||||
): Promise<TData> => {
|
||||
return axiosInstance.post(`/shares/${shareId}/files`, addFilesBody, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* @summary Remove files from share
|
||||
*/
|
||||
export const removeFiles = <TData = RemoveFilesResult>(
|
||||
shareId: string,
|
||||
removeFilesBody: RemoveFilesBody,
|
||||
options?: AxiosRequestConfig
|
||||
): Promise<TData> => {
|
||||
return axiosInstance.delete(`/shares/${shareId}/files`, {
|
||||
data: removeFilesBody,
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @summary Add recipients to a share
|
||||
*/
|
||||
export const addRecipients = <TData = AddRecipientsResult>(
|
||||
shareId: string,
|
||||
addRecipientsBody: AddRecipientsBody,
|
||||
options?: AxiosRequestConfig
|
||||
): Promise<TData> => {
|
||||
return axiosInstance.post(`/shares/${shareId}/recipients`, addRecipientsBody, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove recipients from a share
|
||||
* @summary Remove recipients from a share
|
||||
*/
|
||||
export const removeRecipients = <TData = RemoveRecipientsResult>(
|
||||
shareId: string,
|
||||
removeRecipientsBody: RemoveRecipientsBody,
|
||||
options?: AxiosRequestConfig
|
||||
): Promise<TData> => {
|
||||
return axiosInstance.delete(`/shares/${shareId}/recipients`, {
|
||||
data: removeRecipientsBody,
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @summary Create or update share alias
|
||||
*/
|
||||
export const createShareAlias = <TData = CreateShareAliasResult>(
|
||||
shareId: string,
|
||||
createShareAliasBody: CreateShareAliasBody,
|
||||
options?: AxiosRequestConfig
|
||||
): Promise<TData> => {
|
||||
return axiosInstance.post(`/shares/${shareId}/alias`, createShareAliasBody, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* @summary Get share by alias
|
||||
*/
|
||||
export const getShareByAlias = <TData = GetShareByAliasResult>(
|
||||
alias: string,
|
||||
params?: GetShareByAliasParams,
|
||||
options?: AxiosRequestConfig
|
||||
): Promise<TData> => {
|
||||
return axiosInstance.get(`/shares/alias/${alias}`, {
|
||||
...options,
|
||||
params: { ...params, ...options?.params },
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Send email notification with share link to all recipients
|
||||
* @summary Send email notification to share recipients
|
||||
*/
|
||||
export const notifyRecipients = <TData = NotifyRecipientsResult>(
|
||||
shareId: string,
|
||||
notifyRecipientsBody: NotifyRecipientsBody,
|
||||
options?: AxiosRequestConfig
|
||||
): Promise<TData> => {
|
||||
return axiosInstance.post(`/shares/${shareId}/notify`, notifyRecipientsBody, options);
|
||||
};
|
55
apps/app/src/http/endpoints/shares/types.ts
Normal file
55
apps/app/src/http/endpoints/shares/types.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import type {
|
||||
CreateShare201,
|
||||
CreateShareBody,
|
||||
UpdateShare200,
|
||||
UpdateShareBody,
|
||||
ListUserShares200,
|
||||
GetShare200,
|
||||
GetShareParams,
|
||||
DeleteShare200,
|
||||
UpdateSharePassword200,
|
||||
UpdateSharePasswordBody,
|
||||
AddFiles200,
|
||||
AddFilesBody,
|
||||
RemoveFiles200,
|
||||
RemoveFilesBody,
|
||||
AddRecipients200,
|
||||
AddRecipientsBody,
|
||||
RemoveRecipients200,
|
||||
RemoveRecipientsBody,
|
||||
CreateShareAlias200,
|
||||
CreateShareAliasBody,
|
||||
GetShareByAlias200,
|
||||
GetShareByAliasParams,
|
||||
NotifyRecipients200,
|
||||
NotifyRecipientsBody,
|
||||
} from "../../models";
|
||||
import type { AxiosResponse } from "axios";
|
||||
|
||||
export type CreateShareResult = AxiosResponse<CreateShare201>;
|
||||
export type UpdateShareResult = AxiosResponse<UpdateShare200>;
|
||||
export type ListUserSharesResult = AxiosResponse<ListUserShares200>;
|
||||
export type GetShareResult = AxiosResponse<GetShare200>;
|
||||
export type DeleteShareResult = AxiosResponse<DeleteShare200>;
|
||||
export type UpdateSharePasswordResult = AxiosResponse<UpdateSharePassword200>;
|
||||
export type AddFilesResult = AxiosResponse<AddFiles200>;
|
||||
export type RemoveFilesResult = AxiosResponse<RemoveFiles200>;
|
||||
export type AddRecipientsResult = AxiosResponse<AddRecipients200>;
|
||||
export type RemoveRecipientsResult = AxiosResponse<RemoveRecipients200>;
|
||||
export type CreateShareAliasResult = AxiosResponse<CreateShareAlias200>;
|
||||
export type GetShareByAliasResult = AxiosResponse<GetShareByAlias200>;
|
||||
export type NotifyRecipientsResult = AxiosResponse<NotifyRecipients200>;
|
||||
|
||||
export type {
|
||||
CreateShareBody,
|
||||
UpdateShareBody,
|
||||
GetShareParams,
|
||||
UpdateSharePasswordBody,
|
||||
AddFilesBody,
|
||||
RemoveFilesBody,
|
||||
AddRecipientsBody,
|
||||
RemoveRecipientsBody,
|
||||
CreateShareAliasBody,
|
||||
GetShareByAliasParams,
|
||||
NotifyRecipientsBody,
|
||||
};
|
126
apps/app/src/http/endpoints/users/index.ts
Normal file
126
apps/app/src/http/endpoints/users/index.ts
Normal file
@@ -0,0 +1,126 @@
|
||||
import type {
|
||||
RegisterUserResult,
|
||||
ListUsersResult,
|
||||
UpdateUserResult,
|
||||
GetUserByIdResult,
|
||||
DeleteUserResult,
|
||||
ActivateUserResult,
|
||||
DeactivateUserResult,
|
||||
UpdateUserImageResult,
|
||||
UploadAvatarResult,
|
||||
RemoveAvatarResult,
|
||||
RegisterUserBody,
|
||||
UpdateUserBody,
|
||||
UpdateUserImageBody,
|
||||
UploadAvatarBody,
|
||||
} from "./types";
|
||||
import axiosInstance from "@/config/axios";
|
||||
import type { AxiosRequestConfig } from "axios";
|
||||
|
||||
/**
|
||||
* Register a new user (admin only)
|
||||
* @summary Register New User
|
||||
*/
|
||||
export const registerUser = <TData = RegisterUserResult>(
|
||||
registerUserBody: RegisterUserBody,
|
||||
options?: AxiosRequestConfig
|
||||
): Promise<TData> => {
|
||||
return axiosInstance.post(`/auth/register`, registerUserBody, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* List all users (admin only)
|
||||
* @summary List All Users
|
||||
*/
|
||||
export const listUsers = <TData = ListUsersResult>(options?: AxiosRequestConfig): Promise<TData> => {
|
||||
return axiosInstance.get(`/users`, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Update user data (admin only)
|
||||
* @summary Update User Data
|
||||
*/
|
||||
export const updateUser = <TData = UpdateUserResult>(
|
||||
updateUserBody: UpdateUserBody,
|
||||
options?: AxiosRequestConfig
|
||||
): Promise<TData> => {
|
||||
return axiosInstance.put(`/users`, updateUserBody, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a user by ID (admin only)
|
||||
* @summary Get User by ID
|
||||
*/
|
||||
export const getUserById = <TData = GetUserByIdResult>(id: string, options?: AxiosRequestConfig): Promise<TData> => {
|
||||
return axiosInstance.get(`/users/${id}`, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete a user (admin only)
|
||||
* @summary Delete User
|
||||
*/
|
||||
export const deleteUser = <TData = DeleteUserResult>(id: string, options?: AxiosRequestConfig): Promise<TData> => {
|
||||
return axiosInstance.delete(`/users/${id}`, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Activate a user (admin only)
|
||||
* @summary Activate User
|
||||
*/
|
||||
export const activateUser = <TData = ActivateUserResult>(id: string, options?: AxiosRequestConfig): Promise<TData> => {
|
||||
return axiosInstance.patch(`/users/${id}/activate`, undefined, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Deactivate a user (admin only)
|
||||
* @summary Deactivate User
|
||||
*/
|
||||
export const deactivateUser = <TData = DeactivateUserResult>(
|
||||
id: string,
|
||||
options?: AxiosRequestConfig
|
||||
): Promise<TData> => {
|
||||
return axiosInstance.patch(`/users/${id}/deactivate`, undefined, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Update user profile image (admin only)
|
||||
* @summary Update User Image
|
||||
*/
|
||||
export const updateUserImage = <TData = UpdateUserImageResult>(
|
||||
id: string,
|
||||
updateUserImageBody: UpdateUserImageBody,
|
||||
options?: AxiosRequestConfig
|
||||
): Promise<TData> => {
|
||||
return axiosInstance.patch(`/users/${id}/image`, updateUserImageBody, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Upload and update user profile image
|
||||
* @summary Upload user avatar
|
||||
*/
|
||||
export const uploadAvatar = <TData = UploadAvatarResult>(
|
||||
uploadAvatarBody: UploadAvatarBody,
|
||||
options?: AxiosRequestConfig
|
||||
): Promise<TData> => {
|
||||
const formData = new FormData();
|
||||
|
||||
if (uploadAvatarBody.file !== undefined) {
|
||||
formData.append("file", uploadAvatarBody.file as Blob);
|
||||
}
|
||||
|
||||
return axiosInstance.post(`/users/avatar`, formData, {
|
||||
...options,
|
||||
headers: {
|
||||
...options?.headers,
|
||||
"Content-Type": "multipart/form-data",
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove user profile image
|
||||
* @summary Remove user avatar
|
||||
*/
|
||||
export const removeAvatar = <TData = RemoveAvatarResult>(options?: AxiosRequestConfig): Promise<TData> => {
|
||||
return axiosInstance.delete(`/users/avatar`, options);
|
||||
};
|
30
apps/app/src/http/endpoints/users/types.ts
Normal file
30
apps/app/src/http/endpoints/users/types.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import type {
|
||||
RegisterUser201,
|
||||
RegisterUserBody,
|
||||
ListUsers200Item,
|
||||
UpdateUser200,
|
||||
UpdateUserBody,
|
||||
GetUserById200,
|
||||
DeleteUser200,
|
||||
ActivateUser200,
|
||||
DeactivateUser200,
|
||||
UpdateUserImage200,
|
||||
UpdateUserImageBody,
|
||||
UploadAvatar200,
|
||||
UploadAvatarBody,
|
||||
RemoveAvatar200,
|
||||
} from "../../models";
|
||||
import type { AxiosResponse } from "axios";
|
||||
|
||||
export type RegisterUserResult = AxiosResponse<RegisterUser201>;
|
||||
export type ListUsersResult = AxiosResponse<ListUsers200Item[]>;
|
||||
export type UpdateUserResult = AxiosResponse<UpdateUser200>;
|
||||
export type GetUserByIdResult = AxiosResponse<GetUserById200>;
|
||||
export type DeleteUserResult = AxiosResponse<DeleteUser200>;
|
||||
export type ActivateUserResult = AxiosResponse<ActivateUser200>;
|
||||
export type DeactivateUserResult = AxiosResponse<DeactivateUser200>;
|
||||
export type UpdateUserImageResult = AxiosResponse<UpdateUserImage200>;
|
||||
export type UploadAvatarResult = AxiosResponse<UploadAvatar200>;
|
||||
export type RemoveAvatarResult = AxiosResponse<RemoveAvatar200>;
|
||||
|
||||
export type { RegisterUserBody, UpdateUserBody, UpdateUserImageBody, UploadAvatarBody };
|
33
apps/app/src/http/models/activateUser200.ts
Normal file
33
apps/app/src/http/models/activateUser200.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Generated by orval v7.5.0 🍺
|
||||
* Do not edit manually.
|
||||
* 🌴 Palmr. API
|
||||
* API documentation for Palmr file sharing system
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*/
|
||||
|
||||
export type ActivateUser200 = {
|
||||
/** User ID */
|
||||
id: string;
|
||||
/** User first name */
|
||||
firstName: string;
|
||||
/** User last name */
|
||||
lastName: string;
|
||||
/** User username */
|
||||
username: string;
|
||||
/** User email */
|
||||
email: string;
|
||||
/**
|
||||
* User profile image URL
|
||||
* @nullable
|
||||
*/
|
||||
image: string | null;
|
||||
/** User is admin */
|
||||
isAdmin: boolean;
|
||||
/** User is active */
|
||||
isActive: boolean;
|
||||
/** User creation date */
|
||||
createdAt: string;
|
||||
/** User last update date */
|
||||
updatedAt: string;
|
||||
};
|
12
apps/app/src/http/models/activateUser400.ts
Normal file
12
apps/app/src/http/models/activateUser400.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Generated by orval v7.5.0 🍺
|
||||
* Do not edit manually.
|
||||
* 🌴 Palmr. API
|
||||
* API documentation for Palmr file sharing system
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*/
|
||||
|
||||
export type ActivateUser400 = {
|
||||
/** Error message */
|
||||
error: string;
|
||||
};
|
12
apps/app/src/http/models/activateUser401.ts
Normal file
12
apps/app/src/http/models/activateUser401.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Generated by orval v7.5.0 🍺
|
||||
* Do not edit manually.
|
||||
* 🌴 Palmr. API
|
||||
* API documentation for Palmr file sharing system
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*/
|
||||
|
||||
export type ActivateUser401 = {
|
||||
/** Error message */
|
||||
error: string;
|
||||
};
|
12
apps/app/src/http/models/activateUser403.ts
Normal file
12
apps/app/src/http/models/activateUser403.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Generated by orval v7.5.0 🍺
|
||||
* Do not edit manually.
|
||||
* 🌴 Palmr. API
|
||||
* API documentation for Palmr file sharing system
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*/
|
||||
|
||||
export type ActivateUser403 = {
|
||||
/** Error message */
|
||||
error: string;
|
||||
};
|
12
apps/app/src/http/models/addFiles200.ts
Normal file
12
apps/app/src/http/models/addFiles200.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Generated by orval v7.5.0 🍺
|
||||
* Do not edit manually.
|
||||
* 🌴 Palmr. API
|
||||
* API documentation for Palmr file sharing system
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*/
|
||||
import type { AddFiles200Share } from "./addFiles200Share";
|
||||
|
||||
export type AddFiles200 = {
|
||||
share: AddFiles200Share;
|
||||
};
|
44
apps/app/src/http/models/addFiles200Share.ts
Normal file
44
apps/app/src/http/models/addFiles200Share.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* Generated by orval v7.5.0 🍺
|
||||
* Do not edit manually.
|
||||
* 🌴 Palmr. API
|
||||
* API documentation for Palmr file sharing system
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*/
|
||||
import type { AddFiles200ShareAlias } from "./addFiles200ShareAlias";
|
||||
import type { AddFiles200ShareFilesItem } from "./addFiles200ShareFilesItem";
|
||||
import type { AddFiles200ShareRecipientsItem } from "./addFiles200ShareRecipientsItem";
|
||||
import type { AddFiles200ShareSecurity } from "./addFiles200ShareSecurity";
|
||||
|
||||
export type AddFiles200Share = {
|
||||
/** The share ID */
|
||||
id: string;
|
||||
/**
|
||||
* The share name
|
||||
* @nullable
|
||||
*/
|
||||
name: string | null;
|
||||
/**
|
||||
* The share description
|
||||
* @nullable
|
||||
*/
|
||||
description: string | null;
|
||||
/**
|
||||
* The share expiration date
|
||||
* @nullable
|
||||
*/
|
||||
expiration: string | null;
|
||||
/** The number of views */
|
||||
views: number;
|
||||
/** The share creation date */
|
||||
createdAt: string;
|
||||
/** The share update date */
|
||||
updatedAt: string;
|
||||
/** The creator ID */
|
||||
creatorId: string;
|
||||
security: AddFiles200ShareSecurity;
|
||||
files: AddFiles200ShareFilesItem[];
|
||||
recipients: AddFiles200ShareRecipientsItem[];
|
||||
/** @nullable */
|
||||
alias: AddFiles200ShareAlias;
|
||||
};
|
18
apps/app/src/http/models/addFiles200ShareAlias.ts
Normal file
18
apps/app/src/http/models/addFiles200ShareAlias.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Generated by orval v7.5.0 🍺
|
||||
* Do not edit manually.
|
||||
* 🌴 Palmr. API
|
||||
* API documentation for Palmr file sharing system
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @nullable
|
||||
*/
|
||||
export type AddFiles200ShareAlias = {
|
||||
id: string;
|
||||
alias: string;
|
||||
shareId: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
} | null;
|
31
apps/app/src/http/models/addFiles200ShareFilesItem.ts
Normal file
31
apps/app/src/http/models/addFiles200ShareFilesItem.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Generated by orval v7.5.0 🍺
|
||||
* Do not edit manually.
|
||||
* 🌴 Palmr. API
|
||||
* API documentation for Palmr file sharing system
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*/
|
||||
|
||||
export type AddFiles200ShareFilesItem = {
|
||||
/** The file ID */
|
||||
id: string;
|
||||
/** The file name */
|
||||
name: string;
|
||||
/**
|
||||
* The file description
|
||||
* @nullable
|
||||
*/
|
||||
description: string | null;
|
||||
/** The file extension */
|
||||
extension: string;
|
||||
/** The file size */
|
||||
size: string;
|
||||
/** The file object name */
|
||||
objectName: string;
|
||||
/** The user ID */
|
||||
userId: string;
|
||||
/** The file creation date */
|
||||
createdAt: string;
|
||||
/** The file update date */
|
||||
updatedAt: string;
|
||||
};
|
18
apps/app/src/http/models/addFiles200ShareRecipientsItem.ts
Normal file
18
apps/app/src/http/models/addFiles200ShareRecipientsItem.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Generated by orval v7.5.0 🍺
|
||||
* Do not edit manually.
|
||||
* 🌴 Palmr. API
|
||||
* API documentation for Palmr file sharing system
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*/
|
||||
|
||||
export type AddFiles200ShareRecipientsItem = {
|
||||
/** The recipient ID */
|
||||
id: string;
|
||||
/** The recipient email */
|
||||
email: string;
|
||||
/** The recipient creation date */
|
||||
createdAt: string;
|
||||
/** The recipient update date */
|
||||
updatedAt: string;
|
||||
};
|
17
apps/app/src/http/models/addFiles200ShareSecurity.ts
Normal file
17
apps/app/src/http/models/addFiles200ShareSecurity.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Generated by orval v7.5.0 🍺
|
||||
* Do not edit manually.
|
||||
* 🌴 Palmr. API
|
||||
* API documentation for Palmr file sharing system
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*/
|
||||
|
||||
export type AddFiles200ShareSecurity = {
|
||||
/**
|
||||
* The maximum number of views
|
||||
* @nullable
|
||||
*/
|
||||
maxViews: number | null;
|
||||
/** Whether the share has a password */
|
||||
hasPassword: boolean;
|
||||
};
|
12
apps/app/src/http/models/addFiles400.ts
Normal file
12
apps/app/src/http/models/addFiles400.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Generated by orval v7.5.0 🍺
|
||||
* Do not edit manually.
|
||||
* 🌴 Palmr. API
|
||||
* API documentation for Palmr file sharing system
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*/
|
||||
|
||||
export type AddFiles400 = {
|
||||
/** Error message */
|
||||
error: string;
|
||||
};
|
12
apps/app/src/http/models/addFiles401.ts
Normal file
12
apps/app/src/http/models/addFiles401.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Generated by orval v7.5.0 🍺
|
||||
* Do not edit manually.
|
||||
* 🌴 Palmr. API
|
||||
* API documentation for Palmr file sharing system
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*/
|
||||
|
||||
export type AddFiles401 = {
|
||||
/** Error message */
|
||||
error: string;
|
||||
};
|
12
apps/app/src/http/models/addFiles404.ts
Normal file
12
apps/app/src/http/models/addFiles404.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Generated by orval v7.5.0 🍺
|
||||
* Do not edit manually.
|
||||
* 🌴 Palmr. API
|
||||
* API documentation for Palmr file sharing system
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*/
|
||||
|
||||
export type AddFiles404 = {
|
||||
/** Error message */
|
||||
error: string;
|
||||
};
|
11
apps/app/src/http/models/addFilesBody.ts
Normal file
11
apps/app/src/http/models/addFilesBody.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Generated by orval v7.5.0 🍺
|
||||
* Do not edit manually.
|
||||
* 🌴 Palmr. API
|
||||
* API documentation for Palmr file sharing system
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*/
|
||||
|
||||
export type AddFilesBody = {
|
||||
files: string[];
|
||||
};
|
12
apps/app/src/http/models/addRecipients200.ts
Normal file
12
apps/app/src/http/models/addRecipients200.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Generated by orval v7.5.0 🍺
|
||||
* Do not edit manually.
|
||||
* 🌴 Palmr. API
|
||||
* API documentation for Palmr file sharing system
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*/
|
||||
import type { AddRecipients200Share } from "./addRecipients200Share";
|
||||
|
||||
export type AddRecipients200 = {
|
||||
share: AddRecipients200Share;
|
||||
};
|
44
apps/app/src/http/models/addRecipients200Share.ts
Normal file
44
apps/app/src/http/models/addRecipients200Share.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* Generated by orval v7.5.0 🍺
|
||||
* Do not edit manually.
|
||||
* 🌴 Palmr. API
|
||||
* API documentation for Palmr file sharing system
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*/
|
||||
import type { AddRecipients200ShareAlias } from "./addRecipients200ShareAlias";
|
||||
import type { AddRecipients200ShareFilesItem } from "./addRecipients200ShareFilesItem";
|
||||
import type { AddRecipients200ShareRecipientsItem } from "./addRecipients200ShareRecipientsItem";
|
||||
import type { AddRecipients200ShareSecurity } from "./addRecipients200ShareSecurity";
|
||||
|
||||
export type AddRecipients200Share = {
|
||||
/** The share ID */
|
||||
id: string;
|
||||
/**
|
||||
* The share name
|
||||
* @nullable
|
||||
*/
|
||||
name: string | null;
|
||||
/**
|
||||
* The share description
|
||||
* @nullable
|
||||
*/
|
||||
description: string | null;
|
||||
/**
|
||||
* The share expiration date
|
||||
* @nullable
|
||||
*/
|
||||
expiration: string | null;
|
||||
/** The number of views */
|
||||
views: number;
|
||||
/** The share creation date */
|
||||
createdAt: string;
|
||||
/** The share update date */
|
||||
updatedAt: string;
|
||||
/** The creator ID */
|
||||
creatorId: string;
|
||||
security: AddRecipients200ShareSecurity;
|
||||
files: AddRecipients200ShareFilesItem[];
|
||||
recipients: AddRecipients200ShareRecipientsItem[];
|
||||
/** @nullable */
|
||||
alias: AddRecipients200ShareAlias;
|
||||
};
|
18
apps/app/src/http/models/addRecipients200ShareAlias.ts
Normal file
18
apps/app/src/http/models/addRecipients200ShareAlias.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Generated by orval v7.5.0 🍺
|
||||
* Do not edit manually.
|
||||
* 🌴 Palmr. API
|
||||
* API documentation for Palmr file sharing system
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @nullable
|
||||
*/
|
||||
export type AddRecipients200ShareAlias = {
|
||||
id: string;
|
||||
alias: string;
|
||||
shareId: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
} | null;
|
31
apps/app/src/http/models/addRecipients200ShareFilesItem.ts
Normal file
31
apps/app/src/http/models/addRecipients200ShareFilesItem.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Generated by orval v7.5.0 🍺
|
||||
* Do not edit manually.
|
||||
* 🌴 Palmr. API
|
||||
* API documentation for Palmr file sharing system
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*/
|
||||
|
||||
export type AddRecipients200ShareFilesItem = {
|
||||
/** The file ID */
|
||||
id: string;
|
||||
/** The file name */
|
||||
name: string;
|
||||
/**
|
||||
* The file description
|
||||
* @nullable
|
||||
*/
|
||||
description: string | null;
|
||||
/** The file extension */
|
||||
extension: string;
|
||||
/** The file size */
|
||||
size: string;
|
||||
/** The file object name */
|
||||
objectName: string;
|
||||
/** The user ID */
|
||||
userId: string;
|
||||
/** The file creation date */
|
||||
createdAt: string;
|
||||
/** The file update date */
|
||||
updatedAt: string;
|
||||
};
|
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Generated by orval v7.5.0 🍺
|
||||
* Do not edit manually.
|
||||
* 🌴 Palmr. API
|
||||
* API documentation for Palmr file sharing system
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*/
|
||||
|
||||
export type AddRecipients200ShareRecipientsItem = {
|
||||
/** The recipient ID */
|
||||
id: string;
|
||||
/** The recipient email */
|
||||
email: string;
|
||||
/** The recipient creation date */
|
||||
createdAt: string;
|
||||
/** The recipient update date */
|
||||
updatedAt: string;
|
||||
};
|
17
apps/app/src/http/models/addRecipients200ShareSecurity.ts
Normal file
17
apps/app/src/http/models/addRecipients200ShareSecurity.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Generated by orval v7.5.0 🍺
|
||||
* Do not edit manually.
|
||||
* 🌴 Palmr. API
|
||||
* API documentation for Palmr file sharing system
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*/
|
||||
|
||||
export type AddRecipients200ShareSecurity = {
|
||||
/**
|
||||
* The maximum number of views
|
||||
* @nullable
|
||||
*/
|
||||
maxViews: number | null;
|
||||
/** Whether the share has a password */
|
||||
hasPassword: boolean;
|
||||
};
|
12
apps/app/src/http/models/addRecipients400.ts
Normal file
12
apps/app/src/http/models/addRecipients400.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Generated by orval v7.5.0 🍺
|
||||
* Do not edit manually.
|
||||
* 🌴 Palmr. API
|
||||
* API documentation for Palmr file sharing system
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*/
|
||||
|
||||
export type AddRecipients400 = {
|
||||
/** Error message */
|
||||
error: string;
|
||||
};
|
12
apps/app/src/http/models/addRecipients401.ts
Normal file
12
apps/app/src/http/models/addRecipients401.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Generated by orval v7.5.0 🍺
|
||||
* Do not edit manually.
|
||||
* 🌴 Palmr. API
|
||||
* API documentation for Palmr file sharing system
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*/
|
||||
|
||||
export type AddRecipients401 = {
|
||||
/** Error message */
|
||||
error: string;
|
||||
};
|
12
apps/app/src/http/models/addRecipients404.ts
Normal file
12
apps/app/src/http/models/addRecipients404.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Generated by orval v7.5.0 🍺
|
||||
* Do not edit manually.
|
||||
* 🌴 Palmr. API
|
||||
* API documentation for Palmr file sharing system
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*/
|
||||
|
||||
export type AddRecipients404 = {
|
||||
/** Error message */
|
||||
error: string;
|
||||
};
|
11
apps/app/src/http/models/addRecipientsBody.ts
Normal file
11
apps/app/src/http/models/addRecipientsBody.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Generated by orval v7.5.0 🍺
|
||||
* Do not edit manually.
|
||||
* 🌴 Palmr. API
|
||||
* API documentation for Palmr file sharing system
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*/
|
||||
|
||||
export type AddRecipientsBody = {
|
||||
emails: string[];
|
||||
};
|
12
apps/app/src/http/models/bulkUpdateConfigs200.ts
Normal file
12
apps/app/src/http/models/bulkUpdateConfigs200.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Generated by orval v7.5.0 🍺
|
||||
* Do not edit manually.
|
||||
* 🌴 Palmr. API
|
||||
* API documentation for Palmr file sharing system
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*/
|
||||
import type { BulkUpdateConfigs200ConfigsItem } from "./bulkUpdateConfigs200ConfigsItem";
|
||||
|
||||
export type BulkUpdateConfigs200 = {
|
||||
configs: BulkUpdateConfigs200ConfigsItem[];
|
||||
};
|
20
apps/app/src/http/models/bulkUpdateConfigs200ConfigsItem.ts
Normal file
20
apps/app/src/http/models/bulkUpdateConfigs200ConfigsItem.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Generated by orval v7.5.0 🍺
|
||||
* Do not edit manually.
|
||||
* 🌴 Palmr. API
|
||||
* API documentation for Palmr file sharing system
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*/
|
||||
|
||||
export type BulkUpdateConfigs200ConfigsItem = {
|
||||
/** The config key */
|
||||
key: string;
|
||||
/** The config value */
|
||||
value: string;
|
||||
/** The config type */
|
||||
type: string;
|
||||
/** The config group */
|
||||
group: string;
|
||||
/** The config update date */
|
||||
updatedAt: string;
|
||||
};
|
12
apps/app/src/http/models/bulkUpdateConfigs400.ts
Normal file
12
apps/app/src/http/models/bulkUpdateConfigs400.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Generated by orval v7.5.0 🍺
|
||||
* Do not edit manually.
|
||||
* 🌴 Palmr. API
|
||||
* API documentation for Palmr file sharing system
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*/
|
||||
|
||||
export type BulkUpdateConfigs400 = {
|
||||
/** Error message */
|
||||
error: string;
|
||||
};
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user