feat: add subscription management for web (#1494)
This commit is contained in:
@@ -183,35 +183,18 @@
|
||||
"Sign in with GitHub": "تسجيل الدخول عبر GitHub",
|
||||
"Account": "الحساب",
|
||||
"Failed to delete user. Please try again later.": "فشل حذف المستخدم. يرجى المحاولة مرة أخرى لاحقًا.",
|
||||
"Unlimited Offline/Online Reading": "القراءة بدون حدود للكتب المتوفر على الجهاز أو عبر الانترنت",
|
||||
"Unlimited Cloud Sync Devices": "مزامنة عبر السحابة لعدد غير محدود من الأجهزة",
|
||||
"Essential Text-to-Speech Voices": "أصوات أساسية لتحويل النص إلى كلام",
|
||||
"DeepL Free Access": "وصول مجاني لـ DeepL",
|
||||
"Community Support": "دعم المجتمع",
|
||||
"500 MB Cloud Sync Space": "مزامنة سحابية بمساحة تخزين 500 ميجابايت",
|
||||
"Includes All Free Tier Benefits": "تشمل جميع مزايا الفئة المجانية",
|
||||
"AI Summaries": "ملخصات الذكاء الاصطناعي",
|
||||
"AI Translations": "ترجمات الذكاء الاصطناعي",
|
||||
"Priority Support": "دعم ذو أولوية",
|
||||
"DeepL Pro Access": "وصول لميزات DeepL Pro",
|
||||
"Expanded Text-to-Speech Voices": "أصوات موسعة لتحويل النص إلى كلام",
|
||||
"2000 MB Cloud Sync Space": "مزامنة سحابية بمساحة تخزين 2000 ميجابايت",
|
||||
"Includes All Plus Tier Benefits": "تشمل جميع مزايا فئة Plus",
|
||||
"Unlimited AI Summaries": "ملخصات ذكاء اصطناعي غير محدودة",
|
||||
"Unlimited AI Translations": "ترجمات ذكاء اصطناعي غير محدودة",
|
||||
"Unlimited DeepL Pro Access": "وصول غير محدود لميزات DeepL Pro",
|
||||
"Advanced AI Tools": "أدوات ذكاء اصطناعي متقدمة",
|
||||
"Early Feature Access": "وصول مبكر للميزات",
|
||||
"10 GB Cloud Sync Space": "مزامنة سحابية بمساحة تخزين 10 جيجابايت",
|
||||
"Loading profile...": "جارٍ تحميل الملف الشخصي...",
|
||||
"Features": "الميزات",
|
||||
"Delete Account": "حذف الحساب",
|
||||
"Delete Your Account?": "حذف حسابك؟",
|
||||
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "لا يمكن التراجع عن هذا الإجراء. سيتم حذف جميع بياناتك في السحابة بشكل دائم.",
|
||||
"Delete Permanently": "حذف نهائي",
|
||||
"Free Tier": "الفئة المجانية",
|
||||
"Plus Tier": "فئة Plus",
|
||||
"Pro Tier": "فئة Pro",
|
||||
"RTL Direction": "الاتجاه من اليمين إلى اليسار",
|
||||
"Maximum Column Height": "الارتفاع الأقصى للعمود",
|
||||
"Maximum Column Width": "العرض الأقصى للعمود",
|
||||
@@ -393,5 +376,44 @@
|
||||
"Show Remaining Pages": "عرض الصفحات المتبقية",
|
||||
"Source Han Serif CN VF": "Source Han Serif",
|
||||
"Huiwen-mincho": "Huiwen Mincho",
|
||||
"KingHwa_OldSong": "KingHwa Song"
|
||||
"KingHwa_OldSong": "KingHwa Song",
|
||||
"Manage Subscription": "إدارة الاشتراك",
|
||||
"Coming Soon": "قريبًا",
|
||||
"Upgrade to {{plan}}": "الترقية إلى {{plan}}",
|
||||
"Upgrade to Plus or Pro": "الترقية إلى Plus أو Pro",
|
||||
"Current Plan": "الخطة الحالية",
|
||||
"Plan Limits": "حدود الخطة",
|
||||
"Available Plans": "الخطط المتاحة",
|
||||
"{{current}} of {{all}}": "{{current}} من {{all}}",
|
||||
"Failed to manage subscription. Please try again later.": "فشل في إدارة الاشتراك. يرجى المحاولة مرة أخرى لاحقًا.",
|
||||
"Processing your payment...": "جارٍ معالجة الدفع...",
|
||||
"Please wait while we confirm your subscription.": "يرجى الانتظار بينما نقوم بتأكيد اشتراكك.",
|
||||
"Payment Processing": "معالجة الدفع",
|
||||
"Your payment is being processed. This usually takes a few moments.": "يتم الآن معالجة الدفع الخاص بك. عادةً ما يستغرق ذلك بضع لحظات.",
|
||||
"Payment Failed": "فشل الدفع",
|
||||
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "تعذر علينا معالجة اشتراكك. يرجى المحاولة مرة أخرى أو التواصل مع الدعم إذا استمرت المشكلة.",
|
||||
"Back to Profile": "العودة إلى الملف الشخصي",
|
||||
"Subscription Successful!": "تم الاشتراك بنجاح!",
|
||||
"Thank you for your subscription! Your payment has been processed successfully.": "شكرًا لاشتراكك! تم معالجة الدفع بنجاح.",
|
||||
"Email:": "البريد الإلكتروني:",
|
||||
"Plan:": "الخطة:",
|
||||
"Amount:": "المبلغ:",
|
||||
"Subscription ID:": "رقم الاشتراك:",
|
||||
"Go to Library": "الانتقال إلى المكتبة",
|
||||
"Need help? Contact our support team at support@readest.com": "تحتاج مساعدة؟ تواصل مع فريق الدعم على support@readest.com",
|
||||
"Free Plan": "الخطة المجانية",
|
||||
"month": "شهر",
|
||||
"Unlimited Text-to-Speech Hours": "ساعات تحويل النص إلى كلام غير محدودة",
|
||||
"DeepL Free Access (10K characters/day)": "وصول مجاني إلى DeepL (10 آلاف حرف يوميًا)",
|
||||
"AI Translations (per day)": "ترجمات بالذكاء الاصطناعي (يوميًا)",
|
||||
"Cloud Storage": "تخزين سحابي",
|
||||
"Plus Plan": "خطة Plus",
|
||||
"Includes All Free Plan Benefits": "تتضمن جميع مزايا الخطة المجانية",
|
||||
"Basic AI Translations": "ترجمات أساسية بالذكاء الاصطناعي",
|
||||
"DeepL Pro Access (50K characters/day)": "وصول احترافي إلى DeepL (50 ألف حرف يوميًا)",
|
||||
"2 GB Cloud Sync Space": "2 جيجابايت مساحة مزامنة سحابية",
|
||||
"Pro Plan": "خطة Pro",
|
||||
"Includes All Plus Plan Benefits": "تتضمن جميع مزايا خطة Plus",
|
||||
"More AI Translations": "المزيد من الترجمات بالذكاء الاصطناعي",
|
||||
"DeepL Pro Access (200K characters/day)": "وصول احترافي إلى DeepL (200 ألف حرف يوميًا)"
|
||||
}
|
||||
|
||||
@@ -183,35 +183,18 @@
|
||||
"Sign in with GitHub": "Mit GitHub anmelden",
|
||||
"Account": "Konto",
|
||||
"Failed to delete user. Please try again later.": "Benutzer konnte nicht gelöscht werden. Bitte versuchen Sie es später erneut.",
|
||||
"Unlimited Offline/Online Reading": "Unbegrenztes Offline/Online Lesen",
|
||||
"Unlimited Cloud Sync Devices": "Unbegrenzte Cloud-Synchronisierungsgeräte",
|
||||
"Essential Text-to-Speech Voices": "Grundlegende Text-zu-Sprache-Stimmen",
|
||||
"DeepL Free Access": "Kostenloser DeepL-Zugang",
|
||||
"Community Support": "Community-Support",
|
||||
"500 MB Cloud Sync Space": "500 MB Cloud-Synchronisierungsspeicher",
|
||||
"Includes All Free Tier Benefits": "Beinhaltet alle Vorteile der kostenlosen Stufe",
|
||||
"AI Summaries": "KI-Zusammenfassungen",
|
||||
"AI Translations": "KI-Übersetzungen",
|
||||
"Priority Support": "Bevorzugter Support",
|
||||
"DeepL Pro Access": "DeepL Pro-Zugang",
|
||||
"Expanded Text-to-Speech Voices": "Erweiterte Text-zu-Sprache-Stimmen",
|
||||
"2000 MB Cloud Sync Space": "2000 MB Cloud-Synchronisierungsspeicher",
|
||||
"Includes All Plus Tier Benefits": "Beinhaltet alle Vorteile der Plus-Stufe",
|
||||
"Unlimited AI Summaries": "Unbegrenzte KI-Zusammenfassungen",
|
||||
"Unlimited AI Translations": "Unbegrenzte KI-Übersetzungen",
|
||||
"Unlimited DeepL Pro Access": "Unbegrenzter DeepL Pro-Zugang",
|
||||
"Advanced AI Tools": "Fortgeschrittene KI-Tools",
|
||||
"Early Feature Access": "Früher Zugang zu neuen Funktionen",
|
||||
"10 GB Cloud Sync Space": "10 GB Cloud-Synchronisierungsspeicher",
|
||||
"Loading profile...": "Profil wird geladen...",
|
||||
"Features": "Funktionen",
|
||||
"Delete Account": "Konto löschen",
|
||||
"Delete Your Account?": "Ihr Konto löschen?",
|
||||
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "Diese Aktion kann nicht rückgängig gemacht werden. Alle Ihre Daten in der Cloud werden dauerhaft gelöscht.",
|
||||
"Delete Permanently": "Dauerhaft löschen",
|
||||
"Free Tier": "Kostenlose Stufe",
|
||||
"Plus Tier": "Plus-Stufe",
|
||||
"Pro Tier": "Pro-Stufe",
|
||||
"RTL Direction": "RTL-Richtung",
|
||||
"Maximum Column Height": "Maximale Spaltenhöhe",
|
||||
"Maximum Column Width": "Maximale Spaltenbreite",
|
||||
@@ -377,5 +360,44 @@
|
||||
"Show Remaining Pages": "Verbleibende Seiten anzeigen",
|
||||
"Source Han Serif CN VF": "Source Han Serif",
|
||||
"Huiwen-mincho": "Huiwen Mincho",
|
||||
"KingHwa_OldSong": "KingHwa Song"
|
||||
"KingHwa_OldSong": "KingHwa Song",
|
||||
"Manage Subscription": "Abo verwalten",
|
||||
"Coming Soon": "Demnächst verfügbar",
|
||||
"Upgrade to {{plan}}": "Upgrade auf {{plan}}",
|
||||
"Upgrade to Plus or Pro": "Upgrade auf Plus oder Pro",
|
||||
"Current Plan": "Aktueller Tarif",
|
||||
"Plan Limits": "Tariflimits",
|
||||
"Available Plans": "Verfügbare Tarife",
|
||||
"{{current}} of {{all}}": "{{current}} von {{all}}",
|
||||
"Failed to manage subscription. Please try again later.": "Verwaltung des Abos fehlgeschlagen. Bitte versuchen Sie es später erneut.",
|
||||
"Processing your payment...": "Zahlung wird verarbeitet...",
|
||||
"Please wait while we confirm your subscription.": "Bitte warten Sie, während wir Ihr Abo bestätigen.",
|
||||
"Payment Processing": "Zahlung wird verarbeitet",
|
||||
"Your payment is being processed. This usually takes a few moments.": "Ihre Zahlung wird verarbeitet. Dies dauert normalerweise nur wenige Augenblicke.",
|
||||
"Payment Failed": "Zahlung fehlgeschlagen",
|
||||
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "Ihr Abo konnte nicht verarbeitet werden. Bitte versuchen Sie es erneut oder kontaktieren Sie den Support, falls das Problem weiterhin besteht.",
|
||||
"Back to Profile": "Zurück zum Profil",
|
||||
"Subscription Successful!": "Abo erfolgreich!",
|
||||
"Thank you for your subscription! Your payment has been processed successfully.": "Vielen Dank für Ihr Abo! Die Zahlung wurde erfolgreich verarbeitet.",
|
||||
"Email:": "E-Mail:",
|
||||
"Plan:": "Tarif:",
|
||||
"Amount:": "Betrag:",
|
||||
"Subscription ID:": "Abo-ID:",
|
||||
"Go to Library": "Zur Bibliothek",
|
||||
"Need help? Contact our support team at support@readest.com": "Brauchen Sie Hilfe? Kontaktieren Sie unser Support-Team unter support@readest.com",
|
||||
"Free Plan": "Gratis-Tarif",
|
||||
"month": "Monat",
|
||||
"Unlimited Text-to-Speech Hours": "Unbegrenzte Text-to-Speech-Stunden",
|
||||
"DeepL Free Access (10K characters/day)": "Kostenfreier DeepL-Zugang (10.000 Zeichen/Tag)",
|
||||
"AI Translations (per day)": "KI-Übersetzungen (pro Tag)",
|
||||
"Cloud Storage": "Cloud-Speicher",
|
||||
"Plus Plan": "Plus-Tarif",
|
||||
"Includes All Free Plan Benefits": "Enthält alle Vorteile des Gratis-Tarifs",
|
||||
"Basic AI Translations": "Basis-KI-Übersetzungen",
|
||||
"DeepL Pro Access (50K characters/day)": "DeepL Pro-Zugang (50.000 Zeichen/Tag)",
|
||||
"2 GB Cloud Sync Space": "2 GB Cloud-Speicherplatz",
|
||||
"Pro Plan": "Pro-Tarif",
|
||||
"Includes All Plus Plan Benefits": "Enthält alle Vorteile des Plus-Tarifs",
|
||||
"More AI Translations": "Mehr KI-Übersetzungen",
|
||||
"DeepL Pro Access (200K characters/day)": "DeepL Pro-Zugang (200.000 Zeichen/Tag)"
|
||||
}
|
||||
|
||||
@@ -183,35 +183,18 @@
|
||||
"Sign in with GitHub": "Σύνδεση με GitHub",
|
||||
"Account": "Λογαριασμός",
|
||||
"Failed to delete user. Please try again later.": "Αποτυχία διαγραφής χρήστη. Παρακαλώ δοκιμάστε ξανά αργότερα.",
|
||||
"Unlimited Offline/Online Reading": "Απεριόριστη ανάγνωση εκτός/εντός σύνδεσης",
|
||||
"Unlimited Cloud Sync Devices": "Απεριόριστες συσκευές συγχρονισμού Cloud",
|
||||
"Essential Text-to-Speech Voices": "Βασικές φωνές μετατροπής κειμένου σε ομιλία",
|
||||
"DeepL Free Access": "Δωρεάν πρόσβαση DeepL",
|
||||
"Community Support": "Υποστήριξη κοινότητας",
|
||||
"500 MB Cloud Sync Space": "500 MB χώρος συγχρονισμού Cloud",
|
||||
"Includes All Free Tier Benefits": "Περιλαμβάνει όλα τα οφέλη της δωρεάν βαθμίδας",
|
||||
"AI Summaries": "Περιλήψεις AI",
|
||||
"AI Translations": "Μεταφράσεις AI",
|
||||
"Priority Support": "Υποστήριξη προτεραιότητας",
|
||||
"DeepL Pro Access": "Πρόσβαση DeepL Pro",
|
||||
"Expanded Text-to-Speech Voices": "Διευρυμένες φωνές μετατροπής κειμένου σε ομιλία",
|
||||
"2000 MB Cloud Sync Space": "2000 MB χώρος συγχρονισμού Cloud",
|
||||
"Includes All Plus Tier Benefits": "Περιλαμβάνει όλα τα οφέλη της βαθμίδας Plus",
|
||||
"Unlimited AI Summaries": "Απεριόριστες περιλήψεις AI",
|
||||
"Unlimited AI Translations": "Απεριόριστες μεταφράσεις AI",
|
||||
"Unlimited DeepL Pro Access": "Απεριόριστη πρόσβαση DeepL Pro",
|
||||
"Advanced AI Tools": "Προηγμένα εργαλεία AI",
|
||||
"Early Feature Access": "Πρώιμη πρόσβαση σε λειτουργίες",
|
||||
"10 GB Cloud Sync Space": "10 GB χώρος συγχρονισμού Cloud",
|
||||
"Loading profile...": "Φόρτωση προφίλ...",
|
||||
"Features": "Χαρακτηριστικά",
|
||||
"Delete Account": "Διαγραφή λογαριασμού",
|
||||
"Delete Your Account?": "Διαγραφή του λογαριασμού σας;",
|
||||
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "Αυτή η ενέργεια δεν μπορεί να αναιρεθεί. Όλα τα δεδομένα σας στο cloud θα διαγραφούν μόνιμα.",
|
||||
"Delete Permanently": "Μόνιμη διαγραφή",
|
||||
"Free Tier": "Δωρεάν βαθμίδα",
|
||||
"Plus Tier": "Βαθμίδα Plus",
|
||||
"Pro Tier": "Βαθμίδα Pro",
|
||||
"RTL Direction": "Κατεύθυνση RTL",
|
||||
"Maximum Column Height": "Μέγιστο ύψος στήλης",
|
||||
"Maximum Column Width": "Μέγιστο πλάτος στήλης",
|
||||
@@ -377,5 +360,44 @@
|
||||
"Show Remaining Pages": "Εμφάνιση υπολοίπων",
|
||||
"Source Han Serif CN VF": "Source Han Serif",
|
||||
"Huiwen-mincho": "Huiwen Mincho",
|
||||
"KingHwa_OldSong": "KingHwa Song"
|
||||
"KingHwa_OldSong": "KingHwa Song",
|
||||
"Manage Subscription": "Διαχείριση συνδρομής",
|
||||
"Coming Soon": "Έρχεται σύντομα",
|
||||
"Upgrade to {{plan}}": "Αναβάθμιση σε {{plan}}",
|
||||
"Upgrade to Plus or Pro": "Αναβάθμιση σε Plus ή Pro",
|
||||
"Current Plan": "Τρέχον πρόγραμμα",
|
||||
"Plan Limits": "Όρια προγράμματος",
|
||||
"Available Plans": "Διαθέσιμα προγράμματα",
|
||||
"{{current}} of {{all}}": "{{current}} από {{all}}",
|
||||
"Failed to manage subscription. Please try again later.": "Αποτυχία διαχείρισης της συνδρομής. Παρακαλώ δοκιμάστε ξανά αργότερα.",
|
||||
"Processing your payment...": "Επεξεργασία πληρωμής...",
|
||||
"Please wait while we confirm your subscription.": "Παρακαλώ περιμένετε όσο επιβεβαιώνουμε τη συνδρομή σας.",
|
||||
"Payment Processing": "Επεξεργασία πληρωμής",
|
||||
"Your payment is being processed. This usually takes a few moments.": "Η πληρωμή σας επεξεργάζεται. Συνήθως διαρκεί λίγες στιγμές.",
|
||||
"Payment Failed": "Η πληρωμή απέτυχε",
|
||||
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "Δεν ήταν δυνατή η επεξεργασία της συνδρομής σας. Παρακαλώ προσπαθήστε ξανά ή επικοινωνήστε με την υποστήριξη αν το πρόβλημα συνεχιστεί.",
|
||||
"Back to Profile": "Επιστροφή στο προφίλ",
|
||||
"Subscription Successful!": "Η συνδρομή ολοκληρώθηκε!",
|
||||
"Thank you for your subscription! Your payment has been processed successfully.": "Σας ευχαριστούμε για τη συνδρομή σας! Η πληρωμή ολοκληρώθηκε με επιτυχία.",
|
||||
"Email:": "Email:",
|
||||
"Plan:": "Πρόγραμμα:",
|
||||
"Amount:": "Ποσό:",
|
||||
"Subscription ID:": "ID συνδρομής:",
|
||||
"Go to Library": "Μετάβαση στη βιβλιοθήκη",
|
||||
"Need help? Contact our support team at support@readest.com": "Χρειάζεστε βοήθεια; Επικοινωνήστε με την υποστήριξη στο support@readest.com",
|
||||
"Free Plan": "Δωρεάν πρόγραμμα",
|
||||
"month": "μήνας",
|
||||
"Unlimited Text-to-Speech Hours": "Απεριόριστες ώρες μετατροπής κειμένου σε ομιλία",
|
||||
"DeepL Free Access (10K characters/day)": "Δωρεάν πρόσβαση στο DeepL (10.000 χαρακτήρες/ημέρα)",
|
||||
"AI Translations (per day)": "Μεταφράσεις AI (ανά ημέρα)",
|
||||
"Cloud Storage": "Αποθήκευση στο cloud",
|
||||
"Plus Plan": "Πρόγραμμα Plus",
|
||||
"Includes All Free Plan Benefits": "Περιλαμβάνει όλα τα οφέλη του δωρεάν προγράμματος",
|
||||
"Basic AI Translations": "Βασικές μεταφράσεις AI",
|
||||
"DeepL Pro Access (50K characters/day)": "Pro πρόσβαση στο DeepL (50.000 χαρακτήρες/ημέρα)",
|
||||
"2 GB Cloud Sync Space": "2 GB χώρος συγχρονισμού στο cloud",
|
||||
"Pro Plan": "Πρόγραμμα Pro",
|
||||
"Includes All Plus Plan Benefits": "Περιλαμβάνει όλα τα οφέλη του Plus προγράμματος",
|
||||
"More AI Translations": "Περισσότερες μεταφράσεις AI",
|
||||
"DeepL Pro Access (200K characters/day)": "Pro πρόσβαση στο DeepL (200.000 χαρακτήρες/ημέρα)"
|
||||
}
|
||||
|
||||
@@ -183,35 +183,18 @@
|
||||
"Sign in with GitHub": "Iniciar sesión con GitHub",
|
||||
"Account": "Cuenta",
|
||||
"Failed to delete user. Please try again later.": "Error al eliminar usuario. Por favor, inténtelo de nuevo más tarde.",
|
||||
"Unlimited Offline/Online Reading": "Lectura sin límites en línea/sin conexión",
|
||||
"Unlimited Cloud Sync Devices": "Sincronización ilimitada de dispositivos en la nube",
|
||||
"Essential Text-to-Speech Voices": "Voces esenciales de texto a voz",
|
||||
"DeepL Free Access": "Acceso gratuito a DeepL",
|
||||
"Community Support": "Soporte comunitario",
|
||||
"500 MB Cloud Sync Space": "500 MB de espacio de sincronización en la nube",
|
||||
"Includes All Free Tier Benefits": "Incluye todos los beneficios del nivel gratuito",
|
||||
"AI Summaries": "Resúmenes con IA",
|
||||
"AI Translations": "Traducciones con IA",
|
||||
"Priority Support": "Soporte prioritario",
|
||||
"DeepL Pro Access": "Acceso a DeepL Pro",
|
||||
"Expanded Text-to-Speech Voices": "Voces ampliadas de texto a voz",
|
||||
"2000 MB Cloud Sync Space": "2000 MB de espacio de sincronización en la nube",
|
||||
"Includes All Plus Tier Benefits": "Incluye todos los beneficios del nivel Plus",
|
||||
"Unlimited AI Summaries": "Resúmenes ilimitados con IA",
|
||||
"Unlimited AI Translations": "Traducciones ilimitadas con IA",
|
||||
"Unlimited DeepL Pro Access": "Acceso ilimitado a DeepL Pro",
|
||||
"Advanced AI Tools": "Herramientas avanzadas de IA",
|
||||
"Early Feature Access": "Acceso anticipado a funciones",
|
||||
"10 GB Cloud Sync Space": "10 GB de espacio de sincronización en la nube",
|
||||
"Loading profile...": "Cargando perfil...",
|
||||
"Features": "Características",
|
||||
"Delete Account": "Eliminar cuenta",
|
||||
"Delete Your Account?": "¿Eliminar tu cuenta?",
|
||||
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "Esta acción no se puede deshacer. Todos tus datos en la nube se eliminarán permanentemente.",
|
||||
"Delete Permanently": "Eliminar permanentemente",
|
||||
"Free Tier": "Nivel gratuito",
|
||||
"Plus Tier": "Nivel Plus",
|
||||
"Pro Tier": "Nivel Pro",
|
||||
"RTL Direction": "Dirección RTL",
|
||||
"Maximum Column Height": "Altura máxima de columna",
|
||||
"Maximum Column Width": "Ancho máximo de columna",
|
||||
@@ -381,5 +364,44 @@
|
||||
"Show Remaining Pages": "Mostrar resto",
|
||||
"Source Han Serif CN VF": "Source Han Serif",
|
||||
"Huiwen-mincho": "Huiwen Mincho",
|
||||
"KingHwa_OldSong": "KingHwa Song"
|
||||
"KingHwa_OldSong": "KingHwa Song",
|
||||
"Manage Subscription": "Gestionar suscripción",
|
||||
"Coming Soon": "Próximamente",
|
||||
"Upgrade to {{plan}}": "Actualizar a {{plan}}",
|
||||
"Upgrade to Plus or Pro": "Actualizar a Plus o Pro",
|
||||
"Current Plan": "Plan actual",
|
||||
"Plan Limits": "Límites del plan",
|
||||
"Available Plans": "Planes disponibles",
|
||||
"{{current}} of {{all}}": "{{current}} de {{all}}",
|
||||
"Failed to manage subscription. Please try again later.": "No se pudo gestionar la suscripción. Por favor, inténtalo de nuevo más tarde.",
|
||||
"Processing your payment...": "Procesando tu pago...",
|
||||
"Please wait while we confirm your subscription.": "Espera mientras confirmamos tu suscripción.",
|
||||
"Payment Processing": "Procesando pago",
|
||||
"Payment Failed": "El pago ha fallado",
|
||||
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "No pudimos procesar tu suscripción. Inténtalo de nuevo o contacta con soporte si el problema persiste.",
|
||||
"Back to Profile": "Volver al perfil",
|
||||
"Subscription Successful!": "¡Suscripción exitosa!",
|
||||
"Thank you for your subscription! Your payment has been processed successfully.": "¡Gracias por tu suscripción! Tu pago se ha procesado correctamente.",
|
||||
"Email:": "Correo electrónico:",
|
||||
"Plan:": "Plan:",
|
||||
"Amount:": "Importe:",
|
||||
"Subscription ID:": "ID de suscripción:",
|
||||
"Go to Library": "Ir a la biblioteca",
|
||||
"Need help? Contact our support team at support@readest.com": "¿Necesitas ayuda? Contacta con nuestro equipo de soporte en support@readest.com",
|
||||
"Free Plan": "Plan gratuito",
|
||||
"month": "mes",
|
||||
"Unlimited Text-to-Speech Hours": "Horas ilimitadas de texto a voz",
|
||||
"DeepL Free Access (10K characters/day)": "Acceso gratuito a DeepL (10.000 caracteres/día)",
|
||||
"AI Translations (per day)": "Traducciones con IA (por día)",
|
||||
"Cloud Storage": "Almacenamiento en la nube",
|
||||
"Plus Plan": "Plan Plus",
|
||||
"Includes All Free Plan Benefits": "Incluye todos los beneficios del plan gratuito",
|
||||
"Basic AI Translations": "Traducciones básicas con IA",
|
||||
"DeepL Pro Access (50K characters/day)": "Acceso Pro a DeepL (50.000 caracteres/día)",
|
||||
"2 GB Cloud Sync Space": "2 GB de espacio de sincronización en la nube",
|
||||
"Pro Plan": "Plan Pro",
|
||||
"Includes All Plus Plan Benefits": "Incluye todos los beneficios del plan Plus",
|
||||
"More AI Translations": "Más traducciones con IA",
|
||||
"DeepL Pro Access (200K characters/day)": "Acceso Pro a DeepL (200.000 caracteres/día)",
|
||||
"Your payment is being processed. This usually takes a few moments.": "Tu pago se está procesando. Normalmente tarda unos momentos."
|
||||
}
|
||||
|
||||
@@ -183,35 +183,18 @@
|
||||
"Sign in with GitHub": "Se connecter avec GitHub",
|
||||
"Account": "Compte",
|
||||
"Failed to delete user. Please try again later.": "Échec de la suppression de l'utilisateur. Veuillez réessayer plus tard.",
|
||||
"Unlimited Offline/Online Reading": "Lecture illimitée hors ligne/en ligne",
|
||||
"Unlimited Cloud Sync Devices": "Synchronisation cloud sur appareils illimitée",
|
||||
"Essential Text-to-Speech Voices": "Voix de synthèse vocale essentielles",
|
||||
"DeepL Free Access": "Accès gratuit à DeepL",
|
||||
"Community Support": "Support communautaire",
|
||||
"500 MB Cloud Sync Space": "500 Mo d'espace de synchronisation cloud",
|
||||
"Includes All Free Tier Benefits": "Inclut tous les avantages du niveau gratuit",
|
||||
"AI Summaries": "Résumés par IA",
|
||||
"AI Translations": "Traductions par IA",
|
||||
"Priority Support": "Support prioritaire",
|
||||
"DeepL Pro Access": "Accès à DeepL Pro",
|
||||
"Expanded Text-to-Speech Voices": "Voix de synthèse vocale étendues",
|
||||
"2000 MB Cloud Sync Space": "2000 Mo d'espace de synchronisation cloud",
|
||||
"Includes All Plus Tier Benefits": "Inclut tous les avantages du niveau Plus",
|
||||
"Unlimited AI Summaries": "Résumés par IA illimités",
|
||||
"Unlimited AI Translations": "Traductions par IA illimitées",
|
||||
"Unlimited DeepL Pro Access": "Accès illimité à DeepL Pro",
|
||||
"Advanced AI Tools": "Outils IA avancés",
|
||||
"Early Feature Access": "Accès anticipé aux fonctionnalités",
|
||||
"10 GB Cloud Sync Space": "10 Go d'espace de synchronisation cloud",
|
||||
"Loading profile...": "Chargement du profil...",
|
||||
"Features": "Fonctionnalités",
|
||||
"Delete Account": "Supprimer le compte",
|
||||
"Delete Your Account?": "Supprimer votre compte ?",
|
||||
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "Cette action est irréversible. Toutes vos données dans le cloud seront définitivement supprimées.",
|
||||
"Delete Permanently": "Supprimer définitivement",
|
||||
"Free Tier": "Niveau gratuit",
|
||||
"Plus Tier": "Niveau Plus",
|
||||
"Pro Tier": "Niveau Pro",
|
||||
"RTL Direction": "Direction RTL",
|
||||
"Maximum Column Height": "Hauteur maximale de colonne",
|
||||
"Maximum Column Width": "Largeur maximale de colonne",
|
||||
@@ -381,5 +364,44 @@
|
||||
"Show Remaining Pages": "Voir restantes",
|
||||
"Source Han Serif CN VF": "Source Han Serif",
|
||||
"Huiwen-mincho": "Huiwen Mincho",
|
||||
"KingHwa_OldSong": "KingHwa Song"
|
||||
"KingHwa_OldSong": "KingHwa Song",
|
||||
"Manage Subscription": "Gérer l’abonnement",
|
||||
"Coming Soon": "Bientôt disponible",
|
||||
"Upgrade to {{plan}}": "Passer à {{plan}}",
|
||||
"Upgrade to Plus or Pro": "Passer à Plus ou Pro",
|
||||
"Current Plan": "Abonnement actuel",
|
||||
"Plan Limits": "Limites de l’abonnement",
|
||||
"Available Plans": "Abonnements disponibles",
|
||||
"{{current}} of {{all}}": "{{current}} sur {{all}}",
|
||||
"Failed to manage subscription. Please try again later.": "Échec de la gestion de l’abonnement. Veuillez réessayer plus tard.",
|
||||
"Processing your payment...": "Traitement de votre paiement...",
|
||||
"Please wait while we confirm your subscription.": "Veuillez patienter pendant la confirmation de votre abonnement.",
|
||||
"Payment Processing": "Traitement du paiement",
|
||||
"Your payment is being processed. This usually takes a few moments.": "Votre paiement est en cours de traitement. Cela prend généralement quelques instants.",
|
||||
"Payment Failed": "Le paiement a échoué",
|
||||
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "Nous n’avons pas pu traiter votre abonnement. Veuillez réessayer ou contacter le support si le problème persiste.",
|
||||
"Back to Profile": "Retour au profil",
|
||||
"Subscription Successful!": "Abonnement réussi !",
|
||||
"Thank you for your subscription! Your payment has been processed successfully.": "Merci pour votre abonnement ! Votre paiement a été traité avec succès.",
|
||||
"Email:": "E-mail :",
|
||||
"Plan:": "Abonnement :",
|
||||
"Amount:": "Montant :",
|
||||
"Subscription ID:": "ID d’abonnement :",
|
||||
"Go to Library": "Aller à la bibliothèque",
|
||||
"Need help? Contact our support team at support@readest.com": "Besoin d’aide ? Contactez notre équipe à support@readest.com",
|
||||
"Free Plan": "Abonnement gratuit",
|
||||
"month": "mois",
|
||||
"Unlimited Text-to-Speech Hours": "Heures illimitées de synthèse vocale",
|
||||
"DeepL Free Access (10K characters/day)": "Accès gratuit à DeepL (10 000 caractères/jour)",
|
||||
"AI Translations (per day)": "Traductions IA (par jour)",
|
||||
"Cloud Storage": "Stockage cloud",
|
||||
"Plus Plan": "Abonnement Plus",
|
||||
"Includes All Free Plan Benefits": "Inclut tous les avantages de l’abonnement gratuit",
|
||||
"Basic AI Translations": "Traductions IA de base",
|
||||
"DeepL Pro Access (50K characters/day)": "Accès Pro à DeepL (50 000 caractères/jour)",
|
||||
"2 GB Cloud Sync Space": "2 Go d’espace de synchronisation cloud",
|
||||
"Pro Plan": "Abonnement Pro",
|
||||
"Includes All Plus Plan Benefits": "Inclut tous les avantages de l’abonnement Plus",
|
||||
"More AI Translations": "Plus de traductions IA",
|
||||
"DeepL Pro Access (200K characters/day)": "Accès Pro à DeepL (200 000 caractères/jour)"
|
||||
}
|
||||
|
||||
@@ -183,35 +183,18 @@
|
||||
"Sign in with GitHub": "GitHub के साथ साइन इन करें",
|
||||
"Account": "खाता",
|
||||
"Failed to delete user. Please try again later.": "उपयोगकर्ता को हटाने में विफल। कृपया बाद में पुनः प्रयास करें।",
|
||||
"Unlimited Offline/Online Reading": "असीमित ऑफलाइन/ऑनलाइन पढ़ना",
|
||||
"Unlimited Cloud Sync Devices": "असीमित क्लाउड सिंक उपकरण",
|
||||
"Essential Text-to-Speech Voices": "आवश्यक टेक्स्ट-टू-स्पीच आवाज़ें",
|
||||
"DeepL Free Access": "DeepL मुफ्त पहुंच",
|
||||
"Community Support": "सामुदायिक सहायता",
|
||||
"500 MB Cloud Sync Space": "500 MB क्लाउड सिंक स्पेस",
|
||||
"Includes All Free Tier Benefits": "सभी फ्री टियर लाभ शामिल हैं",
|
||||
"AI Summaries": "AI सारांश",
|
||||
"AI Translations": "AI अनुवाद",
|
||||
"Priority Support": "प्राथमिकता सहायता",
|
||||
"DeepL Pro Access": "DeepL प्रो पहुंच",
|
||||
"Expanded Text-to-Speech Voices": "विस्तारित टेक्स्ट-टू-स्पीच आवाज़ें",
|
||||
"2000 MB Cloud Sync Space": "2000 MB क्लाउड सिंक स्पेस",
|
||||
"Includes All Plus Tier Benefits": "सभी प्लस टियर लाभ शामिल हैं",
|
||||
"Unlimited AI Summaries": "असीमित AI सारांश",
|
||||
"Unlimited AI Translations": "असीमित AI अनुवाद",
|
||||
"Unlimited DeepL Pro Access": "असीमित DeepL प्रो पहुंच",
|
||||
"Advanced AI Tools": "उन्नत AI टूल्स",
|
||||
"Early Feature Access": "प्रारंभिक फीचर पहुंच",
|
||||
"10 GB Cloud Sync Space": "10 GB क्लाउड सिंक स्पेस",
|
||||
"Loading profile...": "प्रोफ़ाइल लोड हो रहा है...",
|
||||
"Features": "विशेषताएं",
|
||||
"Delete Account": "खाता हटाएं",
|
||||
"Delete Your Account?": "अपना खाता हटाएं?",
|
||||
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "यह क्रिया पूर्ववत नहीं की जा सकती। क्लाउड में आपका सभी डेटा स्थायी रूप से हटा दिया जाएगा।",
|
||||
"Delete Permanently": "स्थायी रूप से हटाएं",
|
||||
"Free Tier": "फ्री टियर",
|
||||
"Plus Tier": "प्लस टियर",
|
||||
"Pro Tier": "प्रो टियर",
|
||||
"RTL Direction": "RTL दिशा",
|
||||
"Maximum Column Height": "कॉलम की अधिकतम ऊँचाई",
|
||||
"Maximum Column Width": "कॉलम की अधिकतम चौड़ाई",
|
||||
@@ -377,5 +360,44 @@
|
||||
"Show Remaining Pages": "शेष पृष्ठ दिखाएँ",
|
||||
"Source Han Serif CN VF": "Source Han Serif",
|
||||
"Huiwen-mincho": "Huiwen Mincho",
|
||||
"KingHwa_OldSong": "KingHwa Song"
|
||||
"KingHwa_OldSong": "KingHwa Song",
|
||||
"Manage Subscription": "सदस्यता प्रबंधित करें",
|
||||
"Coming Soon": "जल्द आ रहा है",
|
||||
"Upgrade to {{plan}}": "{{plan}} में अपग्रेड करें",
|
||||
"Upgrade to Plus or Pro": "Plus या Pro में अपग्रेड करें",
|
||||
"Current Plan": "वर्तमान योजना",
|
||||
"Plan Limits": "योजना की सीमाएँ",
|
||||
"Available Plans": "उपलब्ध योजनाएँ",
|
||||
"{{current}} of {{all}}": "{{all}} में से {{current}}",
|
||||
"Failed to manage subscription. Please try again later.": "सदस्यता प्रबंधित करने में विफल। कृपया बाद में पुनः प्रयास करें।",
|
||||
"Processing your payment...": "आपका भुगतान संसाधित हो रहा है...",
|
||||
"Please wait while we confirm your subscription.": "कृपया प्रतीक्षा करें, हम आपकी सदस्यता की पुष्टि कर रहे हैं।",
|
||||
"Payment Processing": "भुगतान संसाधित हो रहा है",
|
||||
"Your payment is being processed. This usually takes a few moments.": "आपका भुगतान संसाधित हो रहा है। इसमें कुछ क्षण लग सकते हैं।",
|
||||
"Payment Failed": "भुगतान विफल",
|
||||
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "हम आपकी सदस्यता संसाधित नहीं कर सके। कृपया पुनः प्रयास करें या समस्या बने रहने पर सहायता से संपर्क करें।",
|
||||
"Back to Profile": "प्रोफ़ाइल पर वापस जाएँ",
|
||||
"Subscription Successful!": "सदस्यता सफल हुई!",
|
||||
"Thank you for your subscription! Your payment has been processed successfully.": "आपकी सदस्यता के लिए धन्यवाद! आपका भुगतान सफलतापूर्वक संसाधित हो गया है।",
|
||||
"Email:": "ईमेल:",
|
||||
"Plan:": "योजना:",
|
||||
"Amount:": "राशि:",
|
||||
"Subscription ID:": "सदस्यता आईडी:",
|
||||
"Go to Library": "लाइब्रेरी पर जाएँ",
|
||||
"Need help? Contact our support team at support@readest.com": "मदद चाहिए? हमारी सहायता टीम से संपर्क करें: support@readest.com",
|
||||
"Free Plan": "मुफ्त योजना",
|
||||
"month": "महीना",
|
||||
"Unlimited Text-to-Speech Hours": "अनलिमिटेड पाठ-पाठ ध्वनि घंटे",
|
||||
"DeepL Free Access (10K characters/day)": "DeepL मुफ्त एक्सेस (10,000 अक्षर/दिन)",
|
||||
"AI Translations (per day)": "AI अनुवाद (प्रतिदिन)",
|
||||
"Cloud Storage": "क्लाउड स्टोरेज",
|
||||
"Plus Plan": "Plus योजना",
|
||||
"Includes All Free Plan Benefits": "सभी मुफ्त योजना के लाभ शामिल हैं",
|
||||
"Basic AI Translations": "मूल AI अनुवाद",
|
||||
"DeepL Pro Access (50K characters/day)": "DeepL प्रो एक्सेस (50,000 अक्षर/दिन)",
|
||||
"2 GB Cloud Sync Space": "2 जीबी क्लाउड सिंक स्पेस",
|
||||
"Pro Plan": "Pro योजना",
|
||||
"Includes All Plus Plan Benefits": "सभी Plus योजना के लाभ शामिल हैं",
|
||||
"More AI Translations": "और अधिक AI अनुवाद",
|
||||
"DeepL Pro Access (200K characters/day)": "DeepL प्रो एक्सेस (200,000 अक्षर/दिन)"
|
||||
}
|
||||
|
||||
@@ -183,35 +183,18 @@
|
||||
"Sign in with GitHub": "Masuk dengan GitHub",
|
||||
"Account": "Akun",
|
||||
"Failed to delete user. Please try again later.": "Gagal menghapus pengguna. Silakan coba lagi nanti.",
|
||||
"Unlimited Offline/Online Reading": "Membaca Offline/Online Tanpa Batas",
|
||||
"Unlimited Cloud Sync Devices": "Perangkat Sinkronisasi Cloud Tanpa Batas",
|
||||
"Essential Text-to-Speech Voices": "Suara Text-to-Speech Esensial",
|
||||
"DeepL Free Access": "Akses DeepL Gratis",
|
||||
"Community Support": "Dukungan Komunitas",
|
||||
"500 MB Cloud Sync Space": "Ruang Sinkronisasi Cloud 500 MB",
|
||||
"Includes All Free Tier Benefits": "Termasuk Semua Manfaat Tingkat Gratis",
|
||||
"AI Summaries": "Ringkasan AI",
|
||||
"AI Translations": "Terjemahan AI",
|
||||
"Priority Support": "Dukungan Prioritas",
|
||||
"DeepL Pro Access": "Akses DeepL Pro",
|
||||
"Expanded Text-to-Speech Voices": "Suara Text-to-Speech yang Diperluas",
|
||||
"2000 MB Cloud Sync Space": "Ruang Sinkronisasi Cloud 2000 MB",
|
||||
"Includes All Plus Tier Benefits": "Termasuk Semua Manfaat Tingkat Plus",
|
||||
"Unlimited AI Summaries": "Ringkasan AI Tanpa Batas",
|
||||
"Unlimited AI Translations": "Terjemahan AI Tanpa Batas",
|
||||
"Unlimited DeepL Pro Access": "Akses DeepL Pro Tanpa Batas",
|
||||
"Advanced AI Tools": "Alat AI Lanjutan",
|
||||
"Early Feature Access": "Akses Fitur Awal",
|
||||
"10 GB Cloud Sync Space": "Ruang Sinkronisasi Cloud 10 GB",
|
||||
"Loading profile...": "Memuat profil...",
|
||||
"Features": "Fitur",
|
||||
"Delete Account": "Hapus Akun",
|
||||
"Delete Your Account?": "Hapus Akun Anda?",
|
||||
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "Tindakan ini tidak dapat dibatalkan. Semua data Anda di cloud akan dihapus secara permanen.",
|
||||
"Delete Permanently": "Hapus Secara Permanen",
|
||||
"Free Tier": "Tingkat Gratis",
|
||||
"Plus Tier": "Tingkat Plus",
|
||||
"Pro Tier": "Tingkat Pro",
|
||||
"RTL Direction": "Arah RTL",
|
||||
"Maximum Column Height": "Tinggi Kolom Maksimum",
|
||||
"Maximum Column Width": "Lebar Kolom Maksimum",
|
||||
@@ -373,5 +356,44 @@
|
||||
"Show Remaining Pages": "Tampilkan halaman tersisa",
|
||||
"Source Han Serif CN VF": "Source Han Serif",
|
||||
"Huiwen-mincho": "Huiwen Mincho",
|
||||
"KingHwa_OldSong": "KingHwa Song"
|
||||
"KingHwa_OldSong": "KingHwa Song",
|
||||
"Manage Subscription": "Kelola Langganan",
|
||||
"Coming Soon": "Segera Hadir",
|
||||
"Upgrade to {{plan}}": "Tingkatkan ke {{plan}}",
|
||||
"Upgrade to Plus or Pro": "Tingkatkan ke Plus atau Pro",
|
||||
"Current Plan": "Paket Saat Ini",
|
||||
"Plan Limits": "Batas Paket",
|
||||
"Available Plans": "Paket yang Tersedia",
|
||||
"{{current}} of {{all}}": "{{current}} dari {{all}}",
|
||||
"Failed to manage subscription. Please try again later.": "Gagal mengelola langganan. Silakan coba lagi nanti.",
|
||||
"Processing your payment...": "Memproses pembayaran Anda...",
|
||||
"Please wait while we confirm your subscription.": "Mohon tunggu saat kami mengonfirmasi langganan Anda.",
|
||||
"Payment Processing": "Memproses Pembayaran",
|
||||
"Your payment is being processed. This usually takes a few moments.": "Pembayaran Anda sedang diproses. Ini biasanya memerlukan beberapa saat.",
|
||||
"Payment Failed": "Pembayaran Gagal",
|
||||
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "Kami tidak dapat memproses langganan Anda. Silakan coba lagi atau hubungi dukungan jika masalah berlanjut.",
|
||||
"Back to Profile": "Kembali ke Profil",
|
||||
"Subscription Successful!": "Langganan Berhasil!",
|
||||
"Thank you for your subscription! Your payment has been processed successfully.": "Terima kasih atas langganan Anda! Pembayaran Anda telah berhasil diproses.",
|
||||
"Email:": "Email:",
|
||||
"Plan:": "Paket:",
|
||||
"Amount:": "Jumlah:",
|
||||
"Subscription ID:": "ID Langganan:",
|
||||
"Go to Library": "Pergi ke Perpustakaan",
|
||||
"Need help? Contact our support team at support@readest.com": "Perlu bantuan? Hubungi tim dukungan kami di support@readest.com",
|
||||
"Free Plan": "Paket Gratis",
|
||||
"month": "bulan",
|
||||
"Unlimited Text-to-Speech Hours": "Jam Text-to-Speech Tanpa Batas",
|
||||
"DeepL Free Access (10K characters/day)": "Akses DeepL Gratis (10.000 karakter/hari)",
|
||||
"AI Translations (per day)": "Terjemahan AI (per hari)",
|
||||
"Cloud Storage": "Penyimpanan Cloud",
|
||||
"Plus Plan": "Paket Plus",
|
||||
"Includes All Free Plan Benefits": "Termasuk Semua Manfaat Paket Gratis",
|
||||
"Basic AI Translations": "Terjemahan AI Dasar",
|
||||
"DeepL Pro Access (50K characters/day)": "Akses DeepL Pro (50.000 karakter/hari)",
|
||||
"2 GB Cloud Sync Space": "2 GB Ruang Sinkronisasi Cloud",
|
||||
"Pro Plan": "Paket Pro",
|
||||
"Includes All Plus Plan Benefits": "Termasuk Semua Manfaat Paket Plus",
|
||||
"More AI Translations": "Lebih Banyak Terjemahan AI",
|
||||
"DeepL Pro Access (200K characters/day)": "Akses DeepL Pro (200.000 karakter/hari)"
|
||||
}
|
||||
|
||||
@@ -183,35 +183,18 @@
|
||||
"Sign in with GitHub": "Accedi con GitHub",
|
||||
"Account": "Account",
|
||||
"Failed to delete user. Please try again later.": "Impossibile eliminare l'utente. Riprova più tardi.",
|
||||
"Unlimited Offline/Online Reading": "Lettura offline/online illimitata",
|
||||
"Unlimited Cloud Sync Devices": "Sincronizzazione cloud su dispositivi illimitati",
|
||||
"Essential Text-to-Speech Voices": "Voci essenziali di sintesi vocale",
|
||||
"DeepL Free Access": "Accesso gratuito a DeepL",
|
||||
"Community Support": "Supporto della community",
|
||||
"500 MB Cloud Sync Space": "500 MB di spazio di sincronizzazione cloud",
|
||||
"Includes All Free Tier Benefits": "Include tutti i vantaggi del piano gratuito",
|
||||
"AI Summaries": "Riassunti AI",
|
||||
"AI Translations": "Traduzioni AI",
|
||||
"Priority Support": "Supporto prioritario",
|
||||
"DeepL Pro Access": "Accesso a DeepL Pro",
|
||||
"Expanded Text-to-Speech Voices": "Voci di sintesi vocale ampliate",
|
||||
"2000 MB Cloud Sync Space": "2000 MB di spazio di sincronizzazione cloud",
|
||||
"Includes All Plus Tier Benefits": "Include tutti i vantaggi del piano Plus",
|
||||
"Unlimited AI Summaries": "Riassunti AI illimitati",
|
||||
"Unlimited AI Translations": "Traduzioni AI illimitate",
|
||||
"Unlimited DeepL Pro Access": "Accesso illimitato a DeepL Pro",
|
||||
"Advanced AI Tools": "Strumenti AI avanzati",
|
||||
"Early Feature Access": "Accesso anticipato alle funzionalità",
|
||||
"10 GB Cloud Sync Space": "10 GB di spazio di sincronizzazione cloud",
|
||||
"Loading profile...": "Caricamento profilo...",
|
||||
"Features": "Funzionalità",
|
||||
"Delete Account": "Elimina account",
|
||||
"Delete Your Account?": "Eliminare il tuo account?",
|
||||
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "Questa azione non può essere annullata. Tutti i tuoi dati nel cloud verranno eliminati definitivamente.",
|
||||
"Delete Permanently": "Elimina definitivamente",
|
||||
"Free Tier": "Piano gratuito",
|
||||
"Plus Tier": "Piano Plus",
|
||||
"Pro Tier": "Piano Pro",
|
||||
"RTL Direction": "Direzione RTL",
|
||||
"Maximum Column Height": "Altezza massima colonna",
|
||||
"Maximum Column Width": "Larghezza massima colonna",
|
||||
@@ -381,5 +364,44 @@
|
||||
"Show Remaining Pages": "Mostra pagine rimanenti",
|
||||
"Source Han Serif CN VF": "Source Han Serif",
|
||||
"Huiwen-mincho": "Huiwen Mincho",
|
||||
"KingHwa_OldSong": "KingHwa Song"
|
||||
"KingHwa_OldSong": "KingHwa Song",
|
||||
"Manage Subscription": "Gestisci Abbonamento",
|
||||
"Coming Soon": "Prossimamente",
|
||||
"Upgrade to {{plan}}": "Aggiorna a {{plan}}",
|
||||
"Upgrade to Plus or Pro": "Aggiorna a Plus o Pro",
|
||||
"Current Plan": "Piano Attuale",
|
||||
"Plan Limits": "Limiti del Piano",
|
||||
"Available Plans": "Piani Disponibili",
|
||||
"{{current}} of {{all}}": "{{current}} di {{all}}",
|
||||
"Failed to manage subscription. Please try again later.": "Impossibile gestire l'abbonamento. Riprova più tardi.",
|
||||
"Processing your payment...": "Elaborazione del pagamento...",
|
||||
"Please wait while we confirm your subscription.": "Attendi mentre confermiamo il tuo abbonamento.",
|
||||
"Payment Processing": "Elaborazione Pagamento",
|
||||
"Your payment is being processed. This usually takes a few moments.": "Il tuo pagamento è in elaborazione. Di solito richiede pochi istanti.",
|
||||
"Payment Failed": "Pagamento Fallito",
|
||||
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "Non è stato possibile elaborare l'abbonamento. Riprova o contatta il supporto se il problema persiste.",
|
||||
"Back to Profile": "Torna al Profilo",
|
||||
"Subscription Successful!": "Abbonamento Avvenuto con Successo!",
|
||||
"Thank you for your subscription! Your payment has been processed successfully.": "Grazie per l'abbonamento! Il pagamento è stato elaborato con successo.",
|
||||
"Email:": "Email:",
|
||||
"Plan:": "Piano:",
|
||||
"Amount:": "Importo:",
|
||||
"Subscription ID:": "ID Abbonamento:",
|
||||
"Go to Library": "Vai alla Libreria",
|
||||
"Need help? Contact our support team at support@readest.com": "Hai bisogno di aiuto? Contatta il nostro supporto a support@readest.com",
|
||||
"Free Plan": "Piano Gratuito",
|
||||
"month": "mese",
|
||||
"Unlimited Text-to-Speech Hours": "Ore Illimitate di Sintesi Vocale",
|
||||
"DeepL Free Access (10K characters/day)": "Accesso Gratuito a DeepL (10.000 caratteri/giorno)",
|
||||
"AI Translations (per day)": "Traduzioni AI (al giorno)",
|
||||
"Cloud Storage": "Archiviazione Cloud",
|
||||
"Plus Plan": "Piano Plus",
|
||||
"Includes All Free Plan Benefits": "Include Tutti i Vantaggi del Piano Gratuito",
|
||||
"Basic AI Translations": "Traduzioni AI di Base",
|
||||
"DeepL Pro Access (50K characters/day)": "Accesso DeepL Pro (50.000 caratteri/giorno)",
|
||||
"2 GB Cloud Sync Space": "2 GB di Spazio di Sincronizzazione Cloud",
|
||||
"Pro Plan": "Piano Pro",
|
||||
"Includes All Plus Plan Benefits": "Include Tutti i Vantaggi del Piano Plus",
|
||||
"More AI Translations": "Più Traduzioni AI",
|
||||
"DeepL Pro Access (200K characters/day)": "Accesso DeepL Pro (200.000 caratteri/giorno)"
|
||||
}
|
||||
|
||||
@@ -183,35 +183,18 @@
|
||||
"Sign in with GitHub": "GitHubでサインイン",
|
||||
"Account": "アカウント",
|
||||
"Failed to delete user. Please try again later.": "ユーザーの削除に失敗しました。後ほど再試行してください。",
|
||||
"Unlimited Offline/Online Reading": "無制限のオフライン/オンライン読書",
|
||||
"Unlimited Cloud Sync Devices": "無制限のクラウド同期デバイス",
|
||||
"Essential Text-to-Speech Voices": "基本的な音声合成ボイス",
|
||||
"DeepL Free Access": "DeepL無料アクセス",
|
||||
"Community Support": "コミュニティサポート",
|
||||
"500 MB Cloud Sync Space": "500 MBのクラウド同期スペース",
|
||||
"Includes All Free Tier Benefits": "無料プランの全特典を含む",
|
||||
"AI Summaries": "AI要約",
|
||||
"AI Translations": "AI翻訳",
|
||||
"Priority Support": "優先サポート",
|
||||
"DeepL Pro Access": "DeepL Proアクセス",
|
||||
"Expanded Text-to-Speech Voices": "拡張された音声合成ボイス",
|
||||
"2000 MB Cloud Sync Space": "2000 MBのクラウド同期スペース",
|
||||
"Includes All Plus Tier Benefits": "Plusプランの全特典を含む",
|
||||
"Unlimited AI Summaries": "無制限のAI要約",
|
||||
"Unlimited AI Translations": "無制限のAI翻訳",
|
||||
"Unlimited DeepL Pro Access": "無制限のDeepL Proアクセス",
|
||||
"Advanced AI Tools": "高度なAIツール",
|
||||
"Early Feature Access": "新機能への早期アクセス",
|
||||
"10 GB Cloud Sync Space": "10 GBのクラウド同期スペース",
|
||||
"Loading profile...": "プロフィール読み込み中...",
|
||||
"Features": "機能",
|
||||
"Delete Account": "アカウント削除",
|
||||
"Delete Your Account?": "アカウントを削除しますか?",
|
||||
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "この操作は元に戻せません。クラウド上のすべてのデータが完全に削除されます。",
|
||||
"Delete Permanently": "完全に削除",
|
||||
"Free Tier": "無料プラン",
|
||||
"Plus Tier": "Plusプラン",
|
||||
"Pro Tier": "Proプラン",
|
||||
"RTL Direction": "RTL方向",
|
||||
"Maximum Column Height": "最大列高",
|
||||
"Maximum Column Width": "最大列幅",
|
||||
@@ -373,5 +356,44 @@
|
||||
"Show Remaining Pages": "残りを表示",
|
||||
"Source Han Serif CN VF": "Source Han Serif",
|
||||
"Huiwen-mincho": "Huiwen Mincho",
|
||||
"KingHwa_OldSong": "KingHwa Song"
|
||||
"KingHwa_OldSong": "KingHwa Song",
|
||||
"Manage Subscription": "サブスクリプションを管理",
|
||||
"Coming Soon": "近日公開",
|
||||
"Upgrade to {{plan}}": "{{plan}} にアップグレード",
|
||||
"Upgrade to Plus or Pro": "Plus または Pro にアップグレード",
|
||||
"Current Plan": "現在のプラン",
|
||||
"Plan Limits": "プランの上限",
|
||||
"Available Plans": "利用可能なプラン",
|
||||
"{{current}} of {{all}}": "{{all}} 中 {{current}}",
|
||||
"Failed to manage subscription. Please try again later.": "サブスクリプションの管理に失敗しました。後でもう一度お試しください。",
|
||||
"Processing your payment...": "お支払いを処理中...",
|
||||
"Please wait while we confirm your subscription.": "サブスクリプションを確認しています。しばらくお待ちください。",
|
||||
"Payment Processing": "支払いを処理中",
|
||||
"Your payment is being processed. This usually takes a few moments.": "お支払いを処理しています。通常、数秒かかります。",
|
||||
"Payment Failed": "支払いに失敗しました",
|
||||
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "サブスクリプションを処理できませんでした。再度お試しいただくか、問題が続く場合はサポートにお問い合わせください。",
|
||||
"Back to Profile": "プロフィールに戻る",
|
||||
"Subscription Successful!": "サブスクリプションが完了しました!",
|
||||
"Thank you for your subscription! Your payment has been processed successfully.": "ご登録ありがとうございます!お支払いが正常に処理されました。",
|
||||
"Email:": "メール:",
|
||||
"Plan:": "プラン:",
|
||||
"Amount:": "金額:",
|
||||
"Subscription ID:": "サブスクリプションID:",
|
||||
"Go to Library": "ライブラリへ移動",
|
||||
"Need help? Contact our support team at support@readest.com": "サポートが必要ですか? support@readest.com までお問い合わせください。",
|
||||
"Free Plan": "無料プラン",
|
||||
"month": "月",
|
||||
"Unlimited Text-to-Speech Hours": "無制限の音声読み上げ時間",
|
||||
"DeepL Free Access (10K characters/day)": "DeepL無料アクセス(1日1万文字)",
|
||||
"AI Translations (per day)": "AI翻訳(1日あたり)",
|
||||
"Cloud Storage": "クラウドストレージ",
|
||||
"Plus Plan": "Plusプラン",
|
||||
"Includes All Free Plan Benefits": "無料プランの全特典を含む",
|
||||
"Basic AI Translations": "基本的なAI翻訳",
|
||||
"DeepL Pro Access (50K characters/day)": "DeepL Proアクセス(1日5万文字)",
|
||||
"2 GB Cloud Sync Space": "2GBのクラウド同期容量",
|
||||
"Pro Plan": "Proプラン",
|
||||
"Includes All Plus Plan Benefits": "Plusプランの全特典を含む",
|
||||
"More AI Translations": "さらに多くのAI翻訳",
|
||||
"DeepL Pro Access (200K characters/day)": "DeepL Proアクセス(1日20万文字)"
|
||||
}
|
||||
|
||||
@@ -183,35 +183,18 @@
|
||||
"Sign in with GitHub": "GitHub로 로그인",
|
||||
"Account": "계정",
|
||||
"Failed to delete user. Please try again later.": "사용자 삭제에 실패했습니다. 나중에 다시 시도해 주세요.",
|
||||
"Unlimited Offline/Online Reading": "무제한 오프라인/온라인 읽기",
|
||||
"Unlimited Cloud Sync Devices": "무제한 클라우드 동기화 기기",
|
||||
"Essential Text-to-Speech Voices": "필수 텍스트 음성 변환 목소리",
|
||||
"DeepL Free Access": "DeepL 무료 접근",
|
||||
"Community Support": "커뮤니티 지원",
|
||||
"500 MB Cloud Sync Space": "500 MB 클라우드 동기화 공간",
|
||||
"Includes All Free Tier Benefits": "무료 등급의 모든 혜택 포함",
|
||||
"AI Summaries": "AI 요약",
|
||||
"AI Translations": "AI 번역",
|
||||
"Priority Support": "우선 지원",
|
||||
"DeepL Pro Access": "DeepL 프로 접근",
|
||||
"Expanded Text-to-Speech Voices": "확장된 텍스트 음성 변환 목소리",
|
||||
"2000 MB Cloud Sync Space": "2000 MB 클라우드 동기화 공간",
|
||||
"Includes All Plus Tier Benefits": "플러스 등급의 모든 혜택 포함",
|
||||
"Unlimited AI Summaries": "무제한 AI 요약",
|
||||
"Unlimited AI Translations": "무제한 AI 번역",
|
||||
"Unlimited DeepL Pro Access": "무제한 DeepL 프로 접근",
|
||||
"Advanced AI Tools": "고급 AI 도구",
|
||||
"Early Feature Access": "신기능 조기 접근",
|
||||
"10 GB Cloud Sync Space": "10 GB 클라우드 동기화 공간",
|
||||
"Loading profile...": "프로필 로딩 중...",
|
||||
"Features": "기능",
|
||||
"Delete Account": "계정 삭제",
|
||||
"Delete Your Account?": "계정을 삭제하시겠습니까?",
|
||||
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "이 작업은 취소할 수 없습니다. 클라우드에 있는 모든 데이터가 영구적으로 삭제됩니다.",
|
||||
"Delete Permanently": "영구 삭제",
|
||||
"Free Tier": "무료 등급",
|
||||
"Plus Tier": "플러스 등급",
|
||||
"Pro Tier": "프로 등급",
|
||||
"RTL Direction": "RTL 방향",
|
||||
"Maximum Column Height": "최대 열 높이",
|
||||
"Maximum Column Width": "최대 열 너비",
|
||||
@@ -373,5 +356,44 @@
|
||||
"Show Remaining Pages": "남은 페이지 보기",
|
||||
"Source Han Serif CN VF": "Source Han Serif",
|
||||
"Huiwen-mincho": "Huiwen Mincho",
|
||||
"KingHwa_OldSong": "KingHwa Song"
|
||||
"KingHwa_OldSong": "KingHwa Song",
|
||||
"Manage Subscription": "구독 관리",
|
||||
"Coming Soon": "곧 출시 예정",
|
||||
"Upgrade to {{plan}}": "{{plan}}로 업그레이드",
|
||||
"Upgrade to Plus or Pro": "Plus 또는 Pro로 업그레이드",
|
||||
"Current Plan": "현재 요금제",
|
||||
"Plan Limits": "요금제 한도",
|
||||
"Available Plans": "이용 가능한 요금제",
|
||||
"{{current}} of {{all}}": "{{all}} 중 {{current}}",
|
||||
"Failed to manage subscription. Please try again later.": "구독 관리에 실패했습니다. 나중에 다시 시도해주세요.",
|
||||
"Processing your payment...": "결제를 처리 중입니다...",
|
||||
"Please wait while we confirm your subscription.": "구독을 확인하는 중입니다. 잠시만 기다려주세요.",
|
||||
"Payment Processing": "결제 처리 중",
|
||||
"Your payment is being processed. This usually takes a few moments.": "결제가 처리되고 있습니다. 잠시만 기다려주세요.",
|
||||
"Payment Failed": "결제 실패",
|
||||
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "구독을 처리할 수 없습니다. 다시 시도하거나 문제가 계속되면 지원팀에 문의해주세요.",
|
||||
"Back to Profile": "프로필로 돌아가기",
|
||||
"Subscription Successful!": "구독이 완료되었습니다!",
|
||||
"Thank you for your subscription! Your payment has been processed successfully.": "구독해주셔서 감사합니다! 결제가 성공적으로 처리되었습니다.",
|
||||
"Email:": "이메일:",
|
||||
"Plan:": "요금제:",
|
||||
"Amount:": "금액:",
|
||||
"Subscription ID:": "구독 ID:",
|
||||
"Go to Library": "라이브러리로 이동",
|
||||
"Need help? Contact our support team at support@readest.com": "도움이 필요하시면 support@readest.com으로 문의해주세요.",
|
||||
"Free Plan": "무료 요금제",
|
||||
"month": "월",
|
||||
"Unlimited Text-to-Speech Hours": "무제한 음성 변환 시간",
|
||||
"DeepL Free Access (10K characters/day)": "DeepL 무료 액세스 (일 1만자)",
|
||||
"AI Translations (per day)": "AI 번역 (일 기준)",
|
||||
"Cloud Storage": "클라우드 저장소",
|
||||
"Plus Plan": "Plus 요금제",
|
||||
"Includes All Free Plan Benefits": "무료 요금제의 모든 혜택 포함",
|
||||
"Basic AI Translations": "기본 AI 번역",
|
||||
"DeepL Pro Access (50K characters/day)": "DeepL Pro 액세스 (일 5만자)",
|
||||
"2 GB Cloud Sync Space": "2GB 클라우드 동기화 공간",
|
||||
"Pro Plan": "Pro 요금제",
|
||||
"Includes All Plus Plan Benefits": "Plus 요금제의 모든 혜택 포함",
|
||||
"More AI Translations": "더 많은 AI 번역",
|
||||
"DeepL Pro Access (200K characters/day)": "DeepL Pro 액세스 (일 20만자)"
|
||||
}
|
||||
|
||||
@@ -225,31 +225,14 @@
|
||||
"Fast": "Snel",
|
||||
"Reading Progress Synced": "Leesvoortgang gesynchroniseerd",
|
||||
"Failed to delete user. Please try again later.": "Gebruiker verwijderen mislukt. Probeer het later opnieuw.",
|
||||
"Free Tier": "Gratis niveau",
|
||||
"Community Support": "Community-ondersteuning",
|
||||
"DeepL Free Access": "DeepL gratis toegang",
|
||||
"Essential Text-to-Speech Voices": "Essentiële tekst-naar-spraak stemmen",
|
||||
"Unlimited Offline/Online Reading": "Onbeperkt offline/online lezen",
|
||||
"Unlimited Cloud Sync Devices": "Onbeperkt aantal cloud-synchronisatie apparaten",
|
||||
"500 MB Cloud Sync Space": "500 MB cloud-synchronisatieruimte",
|
||||
"Plus Tier": "Plus niveau",
|
||||
"Includes All Free Tier Benefits": "Inclusief alle voordelen van het gratis niveau",
|
||||
"Priority Support": "Prioriteitsondersteuning",
|
||||
"AI Summaries": "AI-samenvattingen",
|
||||
"AI Translations": "AI-vertalingen",
|
||||
"DeepL Pro Access": "DeepL Pro toegang",
|
||||
"Expanded Text-to-Speech Voices": "Uitgebreide tekst-naar-spraak stemmen",
|
||||
"2000 MB Cloud Sync Space": "2000 MB cloud-synchronisatieruimte",
|
||||
"Pro Tier": "Pro niveau",
|
||||
"Includes All Plus Tier Benefits": "Inclusief alle voordelen van het Plus niveau",
|
||||
"Unlimited AI Summaries": "Onbeperkte AI-samenvattingen",
|
||||
"Unlimited AI Translations": "Onbeperkte AI-vertalingen",
|
||||
"Unlimited DeepL Pro Access": "Onbeperkte DeepL Pro toegang",
|
||||
"Advanced AI Tools": "Geavanceerde AI-tools",
|
||||
"Early Feature Access": "Vroege toegang tot functies",
|
||||
"10 GB Cloud Sync Space": "10 GB cloud-synchronisatieruimte",
|
||||
"Loading profile...": "Profiel laden...",
|
||||
"Features": "Functies",
|
||||
"Sign Out": "Uitloggen",
|
||||
"Delete Account": "Account verwijderen",
|
||||
"Delete Your Account?": "Uw account verwijderen?",
|
||||
@@ -377,5 +360,44 @@
|
||||
"Show Remaining Pages": "Toon resterende pagina’s",
|
||||
"Source Han Serif CN VF": "Source Han Serif",
|
||||
"Huiwen-mincho": "Huiwen Mincho",
|
||||
"KingHwa_OldSong": "KingHwa Song"
|
||||
"KingHwa_OldSong": "KingHwa Song",
|
||||
"Manage Subscription": "Abonnement beheren",
|
||||
"Coming Soon": "Binnenkort beschikbaar",
|
||||
"Upgrade to {{plan}}": "Upgrade naar {{plan}}",
|
||||
"Upgrade to Plus or Pro": "Upgrade naar Plus of Pro",
|
||||
"Current Plan": "Huidig abonnement",
|
||||
"Plan Limits": "Abonnementslimieten",
|
||||
"Available Plans": "Beschikbare abonnementen",
|
||||
"{{current}} of {{all}}": "{{current}} van {{all}}",
|
||||
"Failed to manage subscription. Please try again later.": "Abonnement beheren is mislukt. Probeer het later opnieuw.",
|
||||
"Processing your payment...": "Je betaling wordt verwerkt...",
|
||||
"Please wait while we confirm your subscription.": "Even geduld terwijl we je abonnement bevestigen.",
|
||||
"Payment Processing": "Betaling verwerken",
|
||||
"Your payment is being processed. This usually takes a few moments.": "Je betaling wordt verwerkt. Dit duurt meestal een paar seconden.",
|
||||
"Payment Failed": "Betaling mislukt",
|
||||
"Back to Profile": "Terug naar profiel",
|
||||
"Subscription Successful!": "Abonnement succesvol!",
|
||||
"Email:": "E-mail:",
|
||||
"Plan:": "Abonnement:",
|
||||
"Amount:": "Bedrag:",
|
||||
"Subscription ID:": "Abonnements-ID:",
|
||||
"Go to Library": "Ga naar bibliotheek",
|
||||
"Need help? Contact our support team at support@readest.com": "Hulp nodig? Neem contact op met support via support@readest.com",
|
||||
"Free Plan": "Gratis abonnement",
|
||||
"month": "maand",
|
||||
"Unlimited Text-to-Speech Hours": "Onbeperkte tekst-naar-spraak-uren",
|
||||
"DeepL Free Access (10K characters/day)": "DeepL gratis toegang (10.000 tekens/dag)",
|
||||
"AI Translations (per day)": "AI-vertalingen (per dag)",
|
||||
"Cloud Storage": "Cloudopslag",
|
||||
"Plus Plan": "Plus-abonnement",
|
||||
"Includes All Free Plan Benefits": "Bevat alle voordelen van het gratis abonnement",
|
||||
"Basic AI Translations": "Basis AI-vertalingen",
|
||||
"DeepL Pro Access (50K characters/day)": "DeepL Pro toegang (50.000 tekens/dag)",
|
||||
"2 GB Cloud Sync Space": "2GB cloud-synchronisatie",
|
||||
"Pro Plan": "Pro-abonnement",
|
||||
"Includes All Plus Plan Benefits": "Bevat alle voordelen van het Plus-abonnement",
|
||||
"More AI Translations": "Meer AI-vertalingen",
|
||||
"DeepL Pro Access (200K characters/day)": "DeepL Pro toegang (200.000 tekens/dag)",
|
||||
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "We konden je abonnement niet verwerken. Probeer het opnieuw of neem contact op met support als het probleem blijft bestaan.",
|
||||
"Thank you for your subscription! Your payment has been processed successfully.": "Bedankt voor je abonnement! Je betaling is succesvol verwerkt."
|
||||
}
|
||||
|
||||
@@ -183,35 +183,18 @@
|
||||
"Sign in with GitHub": "Zaloguj się za pomocą GitHub",
|
||||
"Account": "Konto",
|
||||
"Failed to delete user. Please try again later.": "Nie udało się usunąć użytkownika. Spróbuj ponownie później.",
|
||||
"Unlimited Offline/Online Reading": "Nieograniczone czytanie offline/online",
|
||||
"Unlimited Cloud Sync Devices": "Nieograniczona liczba urządzeń synchronizowanych w chmurze",
|
||||
"Essential Text-to-Speech Voices": "Podstawowe głosy zamiany tekstu na mowę",
|
||||
"DeepL Free Access": "Darmowy dostęp do DeepL",
|
||||
"Community Support": "Wsparcie społeczności",
|
||||
"500 MB Cloud Sync Space": "500 MB przestrzeni synchronizacji w chmurze",
|
||||
"Includes All Free Tier Benefits": "Zawiera wszystkie korzyści darmowego planu",
|
||||
"AI Summaries": "Podsumowania AI",
|
||||
"AI Translations": "Tłumaczenia AI",
|
||||
"Priority Support": "Priorytetowe wsparcie",
|
||||
"DeepL Pro Access": "Dostęp do DeepL Pro",
|
||||
"Expanded Text-to-Speech Voices": "Rozszerzone głosy zamiany tekstu na mowę",
|
||||
"2000 MB Cloud Sync Space": "2000 MB przestrzeni synchronizacji w chmurze",
|
||||
"Includes All Plus Tier Benefits": "Zawiera wszystkie korzyści planu Plus",
|
||||
"Unlimited AI Summaries": "Nieograniczone podsumowania AI",
|
||||
"Unlimited AI Translations": "Nieograniczone tłumaczenia AI",
|
||||
"Unlimited DeepL Pro Access": "Nieograniczony dostęp do DeepL Pro",
|
||||
"Advanced AI Tools": "Zaawansowane narzędzia AI",
|
||||
"Early Feature Access": "Wczesny dostęp do nowych funkcji",
|
||||
"10 GB Cloud Sync Space": "10 GB przestrzeni synchronizacji w chmurze",
|
||||
"Loading profile...": "Ładowanie profilu...",
|
||||
"Features": "Funkcje",
|
||||
"Delete Account": "Usuń konto",
|
||||
"Delete Your Account?": "Usunąć Twoje konto?",
|
||||
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "Tej operacji nie można cofnąć. Wszystkie Twoje dane w chmurze zostaną trwale usunięte.",
|
||||
"Delete Permanently": "Usuń trwale",
|
||||
"Free Tier": "Plan darmowy",
|
||||
"Plus Tier": "Plan Plus",
|
||||
"Pro Tier": "Plan Pro",
|
||||
"RTL Direction": "Kierunek RTL",
|
||||
"Maximum Column Height": "Maksymalna wysokość kolumny",
|
||||
"Maximum Column Width": "Maksymalna szerokość kolumny",
|
||||
@@ -385,5 +368,44 @@
|
||||
"Show Remaining Pages": "Pokaż pozostałe strony",
|
||||
"Source Han Serif CN VF": "Source Han Serif",
|
||||
"Huiwen-mincho": "Huiwen Mincho",
|
||||
"KingHwa_OldSong": "KingHwa Song"
|
||||
"KingHwa_OldSong": "KingHwa Song",
|
||||
"Manage Subscription": "Zarządzaj subskrypcją",
|
||||
"Coming Soon": "Wkrótce dostępne",
|
||||
"Upgrade to {{plan}}": "Uaktualnij do {{plan}}",
|
||||
"Upgrade to Plus or Pro": "Uaktualnij do Plus lub Pro",
|
||||
"Current Plan": "Obecny plan",
|
||||
"Plan Limits": "Limity planu",
|
||||
"Available Plans": "Dostępne plany",
|
||||
"{{current}} of {{all}}": "{{current}} z {{all}}",
|
||||
"Failed to manage subscription. Please try again later.": "Nie udało się zarządzać subskrypcją. Spróbuj ponownie później.",
|
||||
"Processing your payment...": "Przetwarzanie płatności...",
|
||||
"Please wait while we confirm your subscription.": "Proszę czekać, potwierdzamy subskrypcję.",
|
||||
"Payment Processing": "Przetwarzanie płatności",
|
||||
"Your payment is being processed. This usually takes a few moments.": "Twoja płatność jest przetwarzana. Zwykle trwa to kilka chwil.",
|
||||
"Payment Failed": "Płatność nie powiodła się",
|
||||
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "Nie udało się przetworzyć subskrypcji. Spróbuj ponownie lub skontaktuj się z pomocą techniczną, jeśli problem będzie się powtarzać.",
|
||||
"Back to Profile": "Powrót do profilu",
|
||||
"Subscription Successful!": "Subskrypcja zakończona sukcesem!",
|
||||
"Thank you for your subscription! Your payment has been processed successfully.": "Dziękujemy za subskrypcję! Twoja płatność została pomyślnie przetworzona.",
|
||||
"Email:": "E-mail:",
|
||||
"Plan:": "Plan:",
|
||||
"Amount:": "Kwota:",
|
||||
"Subscription ID:": "ID subskrypcji:",
|
||||
"Go to Library": "Przejdź do biblioteki",
|
||||
"Need help? Contact our support team at support@readest.com": "Potrzebujesz pomocy? Skontaktuj się z naszym zespołem wsparcia: support@readest.com",
|
||||
"Free Plan": "Bezpłatny plan",
|
||||
"month": "miesiąc",
|
||||
"Unlimited Text-to-Speech Hours": "Nieograniczone godziny zamiany tekstu na mowę",
|
||||
"DeepL Free Access (10K characters/day)": "Darmowy dostęp do DeepL (10 tys. znaków/dzień)",
|
||||
"AI Translations (per day)": "Tłumaczenia AI (na dzień)",
|
||||
"Cloud Storage": "Przechowywanie w chmurze",
|
||||
"Plus Plan": "Plan Plus",
|
||||
"Includes All Free Plan Benefits": "Zawiera wszystkie korzyści planu darmowego",
|
||||
"Basic AI Translations": "Podstawowe tłumaczenia AI",
|
||||
"DeepL Pro Access (50K characters/day)": "DeepL Pro (50 tys. znaków/dzień)",
|
||||
"2 GB Cloud Sync Space": "2 GB miejsca na synchronizację w chmurze",
|
||||
"Pro Plan": "Plan Pro",
|
||||
"Includes All Plus Plan Benefits": "Zawiera wszystkie korzyści planu Plus",
|
||||
"More AI Translations": "Więcej tłumaczeń AI",
|
||||
"DeepL Pro Access (200K characters/day)": "DeepL Pro (200 tys. znaków/dzień)"
|
||||
}
|
||||
|
||||
@@ -183,35 +183,18 @@
|
||||
"Sign in with GitHub": "Entrar com o GitHub",
|
||||
"Account": "Conta",
|
||||
"Failed to delete user. Please try again later.": "Falha ao excluir usuário. Por favor, tente novamente mais tarde.",
|
||||
"Unlimited Offline/Online Reading": "Leitura offline/online ilimitada",
|
||||
"Unlimited Cloud Sync Devices": "Sincronização ilimitada de dispositivos na nuvem",
|
||||
"Essential Text-to-Speech Voices": "Vozes essenciais de texto para fala",
|
||||
"DeepL Free Access": "Acesso gratuito ao DeepL",
|
||||
"Community Support": "Suporte da comunidade",
|
||||
"500 MB Cloud Sync Space": "500 MB de espaço de sincronização na nuvem",
|
||||
"Includes All Free Tier Benefits": "Inclui todos os benefícios do plano gratuito",
|
||||
"AI Summaries": "Resumos de IA",
|
||||
"AI Translations": "Traduções de IA",
|
||||
"Priority Support": "Suporte prioritário",
|
||||
"DeepL Pro Access": "Acesso ao DeepL Pro",
|
||||
"Expanded Text-to-Speech Voices": "Vozes ampliadas de texto para fala",
|
||||
"2000 MB Cloud Sync Space": "2000 MB de espaço de sincronização na nuvem",
|
||||
"Includes All Plus Tier Benefits": "Inclui todos os benefícios do plano Plus",
|
||||
"Unlimited AI Summaries": "Resumos de IA ilimitados",
|
||||
"Unlimited AI Translations": "Traduções de IA ilimitadas",
|
||||
"Unlimited DeepL Pro Access": "Acesso ilimitado ao DeepL Pro",
|
||||
"Advanced AI Tools": "Ferramentas avançadas de IA",
|
||||
"Early Feature Access": "Acesso antecipado a recursos",
|
||||
"10 GB Cloud Sync Space": "10 GB de espaço de sincronização na nuvem",
|
||||
"Loading profile...": "Carregando perfil...",
|
||||
"Features": "Recursos",
|
||||
"Delete Account": "Excluir conta",
|
||||
"Delete Your Account?": "Excluir sua conta?",
|
||||
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "Esta ação não pode ser desfeita. Todos os seus dados na nuvem serão excluídos permanentemente.",
|
||||
"Delete Permanently": "Excluir permanentemente",
|
||||
"Free Tier": "Plano gratuito",
|
||||
"Plus Tier": "Plano Plus",
|
||||
"Pro Tier": "Plano Pro",
|
||||
"RTL Direction": "Direção RTL",
|
||||
"Maximum Column Height": "Altura Máxima da Coluna",
|
||||
"Maximum Column Width": "Largura Máxima da Coluna",
|
||||
@@ -381,5 +364,44 @@
|
||||
"Show Remaining Pages": "Mostrar páginas restantes",
|
||||
"Source Han Serif CN VF": "Source Han Serif",
|
||||
"Huiwen-mincho": "Huiwen Mincho",
|
||||
"KingHwa_OldSong": "KingHwa Song"
|
||||
"KingHwa_OldSong": "KingHwa Song",
|
||||
"Manage Subscription": "Gerenciar assinatura",
|
||||
"Coming Soon": "Em breve",
|
||||
"Upgrade to {{plan}}": "Atualizar para {{plan}}",
|
||||
"Upgrade to Plus or Pro": "Atualizar para Plus ou Pro",
|
||||
"Current Plan": "Plano atual",
|
||||
"Plan Limits": "Limites do plano",
|
||||
"Available Plans": "Planos disponíveis",
|
||||
"{{current}} of {{all}}": "{{current}} de {{all}}",
|
||||
"Failed to manage subscription. Please try again later.": "Não foi possível gerenciar a assinatura. Tente novamente mais tarde.",
|
||||
"Processing your payment...": "Processando seu pagamento...",
|
||||
"Please wait while we confirm your subscription.": "Por favor, aguarde enquanto confirmamos sua assinatura.",
|
||||
"Payment Processing": "Processando pagamento",
|
||||
"Your payment is being processed. This usually takes a few moments.": "Seu pagamento está sendo processado. Isso normalmente leva alguns instantes.",
|
||||
"Payment Failed": "Falha no pagamento",
|
||||
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "Não foi possível processar sua assinatura. Tente novamente ou entre em contato com o suporte se o problema persistir.",
|
||||
"Back to Profile": "Voltar ao perfil",
|
||||
"Subscription Successful!": "Assinatura realizada com sucesso!",
|
||||
"Thank you for your subscription! Your payment has been processed successfully.": "Obrigado pela sua assinatura! Seu pagamento foi processado com sucesso.",
|
||||
"Email:": "E-mail:",
|
||||
"Plan:": "Plano:",
|
||||
"Amount:": "Valor:",
|
||||
"Subscription ID:": "ID da assinatura:",
|
||||
"Go to Library": "Ir para a biblioteca",
|
||||
"Need help? Contact our support team at support@readest.com": "Precisa de ajuda? Entre em contato com nossa equipe de suporte: support@readest.com",
|
||||
"Free Plan": "Plano gratuito",
|
||||
"month": "mês",
|
||||
"Unlimited Text-to-Speech Hours": "Horas ilimitadas de texto para fala",
|
||||
"DeepL Free Access (10K characters/day)": "Acesso gratuito ao DeepL (10 mil caracteres/dia)",
|
||||
"AI Translations (per day)": "Traduções com IA (por dia)",
|
||||
"Cloud Storage": "Armazenamento na nuvem",
|
||||
"Plus Plan": "Plano Plus",
|
||||
"Includes All Free Plan Benefits": "Inclui todos os benefícios do plano gratuito",
|
||||
"Basic AI Translations": "Traduções básicas com IA",
|
||||
"DeepL Pro Access (50K characters/day)": "Acesso ao DeepL Pro (50 mil caracteres/dia)",
|
||||
"2 GB Cloud Sync Space": "2 GB de espaço para sincronização na nuvem",
|
||||
"Pro Plan": "Plano Pro",
|
||||
"Includes All Plus Plan Benefits": "Inclui todos os benefícios do plano Plus",
|
||||
"More AI Translations": "Mais traduções com IA",
|
||||
"DeepL Pro Access (200K characters/day)": "Acesso ao DeepL Pro (200 mil caracteres/dia)"
|
||||
}
|
||||
|
||||
@@ -183,35 +183,18 @@
|
||||
"Sign in with GitHub": "Войти через GitHub",
|
||||
"Account": "Аккаунт",
|
||||
"Failed to delete user. Please try again later.": "Не удалось удалить пользователя. Пожалуйста, повторите попытку позже.",
|
||||
"Unlimited Offline/Online Reading": "Безлимитное чтение офлайн/онлайн",
|
||||
"Unlimited Cloud Sync Devices": "Неограниченное количество устройств для облачной синхронизации",
|
||||
"Essential Text-to-Speech Voices": "Основные голоса для преобразования текста в речь",
|
||||
"DeepL Free Access": "Бесплатный доступ к DeepL",
|
||||
"Community Support": "Поддержка сообщества",
|
||||
"500 MB Cloud Sync Space": "500 МБ облачного пространства для синхронизации",
|
||||
"Includes All Free Tier Benefits": "Включает все преимущества бесплатного тарифа",
|
||||
"AI Summaries": "AI-резюме",
|
||||
"AI Translations": "AI-переводы",
|
||||
"Priority Support": "Приоритетная поддержка",
|
||||
"DeepL Pro Access": "Доступ к DeepL Pro",
|
||||
"Expanded Text-to-Speech Voices": "Расширенный набор голосов для преобразования текста в речь",
|
||||
"2000 MB Cloud Sync Space": "2000 МБ облачного пространства для синхронизации",
|
||||
"Includes All Plus Tier Benefits": "Включает все преимущества тарифа Plus",
|
||||
"Unlimited AI Summaries": "Безлимитные AI-резюме",
|
||||
"Unlimited AI Translations": "Безлимитные AI-переводы",
|
||||
"Unlimited DeepL Pro Access": "Неограниченный доступ к DeepL Pro",
|
||||
"Advanced AI Tools": "Продвинутые AI-инструменты",
|
||||
"Early Feature Access": "Ранний доступ к новым функциям",
|
||||
"10 GB Cloud Sync Space": "10 ГБ облачного пространства для синхронизации",
|
||||
"Loading profile...": "Загрузка профиля...",
|
||||
"Features": "Функции",
|
||||
"Delete Account": "Удалить аккаунт",
|
||||
"Delete Your Account?": "Удалить ваш аккаунт?",
|
||||
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "Это действие нельзя отменить. Все ваши данные в облаке будут удалены безвозвратно.",
|
||||
"Delete Permanently": "Удалить навсегда",
|
||||
"Free Tier": "Бесплатный тариф",
|
||||
"Plus Tier": "Тариф Plus",
|
||||
"Pro Tier": "Тариф Pro",
|
||||
"RTL Direction": "Направление RTL",
|
||||
"Maximum Column Height": "Максимальная высота колонки",
|
||||
"Maximum Column Width": "Максимальная ширина колонки",
|
||||
@@ -385,5 +368,44 @@
|
||||
"Show Remaining Pages": "Показать оставшиеся страницы",
|
||||
"Source Han Serif CN VF": "Source Han Serif",
|
||||
"Huiwen-mincho": "Huiwen Mincho",
|
||||
"KingHwa_OldSong": "KingHwa Song"
|
||||
"KingHwa_OldSong": "KingHwa Song",
|
||||
"Manage Subscription": "Управление подпиской",
|
||||
"Coming Soon": "Скоро будет",
|
||||
"Upgrade to {{plan}}": "Обновить до {{plan}}",
|
||||
"Upgrade to Plus or Pro": "Обновить до Plus или Pro",
|
||||
"Current Plan": "Текущий план",
|
||||
"Plan Limits": "Лимиты плана",
|
||||
"Available Plans": "Доступные планы",
|
||||
"{{current}} of {{all}}": "{{current}} из {{all}}",
|
||||
"Failed to manage subscription. Please try again later.": "Не удалось управлять подпиской. Пожалуйста, попробуйте позже.",
|
||||
"Processing your payment...": "Обработка платежа...",
|
||||
"Please wait while we confirm your subscription.": "Пожалуйста, подождите, пока мы подтверждаем вашу подписку.",
|
||||
"Payment Processing": "Обработка платежа",
|
||||
"Your payment is being processed. This usually takes a few moments.": "Ваш платеж обрабатывается. Обычно это занимает несколько секунд.",
|
||||
"Payment Failed": "Не удалось провести платеж",
|
||||
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "Не удалось обработать подписку. Пожалуйста, попробуйте еще раз или свяжитесь с поддержкой, если проблема сохраняется.",
|
||||
"Back to Profile": "Назад в профиль",
|
||||
"Subscription Successful!": "Подписка успешно оформлена!",
|
||||
"Thank you for your subscription! Your payment has been processed successfully.": "Спасибо за подписку! Ваш платеж успешно обработан.",
|
||||
"Email:": "Электронная почта:",
|
||||
"Plan:": "План:",
|
||||
"Amount:": "Сумма:",
|
||||
"Subscription ID:": "ID подписки:",
|
||||
"Go to Library": "Перейти в библиотеку",
|
||||
"Need help? Contact our support team at support@readest.com": "Нужна помощь? Свяжитесь с нашей поддержкой: support@readest.com",
|
||||
"Free Plan": "Бесплатный план",
|
||||
"month": "месяц",
|
||||
"Unlimited Text-to-Speech Hours": "Неограниченные часы озвучивания текста",
|
||||
"DeepL Free Access (10K characters/day)": "Бесплатный доступ к DeepL (10 тыс. символов/день)",
|
||||
"AI Translations (per day)": "Переводы ИИ (в день)",
|
||||
"Cloud Storage": "Облачное хранилище",
|
||||
"Plus Plan": "План Plus",
|
||||
"Includes All Free Plan Benefits": "Включает все преимущества бесплатного плана",
|
||||
"Basic AI Translations": "Базовые переводы ИИ",
|
||||
"DeepL Pro Access (50K characters/day)": "Доступ к DeepL Pro (50 тыс. символов/день)",
|
||||
"2 GB Cloud Sync Space": "2 ГБ для синхронизации в облаке",
|
||||
"Pro Plan": "План Pro",
|
||||
"Includes All Plus Plan Benefits": "Включает все преимущества плана Plus",
|
||||
"More AI Translations": "Больше переводов ИИ",
|
||||
"DeepL Pro Access (200K characters/day)": "Доступ к DeepL Pro (200 тыс. символов/день)"
|
||||
}
|
||||
|
||||
@@ -183,35 +183,18 @@
|
||||
"Sign in with GitHub": "GitHub ile giriş yap",
|
||||
"Account": "Hesap",
|
||||
"Failed to delete user. Please try again later.": "Kullanıcı silinemedi. Lütfen daha sonra tekrar deneyin.",
|
||||
"Unlimited Offline/Online Reading": "Sınırsız Çevrimdışı/Çevrimiçi Okuma",
|
||||
"Unlimited Cloud Sync Devices": "Sınırsız Bulut Senkronizasyon Cihazları",
|
||||
"Essential Text-to-Speech Voices": "Temel Metinden Sese Dönüştürme Sesleri",
|
||||
"DeepL Free Access": "DeepL Ücretsiz Erişim",
|
||||
"Community Support": "Topluluk Desteği",
|
||||
"500 MB Cloud Sync Space": "500 MB Bulut Senkronizasyon Alanı",
|
||||
"Includes All Free Tier Benefits": "Tüm Ücretsiz Paket Avantajlarını İçerir",
|
||||
"AI Summaries": "Yapay Zeka Özetleri",
|
||||
"AI Translations": "Yapay Zeka Çevirileri",
|
||||
"Priority Support": "Öncelikli Destek",
|
||||
"DeepL Pro Access": "DeepL Pro Erişimi",
|
||||
"Expanded Text-to-Speech Voices": "Genişletilmiş Metinden Sese Dönüştürme Sesleri",
|
||||
"2000 MB Cloud Sync Space": "2000 MB Bulut Senkronizasyon Alanı",
|
||||
"Includes All Plus Tier Benefits": "Tüm Plus Paket Avantajlarını İçerir",
|
||||
"Unlimited AI Summaries": "Sınırsız Yapay Zeka Özetleri",
|
||||
"Unlimited AI Translations": "Sınırsız Yapay Zeka Çevirileri",
|
||||
"Unlimited DeepL Pro Access": "Sınırsız DeepL Pro Erişimi",
|
||||
"Advanced AI Tools": "Gelişmiş Yapay Zeka Araçları",
|
||||
"Early Feature Access": "Erken Özellik Erişimi",
|
||||
"10 GB Cloud Sync Space": "10 GB Bulut Senkronizasyon Alanı",
|
||||
"Loading profile...": "Profil yükleniyor...",
|
||||
"Features": "Özellikler",
|
||||
"Delete Account": "Hesabı Sil",
|
||||
"Delete Your Account?": "Hesabınızı Silmek İstiyor musunuz?",
|
||||
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "Bu işlem geri alınamaz. Buluttaki tüm verileriniz kalıcı olarak silinecektir.",
|
||||
"Delete Permanently": "Kalıcı Olarak Sil",
|
||||
"Free Tier": "Ücretsiz Paket",
|
||||
"Plus Tier": "Plus Paket",
|
||||
"Pro Tier": "Pro Paket",
|
||||
"RTL Direction": "RTL Yönü",
|
||||
"Maximum Column Height": "Maksimum Sütun Yüksekliği",
|
||||
"Maximum Column Width": "Maksimum Sütun Genişliği",
|
||||
@@ -377,5 +360,44 @@
|
||||
"Show Remaining Pages": "Kalan sayfaları göster",
|
||||
"Source Han Serif CN VF": "Source Han Serif",
|
||||
"Huiwen-mincho": "Huiwen Mincho",
|
||||
"KingHwa_OldSong": "KingHwa Song"
|
||||
"KingHwa_OldSong": "KingHwa Song",
|
||||
"Manage Subscription": "Aboneliği Yönet",
|
||||
"Coming Soon": "Yakında",
|
||||
"Upgrade to {{plan}}": "{{plan}} planına yükselt",
|
||||
"Upgrade to Plus or Pro": "Plus veya Pro'ya yükselt",
|
||||
"Current Plan": "Mevcut Plan",
|
||||
"Plan Limits": "Plan Limitleri",
|
||||
"Available Plans": "Mevcut Planlar",
|
||||
"{{current}} of {{all}}": "{{all}} üzerinden {{current}}",
|
||||
"Failed to manage subscription. Please try again later.": "Abonelik yönetimi başarısız oldu. Lütfen daha sonra tekrar deneyin.",
|
||||
"Processing your payment...": "Ödemeniz işleniyor...",
|
||||
"Please wait while we confirm your subscription.": "Aboneliğinizi onaylıyoruz, lütfen bekleyin.",
|
||||
"Payment Processing": "Ödeme İşleniyor",
|
||||
"Your payment is being processed. This usually takes a few moments.": "Ödemeniz işleniyor. Bu genelde birkaç saniye sürer.",
|
||||
"Payment Failed": "Ödeme Başarısız",
|
||||
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "Aboneliğinizi işleyemedik. Lütfen tekrar deneyin veya sorun devam ederse destek ile iletişime geçin.",
|
||||
"Back to Profile": "Profille Dön",
|
||||
"Subscription Successful!": "Abonelik Başarılı!",
|
||||
"Thank you for your subscription! Your payment has been processed successfully.": "Aboneliğiniz için teşekkürler! Ödemeniz başarıyla işlendi.",
|
||||
"Email:": "E-posta:",
|
||||
"Plan:": "Plan:",
|
||||
"Amount:": "Tutar:",
|
||||
"Subscription ID:": "Abonelik ID'si:",
|
||||
"Go to Library": "Kütüphaneye Git",
|
||||
"Need help? Contact our support team at support@readest.com": "Yardım mı gerekiyor? Destek ekibimizle iletişime geçin: support@readest.com",
|
||||
"Free Plan": "Ücretsiz Plan",
|
||||
"month": "ay",
|
||||
"Unlimited Text-to-Speech Hours": "Sınırsız Sesli Okuma Süresi",
|
||||
"DeepL Free Access (10K characters/day)": "DeepL Ücretsiz Erişim (Günde 10K karakter)",
|
||||
"AI Translations (per day)": "AI Çevirileri (günlük)",
|
||||
"Cloud Storage": "Bulut Depolama",
|
||||
"Plus Plan": "Plus Plan",
|
||||
"Includes All Free Plan Benefits": "Tüm Ücretsiz Plan Özelliklerini İçerir",
|
||||
"Basic AI Translations": "Temel AI Çevirileri",
|
||||
"DeepL Pro Access (50K characters/day)": "DeepL Pro Erişim (Günde 50K karakter)",
|
||||
"2 GB Cloud Sync Space": "2 GB Bulut Senkronizasyon Alanı",
|
||||
"Pro Plan": "Pro Plan",
|
||||
"Includes All Plus Plan Benefits": "Tüm Plus Plan Özelliklerini İçerir",
|
||||
"More AI Translations": "Daha Fazla AI Çevirisi",
|
||||
"DeepL Pro Access (200K characters/day)": "DeepL Pro Erişim (Günde 200K karakter)"
|
||||
}
|
||||
|
||||
@@ -183,35 +183,18 @@
|
||||
"Sign in with GitHub": "Увійти через GitHub",
|
||||
"Account": "Обліковий запис",
|
||||
"Failed to delete user. Please try again later.": "Не вдалося видалити користувача. Будь ласка, спробуйте пізніше.",
|
||||
"Unlimited Offline/Online Reading": "Необмежене читання офлайн/онлайн",
|
||||
"Unlimited Cloud Sync Devices": "Необмежена кількість пристроїв для хмарної синхронізації",
|
||||
"Essential Text-to-Speech Voices": "Основні голоси для перетворення тексту в мовлення",
|
||||
"DeepL Free Access": "Безкоштовний доступ до DeepL",
|
||||
"Community Support": "Підтримка спільноти",
|
||||
"500 MB Cloud Sync Space": "500 МБ простору для хмарної синхронізації",
|
||||
"Includes All Free Tier Benefits": "Включає всі переваги безкоштовного тарифу",
|
||||
"AI Summaries": "AI-резюме",
|
||||
"AI Translations": "AI-переклади",
|
||||
"Priority Support": "Пріоритетна підтримка",
|
||||
"DeepL Pro Access": "Доступ до DeepL Pro",
|
||||
"Expanded Text-to-Speech Voices": "Розширений набір голосів для перетворення тексту в мовлення",
|
||||
"2000 MB Cloud Sync Space": "2000 МБ простору для хмарної синхронізації",
|
||||
"Includes All Plus Tier Benefits": "Включає всі переваги тарифу Plus",
|
||||
"Unlimited AI Summaries": "Необмежені AI-резюме",
|
||||
"Unlimited AI Translations": "Необмежені AI-переклади",
|
||||
"Unlimited DeepL Pro Access": "Необмежений доступ до DeepL Pro",
|
||||
"Advanced AI Tools": "Розширені AI-інструменти",
|
||||
"Early Feature Access": "Ранній доступ до нових функцій",
|
||||
"10 GB Cloud Sync Space": "10 ГБ простору для хмарної синхронізації",
|
||||
"Loading profile...": "Завантаження профілю...",
|
||||
"Features": "Функції",
|
||||
"Delete Account": "Видалити обліковий запис",
|
||||
"Delete Your Account?": "Видалити ваш обліковий запис?",
|
||||
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "Цю дію неможливо скасувати. Всі ваші дані в хмарі будуть повністю видалені.",
|
||||
"Delete Permanently": "Видалити назавжди",
|
||||
"Free Tier": "Безкоштовний тариф",
|
||||
"Plus Tier": "Тариф Plus",
|
||||
"Pro Tier": "Тариф Pro",
|
||||
"RTL Direction": "Напрямок RTL",
|
||||
"Maximum Column Height": "Максимальна висота колонки",
|
||||
"Maximum Column Width": "Максимальна ширина колонки",
|
||||
@@ -385,5 +368,44 @@
|
||||
"Show Remaining Pages": "Показати залишок сторінок",
|
||||
"Source Han Serif CN VF": "Source Han Serif",
|
||||
"Huiwen-mincho": "Huiwen Mincho",
|
||||
"KingHwa_OldSong": "KingHwa Song"
|
||||
"KingHwa_OldSong": "KingHwa Song",
|
||||
"Manage Subscription": "Керувати підпискою",
|
||||
"Coming Soon": "Незабаром",
|
||||
"Upgrade to {{plan}}": "Перейти на {{plan}}",
|
||||
"Upgrade to Plus or Pro": "Перейти на Plus або Pro",
|
||||
"Current Plan": "Поточний план",
|
||||
"Plan Limits": "Обмеження плану",
|
||||
"Available Plans": "Доступні плани",
|
||||
"{{current}} of {{all}}": "{{current}} із {{all}}",
|
||||
"Failed to manage subscription. Please try again later.": "Не вдалося керувати підпискою. Спробуйте ще раз пізніше.",
|
||||
"Processing your payment...": "Обробка вашого платежу...",
|
||||
"Please wait while we confirm your subscription.": "Зачекайте, ми підтверджуємо вашу підписку.",
|
||||
"Payment Processing": "Обробка платежу",
|
||||
"Your payment is being processed. This usually takes a few moments.": "Ваш платіж обробляється. Зазвичай це займає кілька секунд.",
|
||||
"Payment Failed": "Платіж не вдався",
|
||||
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "Не вдалося обробити вашу підписку. Спробуйте ще раз або зверніться до служби підтримки, якщо проблема не зникне.",
|
||||
"Back to Profile": "Повернутися до профілю",
|
||||
"Subscription Successful!": "Підписка активована!",
|
||||
"Thank you for your subscription! Your payment has been processed successfully.": "Дякуємо за підписку! Ваш платіж успішно оброблено.",
|
||||
"Email:": "Електронна пошта:",
|
||||
"Plan:": "План:",
|
||||
"Amount:": "Сума:",
|
||||
"Subscription ID:": "ID підписки:",
|
||||
"Go to Library": "Перейти до бібліотеки",
|
||||
"Need help? Contact our support team at support@readest.com": "Потрібна допомога? Зверніться до служби підтримки: support@readest.com",
|
||||
"Free Plan": "Безкоштовний план",
|
||||
"month": "місяць",
|
||||
"Unlimited Text-to-Speech Hours": "Необмежені години озвучення тексту",
|
||||
"DeepL Free Access (10K characters/day)": "Безкоштовний доступ до DeepL (10 тис. символів/день)",
|
||||
"AI Translations (per day)": "AI-переклади (на день)",
|
||||
"Cloud Storage": "Хмарне сховище",
|
||||
"Plus Plan": "План Plus",
|
||||
"Includes All Free Plan Benefits": "Включає всі переваги Безкоштовного плану",
|
||||
"Basic AI Translations": "Базові AI-переклади",
|
||||
"DeepL Pro Access (50K characters/day)": "DeepL Pro доступ (50 тис. символів/день)",
|
||||
"2 GB Cloud Sync Space": "2 ГБ хмарного сховища для синхронізації",
|
||||
"Pro Plan": "План Pro",
|
||||
"Includes All Plus Plan Benefits": "Включає всі переваги плану Plus",
|
||||
"More AI Translations": "Більше AI-перекладів",
|
||||
"DeepL Pro Access (200K characters/day)": "DeepL Pro доступ (200 тис. символів/день)"
|
||||
}
|
||||
|
||||
@@ -183,35 +183,18 @@
|
||||
"Sign in with GitHub": "Đăng nhập với GitHub",
|
||||
"Account": "Tài khoản",
|
||||
"Failed to delete user. Please try again later.": "Không thể xóa người dùng. Vui lòng thử lại sau.",
|
||||
"Unlimited Offline/Online Reading": "Đọc ngoại tuyến/trực tuyến không giới hạn",
|
||||
"Unlimited Cloud Sync Devices": "Đồng bộ hóa thiết bị đám mây không giới hạn",
|
||||
"Essential Text-to-Speech Voices": "Giọng nói chuyển văn bản thành giọng nói cơ bản",
|
||||
"DeepL Free Access": "Truy cập DeepL miễn phí",
|
||||
"Community Support": "Hỗ trợ cộng đồng",
|
||||
"500 MB Cloud Sync Space": "500 MB không gian đồng bộ hóa đám mây",
|
||||
"Includes All Free Tier Benefits": "Bao gồm tất cả lợi ích của gói miễn phí",
|
||||
"AI Summaries": "Tóm tắt AI",
|
||||
"AI Translations": "Dịch thuật AI",
|
||||
"Priority Support": "Hỗ trợ ưu tiên",
|
||||
"DeepL Pro Access": "Truy cập DeepL Pro",
|
||||
"Expanded Text-to-Speech Voices": "Giọng nói chuyển văn bản thành giọng nói mở rộng",
|
||||
"2000 MB Cloud Sync Space": "2000 MB không gian đồng bộ hóa đám mây",
|
||||
"Includes All Plus Tier Benefits": "Bao gồm tất cả lợi ích của gói Plus",
|
||||
"Unlimited AI Summaries": "Tóm tắt AI không giới hạn",
|
||||
"Unlimited AI Translations": "Dịch thuật AI không giới hạn",
|
||||
"Unlimited DeepL Pro Access": "Truy cập DeepL Pro không giới hạn",
|
||||
"Advanced AI Tools": "Công cụ AI nâng cao",
|
||||
"Early Feature Access": "Truy cập tính năng sớm",
|
||||
"10 GB Cloud Sync Space": "10 GB không gian đồng bộ hóa đám mây",
|
||||
"Loading profile...": "Đang tải hồ sơ...",
|
||||
"Features": "Tính năng",
|
||||
"Delete Account": "Xóa tài khoản",
|
||||
"Delete Your Account?": "Xóa tài khoản của bạn?",
|
||||
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "Hành động này không thể hoàn tác. Tất cả dữ liệu của bạn trên đám mây sẽ bị xóa vĩnh viễn.",
|
||||
"Delete Permanently": "Xóa vĩnh viễn",
|
||||
"Free Tier": "Gói miễn phí",
|
||||
"Plus Tier": "Gói Plus",
|
||||
"Pro Tier": "Gói Pro",
|
||||
"RTL Direction": "Hướng RTL",
|
||||
"Maximum Column Height": "Chiều cao cột tối đa",
|
||||
"Maximum Column Width": "Chiều rộng cột tối đa",
|
||||
@@ -373,5 +356,44 @@
|
||||
"Show Remaining Pages": "Hiển thị trang còn lại",
|
||||
"Source Han Serif CN VF": "Source Han Serif",
|
||||
"Huiwen-mincho": "Huiwen Mincho",
|
||||
"KingHwa_OldSong": "KingHwa Song"
|
||||
"KingHwa_OldSong": "KingHwa Song",
|
||||
"Manage Subscription": "Quản lý đăng ký",
|
||||
"Coming Soon": "Sắp ra mắt",
|
||||
"Upgrade to {{plan}}": "Nâng cấp lên {{plan}}",
|
||||
"Upgrade to Plus or Pro": "Nâng cấp lên Plus hoặc Pro",
|
||||
"Current Plan": "Gói hiện tại",
|
||||
"Plan Limits": "Giới hạn gói",
|
||||
"Available Plans": "Gói khả dụng",
|
||||
"{{current}} of {{all}}": "{{current}} trên {{all}}",
|
||||
"Failed to manage subscription. Please try again later.": "Không thể quản lý đăng ký. Vui lòng thử lại sau.",
|
||||
"Processing your payment...": "Đang xử lý thanh toán...",
|
||||
"Please wait while we confirm your subscription.": "Vui lòng chờ trong khi chúng tôi xác nhận đăng ký của bạn.",
|
||||
"Payment Processing": "Đang xử lý thanh toán",
|
||||
"Your payment is being processed. This usually takes a few moments.": "Thanh toán của bạn đang được xử lý. Thường mất vài giây.",
|
||||
"Payment Failed": "Thanh toán thất bại",
|
||||
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "Chúng tôi không thể xử lý đăng ký của bạn. Vui lòng thử lại hoặc liên hệ hỗ trợ nếu sự cố tiếp tục.",
|
||||
"Back to Profile": "Quay lại hồ sơ",
|
||||
"Subscription Successful!": "Đăng ký thành công!",
|
||||
"Thank you for your subscription! Your payment has been processed successfully.": "Cảm ơn bạn đã đăng ký! Thanh toán của bạn đã được xử lý thành công.",
|
||||
"Email:": "Email:",
|
||||
"Plan:": "Gói:",
|
||||
"Amount:": "Số tiền:",
|
||||
"Subscription ID:": "ID đăng ký:",
|
||||
"Go to Library": "Đi đến Thư viện",
|
||||
"Need help? Contact our support team at support@readest.com": "Cần hỗ trợ? Liên hệ nhóm hỗ trợ tại support@readest.com",
|
||||
"Free Plan": "Gói miễn phí",
|
||||
"month": "tháng",
|
||||
"Unlimited Text-to-Speech Hours": "Không giới hạn giờ chuyển văn bản thành giọng nói",
|
||||
"DeepL Free Access (10K characters/day)": "Truy cập DeepL miễn phí (10.000 ký tự/ngày)",
|
||||
"AI Translations (per day)": "Dịch AI (mỗi ngày)",
|
||||
"Cloud Storage": "Lưu trữ đám mây",
|
||||
"Plus Plan": "Gói Plus",
|
||||
"Includes All Free Plan Benefits": "Bao gồm tất cả lợi ích của gói miễn phí",
|
||||
"Basic AI Translations": "Dịch AI cơ bản",
|
||||
"DeepL Pro Access (50K characters/day)": "Truy cập DeepL Pro (50.000 ký tự/ngày)",
|
||||
"2 GB Cloud Sync Space": "2 GB đồng bộ đám mây",
|
||||
"Pro Plan": "Gói Pro",
|
||||
"Includes All Plus Plan Benefits": "Bao gồm tất cả lợi ích của gói Plus",
|
||||
"More AI Translations": "Thêm dịch AI",
|
||||
"DeepL Pro Access (200K characters/day)": "Truy cập DeepL Pro (200.000 ký tự/ngày)"
|
||||
}
|
||||
|
||||
@@ -183,35 +183,18 @@
|
||||
"Sign in with GitHub": "使用 GitHub 登录",
|
||||
"Account": "账户",
|
||||
"Failed to delete user. Please try again later.": "删除用户失败。请稍后重试。",
|
||||
"Unlimited Offline/Online Reading": "无限离线和在线阅读",
|
||||
"Unlimited Cloud Sync Devices": "无限云同步设备个数",
|
||||
"Essential Text-to-Speech Voices": "基础 TTS 语音包",
|
||||
"DeepL Free Access": "免费版 DeepL 翻译",
|
||||
"Community Support": "社区支持",
|
||||
"500 MB Cloud Sync Space": "500 MB 云同步空间",
|
||||
"Includes All Free Tier Benefits": "包含所有免费版权益",
|
||||
"AI Summaries": "AI 摘要",
|
||||
"AI Translations": "AI 翻译",
|
||||
"Priority Support": "优先支持",
|
||||
"DeepL Pro Access": "专业版 DeepL 翻译",
|
||||
"Expanded Text-to-Speech Voices": "更多文本转语音声音",
|
||||
"2000 MB Cloud Sync Space": "2000 MB 云同步空间",
|
||||
"Includes All Plus Tier Benefits": "包含所有增强版权益",
|
||||
"Unlimited AI Summaries": "无限使用 AI 摘要",
|
||||
"Unlimited AI Translations": "无限使用 AI 翻译",
|
||||
"Unlimited DeepL Pro Access": "无限使用专业版 DeepL 翻译",
|
||||
"Advanced AI Tools": "高级 AI 工具",
|
||||
"Early Feature Access": "抢先体验新功能",
|
||||
"10 GB Cloud Sync Space": "10 GB 云同步空间",
|
||||
"Loading profile...": "加载个人资料中...",
|
||||
"Features": "功能特性",
|
||||
"Delete Account": "删除账户",
|
||||
"Delete Your Account?": "删除您的账户?",
|
||||
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "此操作无法撤销。您在云端的所有数据将被永久删除。",
|
||||
"Delete Permanently": "永久删除",
|
||||
"Free Tier": "免费版",
|
||||
"Plus Tier": "增强版",
|
||||
"Pro Tier": "专业版",
|
||||
"RTL Direction": "从右向左",
|
||||
"Maximum Column Height": "最大列高",
|
||||
"Maximum Column Width": "最大列宽",
|
||||
@@ -373,5 +356,44 @@
|
||||
"Show Remaining Pages": "显示剩余页数",
|
||||
"Source Han Serif CN VF": "思源宋体",
|
||||
"Huiwen-mincho": "汇文明朝体",
|
||||
"KingHwa_OldSong": "京华老宋体"
|
||||
"KingHwa_OldSong": "京华老宋体",
|
||||
"Manage Subscription": "管理订阅",
|
||||
"Coming Soon": "即将上线",
|
||||
"Upgrade to {{plan}}": "升级到 {{plan}}",
|
||||
"Upgrade to Plus or Pro": "升级到 Plus 或 Pro",
|
||||
"Current Plan": "当前套餐",
|
||||
"Plan Limits": "套餐限制",
|
||||
"Available Plans": "可用套餐",
|
||||
"{{current}} of {{all}}": "{{current}} / {{all}}",
|
||||
"Failed to manage subscription. Please try again later.": "无法管理订阅,请稍后再试。",
|
||||
"Processing your payment...": "正在处理付款...",
|
||||
"Please wait while we confirm your subscription.": "请稍候,我们正在确认您的订阅。",
|
||||
"Payment Processing": "付款处理中",
|
||||
"Your payment is being processed. This usually takes a few moments.": "您的付款正在处理中,通常需要几秒钟。",
|
||||
"Payment Failed": "付款失败",
|
||||
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "我们无法处理您的订阅。请重试,或如问题持续请联系支持。",
|
||||
"Back to Profile": "返回个人资料",
|
||||
"Subscription Successful!": "订阅成功!",
|
||||
"Thank you for your subscription! Your payment has been processed successfully.": "感谢您的订阅!您的付款已成功处理。",
|
||||
"Email:": "邮箱:",
|
||||
"Plan:": "套餐:",
|
||||
"Amount:": "金额:",
|
||||
"Subscription ID:": "订阅 ID:",
|
||||
"Go to Library": "前往书库",
|
||||
"Need help? Contact our support team at support@readest.com": "需要帮助?请联系支持团队:support@readest.com",
|
||||
"Free Plan": "免费套餐",
|
||||
"month": "月",
|
||||
"Unlimited Text-to-Speech Hours": "无限文本转语音时长",
|
||||
"DeepL Free Access (10K characters/day)": "DeepL 免费额度(每日1万字符)",
|
||||
"AI Translations (per day)": "AI 翻译(每日)",
|
||||
"Cloud Storage": "云存储",
|
||||
"Plus Plan": "Plus 套餐",
|
||||
"Includes All Free Plan Benefits": "包含所有免费套餐功能",
|
||||
"Basic AI Translations": "基础 AI 翻译",
|
||||
"DeepL Pro Access (50K characters/day)": "DeepL Pro(每日5万字符)",
|
||||
"2 GB Cloud Sync Space": "2GB 云同步空间",
|
||||
"Pro Plan": "Pro 套餐",
|
||||
"Includes All Plus Plan Benefits": "包含所有 Plus 套餐功能",
|
||||
"More AI Translations": "更多 AI 翻译",
|
||||
"DeepL Pro Access (200K characters/day)": "DeepL Pro(每日20万字符)"
|
||||
}
|
||||
|
||||
@@ -183,35 +183,18 @@
|
||||
"Sign in with GitHub": "使用 GitHub 登入",
|
||||
"Account": "帳戶",
|
||||
"Failed to delete user. Please try again later.": "刪除使用者失敗。請稍後再試。",
|
||||
"Unlimited Offline/Online Reading": "無限離線/線上閱讀",
|
||||
"Unlimited Cloud Sync Devices": "無限雲端同步裝置",
|
||||
"Essential Text-to-Speech Voices": "基本文字轉語音聲音",
|
||||
"DeepL Free Access": "DeepL免費存取",
|
||||
"Community Support": "社群支援",
|
||||
"500 MB Cloud Sync Space": "500 MB雲端同步空間",
|
||||
"Includes All Free Tier Benefits": "包含所有免費方案權益",
|
||||
"AI Summaries": "AI摘要",
|
||||
"AI Translations": "AI翻譯",
|
||||
"Priority Support": "優先支援",
|
||||
"DeepL Pro Access": "DeepL專業版存取",
|
||||
"Expanded Text-to-Speech Voices": "擴展文字轉語音聲音",
|
||||
"2000 MB Cloud Sync Space": "2000 MB雲端同步空間",
|
||||
"Includes All Plus Tier Benefits": "包含所有Plus方案權益",
|
||||
"Unlimited AI Summaries": "無限AI摘要",
|
||||
"Unlimited AI Translations": "無限AI翻譯",
|
||||
"Unlimited DeepL Pro Access": "無限DeepL專業版存取",
|
||||
"Advanced AI Tools": "進階AI工具",
|
||||
"Early Feature Access": "搶先體驗新功能",
|
||||
"10 GB Cloud Sync Space": "10 GB雲端同步空間",
|
||||
"Loading profile...": "載入個人資料中...",
|
||||
"Features": "功能",
|
||||
"Delete Account": "刪除帳戶",
|
||||
"Delete Your Account?": "刪除您的帳戶?",
|
||||
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "此操作無法撤銷。您在雲端的所有資料將被永久刪除。",
|
||||
"Delete Permanently": "永久刪除",
|
||||
"Free Tier": "免費方案",
|
||||
"Plus Tier": "Plus方案",
|
||||
"Pro Tier": "專業方案",
|
||||
"RTL Direction": "從右向左",
|
||||
"Maximum Column Height": "最大列高",
|
||||
"Maximum Column Width": "最大列寬",
|
||||
@@ -373,5 +356,44 @@
|
||||
"Show Remaining Pages": "顯示剩餘頁數",
|
||||
"Source Han Serif CN VF": "思源宋體",
|
||||
"Huiwen-mincho": "匯文明朝體",
|
||||
"KingHwa_OldSong": "京華老宋體"
|
||||
"KingHwa_OldSong": "京華老宋體",
|
||||
"Manage Subscription": "管理訂閱",
|
||||
"Coming Soon": "即將推出",
|
||||
"Upgrade to {{plan}}": "升級到 {{plan}}",
|
||||
"Upgrade to Plus or Pro": "升級到 Plus 或 Pro",
|
||||
"Current Plan": "當前方案",
|
||||
"Plan Limits": "方案限制",
|
||||
"Available Plans": "可用方案",
|
||||
"{{current}} of {{all}}": "{{current}} / {{all}}",
|
||||
"Failed to manage subscription. Please try again later.": "無法管理訂閱,請稍後再試。",
|
||||
"Processing your payment...": "正在處理付款...",
|
||||
"Please wait while we confirm your subscription.": "請稍候,我們正在確認您的訂閱。",
|
||||
"Payment Processing": "付款處理中",
|
||||
"Your payment is being processed. This usually takes a few moments.": "您的付款正在處理中,通常需要幾秒鐘。",
|
||||
"Payment Failed": "付款失敗",
|
||||
"We couldn't process your subscription. Please try again or contact support if the issue persists.": "我們無法處理您的訂閱。請重試,或若問題持續,請聯絡客服。",
|
||||
"Back to Profile": "返回個人資料",
|
||||
"Subscription Successful!": "訂閱成功!",
|
||||
"Thank you for your subscription! Your payment has been processed successfully.": "感謝您的訂閱!您的付款已成功完成。",
|
||||
"Email:": "電子郵件:",
|
||||
"Plan:": "方案:",
|
||||
"Amount:": "金額:",
|
||||
"Subscription ID:": "訂閱 ID:",
|
||||
"Go to Library": "前往書庫",
|
||||
"Need help? Contact our support team at support@readest.com": "需要協助?請聯絡支援團隊:support@readest.com",
|
||||
"Free Plan": "免費方案",
|
||||
"month": "月",
|
||||
"Unlimited Text-to-Speech Hours": "無限文字轉語音時數",
|
||||
"DeepL Free Access (10K characters/day)": "DeepL 免費使用(每日1萬字)",
|
||||
"AI Translations (per day)": "AI 翻譯(每日)",
|
||||
"Cloud Storage": "雲端儲存",
|
||||
"Plus Plan": "Plus 方案",
|
||||
"Includes All Free Plan Benefits": "包含所有免費方案功能",
|
||||
"Basic AI Translations": "基本 AI 翻譯",
|
||||
"DeepL Pro Access (50K characters/day)": "DeepL Pro(每日5萬字)",
|
||||
"2 GB Cloud Sync Space": "2GB 雲端同步空間",
|
||||
"Pro Plan": "Pro 方案",
|
||||
"Includes All Plus Plan Benefits": "包含所有 Plus 方案功能",
|
||||
"More AI Translations": "更多 AI 翻譯",
|
||||
"DeepL Pro Access (200K characters/day)": "DeepL Pro(每日20萬字)"
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
"img-src": "'self' blob: data: asset: http://asset.localhost https://*",
|
||||
"style-src": "'self' 'unsafe-inline' blob: asset: http://asset.localhost https://cdn.jsdelivr.net https://fonts.googleapis.com https://ik.imagekit.io",
|
||||
"font-src": "'self' blob: data: asset: http://asset.localhost tauri: https://db.onlinewebfonts.com https://cdn.jsdelivr.net https://fonts.gstatic.com https://ik.imagekit.io",
|
||||
"frame-src": "'self' blob: asset: http://asset.localhost",
|
||||
"script-src": "'self' 'unsafe-inline' 'unsafe-eval' blob: asset: http://asset.localhost https://*.sentry.io https://*.posthog.com"
|
||||
"frame-src": "'self' blob: asset: http://asset.localhost https://*.stripe.com",
|
||||
"script-src": "'self' 'unsafe-inline' 'unsafe-eval' blob: asset: http://asset.localhost https://*.sentry.io https://*.posthog.com https://*.stripe.com"
|
||||
},
|
||||
"assetProtocol": {
|
||||
"enable": true,
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
import { useState } from 'react';
|
||||
import { useTranslation } from '@/hooks/useTranslation';
|
||||
import { UserPlan } from '@/types/user';
|
||||
|
||||
interface DeleteConfirmationModalProps {
|
||||
show: boolean;
|
||||
onCancel: () => void;
|
||||
onConfirm: () => void;
|
||||
}
|
||||
|
||||
const DeleteConfirmationModal: React.FC<DeleteConfirmationModalProps> = ({
|
||||
show,
|
||||
onCancel,
|
||||
onConfirm,
|
||||
}) => {
|
||||
const _ = useTranslation();
|
||||
if (!show) return null;
|
||||
|
||||
return (
|
||||
<div className='fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50 p-4'>
|
||||
<div className='w-full max-w-md rounded-2xl bg-white p-6'>
|
||||
<h3 className='mb-4 text-xl font-bold text-gray-800'>{_('Delete Your Account?')}</h3>
|
||||
<p className='mb-6 text-gray-600'>
|
||||
{_(
|
||||
'This action cannot be undone. All your data in the cloud will be permanently deleted.',
|
||||
)}
|
||||
</p>
|
||||
<div className='flex flex-col gap-3 sm:flex-row'>
|
||||
<button
|
||||
onClick={onCancel}
|
||||
className='flex-1 rounded-lg bg-gray-300 px-4 py-2 font-medium text-gray-800 hover:bg-gray-400'
|
||||
>
|
||||
{_('Cancel')}
|
||||
</button>
|
||||
<button
|
||||
onClick={onConfirm}
|
||||
className='flex-1 rounded-lg bg-red-500 px-4 py-2 font-medium text-white hover:bg-red-600'
|
||||
>
|
||||
{_('Delete Permanently')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
interface AccountActionsProps {
|
||||
userPlan: UserPlan;
|
||||
onLogout: () => void;
|
||||
onConfirmDelete: () => void;
|
||||
onManageSubscription: () => void;
|
||||
}
|
||||
|
||||
const AccountActions: React.FC<AccountActionsProps> = ({
|
||||
userPlan,
|
||||
onLogout,
|
||||
onConfirmDelete,
|
||||
onManageSubscription,
|
||||
}) => {
|
||||
const _ = useTranslation();
|
||||
const [showConfirmDelete, setShowConfirmDelete] = useState(false);
|
||||
|
||||
const handleDeleteRequest = () => {
|
||||
setShowConfirmDelete(true);
|
||||
};
|
||||
|
||||
const handleCancelDelete = () => {
|
||||
setShowConfirmDelete(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<DeleteConfirmationModal
|
||||
show={showConfirmDelete}
|
||||
onCancel={handleCancelDelete}
|
||||
onConfirm={async () => {
|
||||
await onConfirmDelete();
|
||||
setShowConfirmDelete(false);
|
||||
}}
|
||||
/>
|
||||
<div className='flex flex-col gap-4 md:flex-row'>
|
||||
{userPlan !== 'free' && (
|
||||
<button
|
||||
onClick={onManageSubscription}
|
||||
className='w-full rounded-lg bg-blue-100 px-6 py-3 font-medium text-blue-600 transition-colors hover:bg-blue-200 md:w-auto'
|
||||
>
|
||||
{_('Manage Subscription')}
|
||||
</button>
|
||||
)}
|
||||
<button
|
||||
onClick={onLogout}
|
||||
className='w-full rounded-lg bg-gray-200 px-6 py-3 font-medium text-gray-800 transition-colors hover:bg-gray-300 md:w-auto'
|
||||
>
|
||||
{_('Sign Out')}
|
||||
</button>
|
||||
<button
|
||||
onClick={handleDeleteRequest}
|
||||
className='w-full rounded-lg bg-red-100 px-6 py-3 font-medium text-red-600 transition-colors hover:bg-red-200 md:w-auto'
|
||||
>
|
||||
{_('Delete Account')}
|
||||
</button>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default AccountActions;
|
||||
@@ -0,0 +1,41 @@
|
||||
import clsx from 'clsx';
|
||||
import { useRef } from 'react';
|
||||
import { IoArrowBack } from 'react-icons/io5';
|
||||
import { useEnv } from '@/context/EnvContext';
|
||||
import { useTrafficLightStore } from '@/store/trafficLightStore';
|
||||
import WindowButtons from '@/components/WindowButtons';
|
||||
|
||||
interface ProfileHeaderProps {
|
||||
onGoBack: () => void;
|
||||
}
|
||||
|
||||
const ProfileHeader: React.FC<ProfileHeaderProps> = ({ onGoBack }) => {
|
||||
const { appService } = useEnv();
|
||||
const { isTrafficLightVisible } = useTrafficLightStore();
|
||||
const headerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={headerRef}
|
||||
className={clsx(
|
||||
'fixed z-30 flex w-full items-center justify-between py-2 pe-6 ps-4',
|
||||
appService?.hasTrafficLight && 'pt-11',
|
||||
)}
|
||||
>
|
||||
<button onClick={onGoBack} className={clsx('btn btn-ghost h-8 min-h-8 w-8 p-0')}>
|
||||
<IoArrowBack className='text-base-content' />
|
||||
</button>
|
||||
|
||||
{appService?.hasWindowBar && (
|
||||
<WindowButtons
|
||||
headerRef={headerRef}
|
||||
showMinimize={!isTrafficLightVisible}
|
||||
showMaximize={!isTrafficLightVisible}
|
||||
showClose={!isTrafficLightVisible}
|
||||
onClose={onGoBack}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
export default ProfileHeader;
|
||||
@@ -0,0 +1,69 @@
|
||||
import { useTranslation } from '@/hooks/useTranslation';
|
||||
import { PlanDetails } from '../utils/plan';
|
||||
|
||||
interface PlanActionButtonProps {
|
||||
plan: PlanDetails;
|
||||
isUserPlan: boolean;
|
||||
comingSoon?: boolean;
|
||||
upgradable?: boolean;
|
||||
onSubscribe: (priceId?: string) => void;
|
||||
onPlanSwipe: (direction: 'left' | 'right') => void;
|
||||
}
|
||||
|
||||
const PlanActionButton: React.FC<PlanActionButtonProps> = ({
|
||||
plan,
|
||||
isUserPlan,
|
||||
comingSoon,
|
||||
upgradable,
|
||||
onSubscribe,
|
||||
onPlanSwipe,
|
||||
}) => {
|
||||
const _ = useTranslation();
|
||||
|
||||
if (upgradable && plan.plan !== 'free' && !isUserPlan) {
|
||||
if (comingSoon) {
|
||||
return (
|
||||
<button
|
||||
disabled
|
||||
className='w-full cursor-default rounded-lg bg-gray-200 px-6 py-3 font-semibold text-gray-500'
|
||||
>
|
||||
{_('Coming Soon')}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<button
|
||||
onClick={() => onSubscribe(plan.price_id)}
|
||||
className='w-full rounded-lg bg-blue-600 px-6 py-3 font-semibold text-white transition-colors hover:bg-blue-700'
|
||||
>
|
||||
{_('Upgrade to {{plan}}', { plan: _(plan.name) })}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
if (plan.plan === 'free' && isUserPlan) {
|
||||
return (
|
||||
<button
|
||||
onClick={() => onPlanSwipe('left')}
|
||||
className='w-full rounded-lg bg-blue-600 px-6 py-3 font-semibold text-white transition-colors hover:bg-blue-700'
|
||||
>
|
||||
{_('Upgrade to Plus or Pro')}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
if (isUserPlan) {
|
||||
return (
|
||||
<button
|
||||
disabled
|
||||
className='w-full cursor-default rounded-lg bg-green-100 px-6 py-3 font-semibold text-green-700'
|
||||
>
|
||||
{_('Current Plan')}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
export default PlanActionButton;
|
||||
@@ -0,0 +1,88 @@
|
||||
import { IoCheckmark } from 'react-icons/io5';
|
||||
import { useTranslation } from '@/hooks/useTranslation';
|
||||
import { PlanDetails } from '../utils/plan';
|
||||
import PlanActionButton from './PlanActionButton';
|
||||
|
||||
interface PlanCardProps {
|
||||
plan: PlanDetails;
|
||||
isUserPlan: boolean;
|
||||
comingSoon?: boolean;
|
||||
upgradable?: boolean;
|
||||
index: number;
|
||||
currentPlanIndex: number;
|
||||
onSubscribe: (priceId?: string) => void;
|
||||
onPlanSwipe: (direction: 'left' | 'right') => void;
|
||||
}
|
||||
|
||||
const PlanCard: React.FC<PlanCardProps> = ({
|
||||
plan,
|
||||
isUserPlan,
|
||||
comingSoon,
|
||||
upgradable,
|
||||
index,
|
||||
currentPlanIndex,
|
||||
onSubscribe,
|
||||
onPlanSwipe,
|
||||
}) => {
|
||||
const _ = useTranslation();
|
||||
|
||||
return (
|
||||
<div
|
||||
key={plan.plan}
|
||||
className='w-full min-w-72 max-w-96 flex-shrink-0 p-6'
|
||||
style={{ scrollSnapAlign: 'start' }}
|
||||
>
|
||||
<div
|
||||
className={`rounded-xl border-2 p-6 ${plan.color} ${index === currentPlanIndex ? 'ring-2 ring-blue-500' : ''}`}
|
||||
>
|
||||
<div className='mb-6 text-center'>
|
||||
<h4 className='mb-2 text-2xl font-bold'>{_(plan.name)}</h4>
|
||||
<div className='text-3xl font-bold'>
|
||||
{`$${(plan.price / 100).toFixed(2)}`}
|
||||
<span className='text-lg font-normal'>/{_(plan.interval)}</span>
|
||||
</div>
|
||||
{isUserPlan && (
|
||||
<div className='mt-3'>
|
||||
<span className='inline-flex items-center rounded-full bg-green-100 px-3 py-1 text-sm font-medium text-green-800'>
|
||||
<IoCheckmark className='mr-1 h-4 w-4' />
|
||||
{_('Current Plan')}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className='mb-6 space-y-3'>
|
||||
{plan.features.map((feature, featureIndex) => (
|
||||
<div key={featureIndex} className='flex items-center'>
|
||||
<IoCheckmark className='mr-3 h-5 w-5 flex-shrink-0 text-green-500' />
|
||||
<span>{_(feature)}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className='mb-6 rounded-lg bg-white/50 p-4'>
|
||||
<h5 className='mb-3 font-semibold'>{_('Plan Limits')}</h5>
|
||||
<div className='space-y-2'>
|
||||
{Object.entries(plan.limits).map(([key, value]) => (
|
||||
<div key={key} className='flex justify-between text-sm'>
|
||||
<span>{_(key)}:</span>
|
||||
<span className='font-medium'>{value}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<PlanActionButton
|
||||
plan={plan}
|
||||
comingSoon={comingSoon}
|
||||
upgradable={upgradable}
|
||||
isUserPlan={isUserPlan}
|
||||
onSubscribe={onSubscribe}
|
||||
onPlanSwipe={onPlanSwipe}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default PlanCard;
|
||||
@@ -0,0 +1,27 @@
|
||||
import { PlanDetails } from '../utils/plan';
|
||||
|
||||
interface PlanIndicatorsProps {
|
||||
allPlans: PlanDetails[];
|
||||
currentPlanIndex: number;
|
||||
onPlanSelect: (index: number) => void;
|
||||
}
|
||||
|
||||
const PlanIndicators: React.FC<PlanIndicatorsProps> = ({
|
||||
allPlans,
|
||||
currentPlanIndex,
|
||||
onPlanSelect,
|
||||
}) => (
|
||||
<div className='flex justify-center space-x-2 pb-6 pt-2'>
|
||||
{allPlans.map((_, index) => (
|
||||
<button
|
||||
key={index}
|
||||
onClick={() => onPlanSelect(index)}
|
||||
className={`h-2 w-2 rounded-full transition-colors ${
|
||||
index === currentPlanIndex ? 'bg-blue-500' : 'bg-gray-300'
|
||||
}`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
|
||||
export default PlanIndicators;
|
||||
@@ -0,0 +1,48 @@
|
||||
import { IoChevronBack, IoChevronForward } from 'react-icons/io5';
|
||||
import { useTranslation } from '@/hooks/useTranslation';
|
||||
|
||||
interface PlanNavigationProps {
|
||||
currentPlanIndex: number;
|
||||
totalPlans: number;
|
||||
onPlanSwipe: (direction: 'left' | 'right') => void;
|
||||
}
|
||||
|
||||
const PlanNavigation: React.FC<PlanNavigationProps> = ({
|
||||
currentPlanIndex,
|
||||
totalPlans,
|
||||
onPlanSwipe,
|
||||
}) => {
|
||||
const _ = useTranslation();
|
||||
|
||||
return (
|
||||
<div className='border-b bg-gray-50 px-6 py-4'>
|
||||
<div className='flex items-center justify-between'>
|
||||
<h3 className='text-lg font-semibold'>{_('Available Plans')}</h3>
|
||||
<div className='flex items-center space-x-2'>
|
||||
<button
|
||||
onClick={() => onPlanSwipe('right')}
|
||||
disabled={currentPlanIndex === 0}
|
||||
className='rounded-lg p-1 hover:bg-gray-200 disabled:cursor-not-allowed disabled:opacity-50'
|
||||
>
|
||||
<IoChevronBack className='h-5 w-5' />
|
||||
</button>
|
||||
<span className='text-sm text-gray-600'>
|
||||
{_('{{current}} of {{all}}', {
|
||||
current: currentPlanIndex + 1,
|
||||
all: totalPlans,
|
||||
})}
|
||||
</span>
|
||||
<button
|
||||
onClick={() => onPlanSwipe('left')}
|
||||
disabled={currentPlanIndex === totalPlans - 1}
|
||||
className='rounded-lg p-1 hover:bg-gray-200 disabled:cursor-not-allowed disabled:opacity-50'
|
||||
>
|
||||
<IoChevronForward className='h-5 w-5' />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default PlanNavigation;
|
||||
@@ -0,0 +1,160 @@
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { debounce } from '@/utils/debounce';
|
||||
import { isWebAppPlatform } from '@/services/environment';
|
||||
import { getPlanDetails } from '../utils/plan';
|
||||
import { AvailablePlan } from '../page';
|
||||
import { UserPlan } from '@/types/user';
|
||||
import PlanNavigation from './PlanNavigation';
|
||||
import PlanCard from './PlanCard';
|
||||
import PlanIndicators from './PlanIndicators';
|
||||
|
||||
interface PlansComparisonProps {
|
||||
availablePlans: AvailablePlan[];
|
||||
userPlan: UserPlan;
|
||||
onSubscribe: (priceId?: string) => void;
|
||||
}
|
||||
|
||||
const PlansComparison: React.FC<PlansComparisonProps> = ({
|
||||
availablePlans,
|
||||
userPlan,
|
||||
onSubscribe,
|
||||
}) => {
|
||||
const [currentPlanIndex, setCurrentPlanIndex] = useState(0);
|
||||
const [userPlanIndex, setUserPlanIndex] = useState(0);
|
||||
const plansScrollRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const userPlans: UserPlan[] = ['free', 'plus', 'pro'];
|
||||
|
||||
useEffect(() => {
|
||||
if (userPlan) {
|
||||
const initialPlanIndex = userPlans.indexOf(userPlan);
|
||||
setCurrentPlanIndex(Math.max(0, initialPlanIndex));
|
||||
setUserPlanIndex(Math.max(0, initialPlanIndex));
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [userPlan]);
|
||||
|
||||
const handlePlanSwipe = (direction: 'left' | 'right') => {
|
||||
if (direction === 'left' && currentPlanIndex < allPlans.length - 1) {
|
||||
setCurrentPlanIndex(currentPlanIndex + 1);
|
||||
} else if (direction === 'right' && currentPlanIndex > 0) {
|
||||
setCurrentPlanIndex(currentPlanIndex - 1);
|
||||
}
|
||||
};
|
||||
|
||||
const handleTouchStart = (e: React.TouchEvent) => {
|
||||
const touchStart = e.touches[0]!.clientX;
|
||||
const handleTouchMove = (moveEvent: TouchEvent) => {
|
||||
const touchEnd = moveEvent.touches[0]!.clientX;
|
||||
const diff = touchStart - touchEnd;
|
||||
|
||||
if (Math.abs(diff) > 50) {
|
||||
if (diff > 0) {
|
||||
handlePlanSwipe('left');
|
||||
} else {
|
||||
handlePlanSwipe('right');
|
||||
}
|
||||
document.removeEventListener('touchmove', handleTouchMove);
|
||||
}
|
||||
};
|
||||
|
||||
const handleTouchEnd = () => {
|
||||
document.removeEventListener('touchmove', handleTouchMove);
|
||||
document.removeEventListener('touchend', handleTouchEnd);
|
||||
};
|
||||
|
||||
document.addEventListener('touchmove', handleTouchMove);
|
||||
document.addEventListener('touchend', handleTouchEnd);
|
||||
};
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
const handleScroll = useCallback(
|
||||
debounce(() => {
|
||||
if (plansScrollRef.current) {
|
||||
const container = plansScrollRef.current;
|
||||
const scrollLeft = container.scrollLeft;
|
||||
const containerWidth = container.clientWidth;
|
||||
const scrollWidth = container.scrollWidth;
|
||||
|
||||
const cardWidth = scrollWidth / allPlans.length;
|
||||
const viewportCenter = scrollLeft + containerWidth / 2;
|
||||
const newIndex = Math.floor(viewportCenter / cardWidth);
|
||||
const clampedIndex = Math.max(0, Math.min(newIndex, allPlans.length - 1));
|
||||
|
||||
if (clampedIndex !== currentPlanIndex) {
|
||||
setCurrentPlanIndex(clampedIndex);
|
||||
}
|
||||
}
|
||||
}, 100),
|
||||
[currentPlanIndex],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!plansScrollRef.current) return;
|
||||
|
||||
const container = plansScrollRef.current;
|
||||
container.addEventListener('scroll', handleScroll);
|
||||
return () => {
|
||||
container.removeEventListener('scroll', handleScroll);
|
||||
};
|
||||
}, [currentPlanIndex, handleScroll]);
|
||||
|
||||
useEffect(() => {
|
||||
if (plansScrollRef.current) {
|
||||
const planWidth = plansScrollRef.current.scrollWidth / allPlans.length;
|
||||
const scrollPosition = currentPlanIndex * planWidth;
|
||||
plansScrollRef.current.scrollTo({
|
||||
left: scrollPosition,
|
||||
behavior: 'smooth',
|
||||
});
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [currentPlanIndex]);
|
||||
|
||||
const allPlans = userPlans.map((plan) => ({
|
||||
...getPlanDetails(plan, availablePlans),
|
||||
}));
|
||||
|
||||
return (
|
||||
<div className='overflow-hidden rounded-xl border bg-white shadow-sm'>
|
||||
<PlanNavigation
|
||||
currentPlanIndex={currentPlanIndex}
|
||||
totalPlans={allPlans.length}
|
||||
onPlanSwipe={handlePlanSwipe}
|
||||
/>
|
||||
|
||||
<div
|
||||
ref={plansScrollRef}
|
||||
className='scrollbar-hide flex items-center overflow-x-auto scroll-smooth pe-20'
|
||||
onTouchStart={handleTouchStart}
|
||||
style={{
|
||||
scrollSnapType: 'x mandatory',
|
||||
scrollbarWidth: 'none',
|
||||
msOverflowStyle: 'none',
|
||||
}}
|
||||
>
|
||||
{allPlans.map((plan, index) => (
|
||||
<PlanCard
|
||||
key={plan.plan}
|
||||
plan={plan}
|
||||
comingSoon={!isWebAppPlatform()}
|
||||
isUserPlan={plan.plan === userPlan}
|
||||
upgradable={index > userPlanIndex}
|
||||
index={index}
|
||||
currentPlanIndex={currentPlanIndex}
|
||||
onSubscribe={onSubscribe}
|
||||
onPlanSwipe={handlePlanSwipe}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<PlanIndicators
|
||||
allPlans={allPlans}
|
||||
currentPlanIndex={currentPlanIndex}
|
||||
onPlanSelect={setCurrentPlanIndex}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default PlansComparison;
|
||||
@@ -0,0 +1,20 @@
|
||||
import Quota from '@/components/Quota';
|
||||
import { QuotaType } from '@/types/user';
|
||||
|
||||
interface UsageStatsProps {
|
||||
quotas: QuotaType[];
|
||||
}
|
||||
|
||||
const UsageStats: React.FC<UsageStatsProps> = ({ quotas }) => (
|
||||
<div className='rounded-lg'>
|
||||
<div className='p-0'>
|
||||
{quotas && quotas.length > 0 ? (
|
||||
<Quota quotas={quotas} showProgress className='space-y-4' labelClassName='pl-4 pr-2' />
|
||||
) : (
|
||||
<div className='h-10 animate-pulse'></div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default UsageStats;
|
||||
@@ -0,0 +1,42 @@
|
||||
import { PiUserCircle } from 'react-icons/pi';
|
||||
import { PlanDetails } from '../utils/plan';
|
||||
import UserAvatar from '@/components/UserAvatar';
|
||||
|
||||
interface UserInfoProps {
|
||||
avatarUrl?: string;
|
||||
userFullName: string;
|
||||
userEmail: string;
|
||||
planDetails: PlanDetails;
|
||||
}
|
||||
|
||||
const UserInfo: React.FC<UserInfoProps> = ({ avatarUrl, userFullName, userEmail, planDetails }) => (
|
||||
<div className='flex flex-col items-center gap-x-6 gap-y-4 md:flex-row md:items-start'>
|
||||
<div className='flex-shrink-0'>
|
||||
{avatarUrl ? (
|
||||
<UserAvatar
|
||||
url={avatarUrl}
|
||||
size={128}
|
||||
DefaultIcon={PiUserCircle}
|
||||
className='h-16 w-16 md:h-24 md:w-24'
|
||||
borderClassName='border-base-100 border-4'
|
||||
/>
|
||||
) : (
|
||||
<PiUserCircle className='h-16 w-16 md:h-24 md:w-24' />
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className='flex-grow text-center md:text-left'>
|
||||
<h2 className='text-base-content text-xl font-bold md:text-2xl'>{userFullName}</h2>
|
||||
<p className='text-base-content/60'>{userEmail}</p>
|
||||
<div className='mt-3'>
|
||||
<span
|
||||
className={`inline-block rounded-full px-3 py-1 text-sm font-medium ${planDetails.color}`}
|
||||
>
|
||||
{planDetails.name}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default UserInfo;
|
||||
@@ -1,36 +1,54 @@
|
||||
'use client';
|
||||
|
||||
import clsx from 'clsx';
|
||||
import React, { useState, useRef } from 'react';
|
||||
import Stripe from 'stripe';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { IoArrowBack } from 'react-icons/io5';
|
||||
import { PiUserCircle } from 'react-icons/pi';
|
||||
import { useEnv } from '@/context/EnvContext';
|
||||
import { useAuth } from '@/context/AuthContext';
|
||||
import { useTheme } from '@/hooks/useTheme';
|
||||
import { useQuotaStats } from '@/hooks/useQuotaStats';
|
||||
import { useTranslation } from '@/hooks/useTranslation';
|
||||
import { useSettingsStore } from '@/store/settingsStore';
|
||||
import { useTrafficLightStore } from '@/store/trafficLightStore';
|
||||
import { UserPlan } from '@/types/user';
|
||||
import { navigateToLibrary } from '@/utils/nav';
|
||||
import { deleteUser } from '@/libs/user';
|
||||
import { eventDispatcher } from '@/utils/event';
|
||||
import { getStripe } from '@/libs/stripe/client';
|
||||
import { getAPIBaseUrl } from '@/services/environment';
|
||||
import { getAccessToken } from '@/utils/access';
|
||||
import { getPlanDetails } from './utils/plan';
|
||||
import { Toast } from '@/components/Toast';
|
||||
import WindowButtons from '@/components/WindowButtons';
|
||||
import Quota from '@/components/Quota';
|
||||
import UserAvatar from '@/components/UserAvatar';
|
||||
import ProfileHeader from './components/Header';
|
||||
import UserInfo from './components/UserInfo';
|
||||
import UsageStats from './components/UsageStats';
|
||||
import PlansComparison from './components/PlansComparison';
|
||||
import AccountActions from './components/AccountActions';
|
||||
|
||||
const WEB_STRIPE_PLANS_URL = `${getAPIBaseUrl()}/stripe/plans`;
|
||||
const WEB_STRIPE_CHECKOUT_URL = `${getAPIBaseUrl()}/stripe/checkout`;
|
||||
const WEB_STRIPE_PORTAL_URL = `${getAPIBaseUrl()}/stripe/portal`;
|
||||
|
||||
export type AvailablePlan = {
|
||||
plan: UserPlan;
|
||||
price_id: string;
|
||||
price: number;
|
||||
currency: string;
|
||||
interval: string;
|
||||
product: Stripe.Product;
|
||||
};
|
||||
|
||||
const ProfilePage = () => {
|
||||
const _ = useTranslation();
|
||||
const router = useRouter();
|
||||
const { envConfig, appService } = useEnv();
|
||||
const { token, user, logout } = useAuth();
|
||||
const { isTrafficLightVisible } = useTrafficLightStore();
|
||||
const { settings, setSettings, saveSettings } = useSettingsStore();
|
||||
const [showConfirmDelete, setShowConfirmDelete] = useState(false);
|
||||
|
||||
const headerRef = useRef<HTMLDivElement>(null);
|
||||
const [availablePlans, setAvailablePlans] = useState<AvailablePlan[]>([]);
|
||||
|
||||
const [mounted, setMounted] = useState(false);
|
||||
useEffect(() => setMounted(true), []);
|
||||
|
||||
useTheme({ systemUIVisible: false });
|
||||
|
||||
@@ -48,14 +66,6 @@ const ProfilePage = () => {
|
||||
navigateToLibrary(router);
|
||||
};
|
||||
|
||||
const handleDeleteRequest = () => {
|
||||
setShowConfirmDelete(true);
|
||||
};
|
||||
|
||||
const handleCancelDelete = () => {
|
||||
setShowConfirmDelete(false);
|
||||
};
|
||||
|
||||
const handleConfirmDelete = async () => {
|
||||
try {
|
||||
await deleteUser();
|
||||
@@ -67,55 +77,69 @@ const ProfilePage = () => {
|
||||
message: _('Failed to delete user. Please try again later.'),
|
||||
});
|
||||
}
|
||||
setShowConfirmDelete(false);
|
||||
};
|
||||
|
||||
const getPlanDetails = (userPlan: UserPlan) => {
|
||||
switch (userPlan) {
|
||||
case 'free':
|
||||
return {
|
||||
name: _('Free Tier'),
|
||||
color: 'bg-gray-200 text-gray-800',
|
||||
features: [
|
||||
_('Community Support'),
|
||||
_('DeepL Free Access'),
|
||||
_('Essential Text-to-Speech Voices'),
|
||||
_('Unlimited Offline/Online Reading'),
|
||||
_('Unlimited Cloud Sync Devices'),
|
||||
_('500 MB Cloud Sync Space'),
|
||||
],
|
||||
};
|
||||
case 'plus':
|
||||
return {
|
||||
name: _('Plus Tier'),
|
||||
color: 'bg-blue-200 text-blue-800',
|
||||
features: [
|
||||
_('Includes All Free Tier Benefits'),
|
||||
_('Priority Support'),
|
||||
_('AI Summaries'),
|
||||
_('AI Translations'),
|
||||
_('DeepL Pro Access'),
|
||||
_('Expanded Text-to-Speech Voices'),
|
||||
_('2000 MB Cloud Sync Space'),
|
||||
],
|
||||
};
|
||||
case 'pro':
|
||||
return {
|
||||
name: _('Pro Tier'),
|
||||
color: 'bg-purple-200 text-purple-800',
|
||||
features: [
|
||||
_('Includes All Plus Tier Benefits'),
|
||||
_('Unlimited AI Summaries'),
|
||||
_('Unlimited AI Translations'),
|
||||
_('Unlimited DeepL Pro Access'),
|
||||
_('Advanced AI Tools'),
|
||||
_('Early Feature Access'),
|
||||
_('10 GB Cloud Sync Space'),
|
||||
],
|
||||
};
|
||||
const handleSubscribe = async (priceId?: string) => {
|
||||
const token = await getAccessToken();
|
||||
const stripe = await getStripe();
|
||||
if (!stripe) {
|
||||
console.error('Stripe not loaded');
|
||||
return;
|
||||
}
|
||||
const { sessionId, url } = await fetch(WEB_STRIPE_CHECKOUT_URL, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
body: JSON.stringify({ priceId }),
|
||||
}).then((res) => res.json());
|
||||
|
||||
if (url) {
|
||||
window.location.href = url;
|
||||
} else {
|
||||
const result = await stripe.redirectToCheckout({ sessionId });
|
||||
|
||||
if (result.error) {
|
||||
console.error(result.error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleManageSubscription = async () => {
|
||||
const token = await getAccessToken();
|
||||
const response = await fetch(WEB_STRIPE_PORTAL_URL, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
});
|
||||
|
||||
const { url, error } = await response.json();
|
||||
|
||||
if (error) {
|
||||
console.error('Error creating portal session:', error);
|
||||
eventDispatcher.dispatch('toast', {
|
||||
type: 'error',
|
||||
message: _('Failed to manage subscription. Please try again later.'),
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
window.location.href = url;
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetch(WEB_STRIPE_PLANS_URL)
|
||||
.then((res) => res.json())
|
||||
.then((data) => setAvailablePlans(data));
|
||||
}, []);
|
||||
|
||||
if (!mounted) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!user || !token) {
|
||||
return (
|
||||
<div className='mx-auto max-w-4xl px-4 py-8'>
|
||||
@@ -131,7 +155,8 @@ const ProfilePage = () => {
|
||||
const avatarUrl = user?.user_metadata?.['picture'] || user?.user_metadata?.['avatar_url'];
|
||||
const userFullName = user?.user_metadata?.['full_name'] || '-';
|
||||
const userEmail = user?.email || '';
|
||||
const planDetails = getPlanDetails(userPlan) || getPlanDetails('free');
|
||||
const planDetails =
|
||||
getPlanDetails(userPlan, availablePlans) || getPlanDetails('free', availablePlans);
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -141,140 +166,33 @@ const ProfilePage = () => {
|
||||
appService?.hasSafeAreaInset && 'pt-[env(safe-area-inset-top)]',
|
||||
)}
|
||||
>
|
||||
<div
|
||||
ref={headerRef}
|
||||
className={clsx(
|
||||
'fixed flex w-full items-center justify-between py-2 pe-6 ps-4',
|
||||
appService?.hasTrafficLight && 'pt-11',
|
||||
)}
|
||||
>
|
||||
<button onClick={handleGoBack} className={clsx('btn btn-ghost h-8 min-h-8 w-8 p-0')}>
|
||||
<IoArrowBack className='text-base-content' />
|
||||
</button>
|
||||
|
||||
{appService?.hasWindowBar && (
|
||||
<WindowButtons
|
||||
headerRef={headerRef}
|
||||
showMinimize={!isTrafficLightVisible}
|
||||
showMaximize={!isTrafficLightVisible}
|
||||
showClose={!isTrafficLightVisible}
|
||||
onClose={handleGoBack}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<ProfileHeader onGoBack={handleGoBack} />
|
||||
<div className='w-full min-w-60 max-w-4xl px-4 py-10'>
|
||||
<div className='bg-base-200 overflow-hidden rounded-lg p-2 shadow-md sm:p-6'>
|
||||
<div className='p-2 sm:p-6'>
|
||||
<div className='mb-8 flex flex-col items-center gap-x-6 gap-y-4 md:flex-row md:items-start'>
|
||||
<div className='flex-shrink-0'>
|
||||
{avatarUrl ? (
|
||||
<UserAvatar
|
||||
url={avatarUrl}
|
||||
size={128}
|
||||
DefaultIcon={PiUserCircle}
|
||||
className='h-16 w-16 md:h-24 md:w-24'
|
||||
borderClassName='border-base-100 border-4'
|
||||
/>
|
||||
) : (
|
||||
<PiUserCircle className='h-16 w-16 md:h-24 md:w-24' />
|
||||
)}
|
||||
</div>
|
||||
<div className='flex flex-col gap-y-8 p-2 sm:p-6'>
|
||||
<UserInfo
|
||||
avatarUrl={avatarUrl}
|
||||
userFullName={userFullName}
|
||||
userEmail={userEmail}
|
||||
planDetails={planDetails}
|
||||
/>
|
||||
|
||||
<div className='flex-grow text-center md:text-left'>
|
||||
<h2 className='text-base-content text-xl font-bold md:text-2xl'>{userFullName}</h2>
|
||||
<p className='text-base-content/60'>{userEmail}</p>
|
||||
<div className='mt-3'>
|
||||
<span
|
||||
className={`inline-block rounded-full px-3 py-1 text-sm font-medium ${planDetails.color}`}
|
||||
>
|
||||
{planDetails.name}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<UsageStats quotas={quotas} />
|
||||
|
||||
<div className='bg-base-100 mb-8 rounded-lg px-4 py-6'>
|
||||
<h3 className='text-base-content mb-2 text-lg font-semibold'>{_('Features')}</h3>
|
||||
<div className='mt-6'>
|
||||
<ul className='text-base-content/60 grid grid-cols-1 gap-2 md:grid-cols-2'>
|
||||
{planDetails.features.map((feature, index) => (
|
||||
<li key={index} className='flex items-center'>
|
||||
<svg
|
||||
className='mr-2 h-4 w-4 text-green-500'
|
||||
fill='currentColor'
|
||||
viewBox='0 0 20 20'
|
||||
>
|
||||
<path
|
||||
fillRule='evenodd'
|
||||
d='M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z'
|
||||
clipRule='evenodd'
|
||||
/>
|
||||
</svg>
|
||||
{feature}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<PlansComparison
|
||||
availablePlans={availablePlans}
|
||||
userPlan={userPlan}
|
||||
onSubscribe={handleSubscribe}
|
||||
/>
|
||||
|
||||
<div className='mb-8 rounded-lg'>
|
||||
<div className='p-0'>
|
||||
{quotas && quotas.length > 0 ? (
|
||||
<Quota
|
||||
quotas={quotas}
|
||||
showProgress
|
||||
className='space-y-4'
|
||||
labelClassName='pl-4 pr-2'
|
||||
/>
|
||||
) : (
|
||||
<div className='h-10 animate-pulse'></div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='flex flex-col gap-4 md:flex-row'>
|
||||
<button
|
||||
onClick={handleLogout}
|
||||
className='w-full rounded-lg bg-gray-200 px-6 py-3 font-medium text-gray-800 transition-colors hover:bg-gray-300 md:w-auto'
|
||||
>
|
||||
{_('Sign Out')}
|
||||
</button>
|
||||
<button
|
||||
onClick={handleDeleteRequest}
|
||||
className='w-full rounded-lg bg-red-100 px-6 py-3 font-medium text-red-600 transition-colors hover:bg-red-200 md:w-auto'
|
||||
>
|
||||
{_('Delete Account')}
|
||||
</button>
|
||||
</div>
|
||||
<AccountActions
|
||||
userPlan={userPlan}
|
||||
onLogout={handleLogout}
|
||||
onConfirmDelete={handleConfirmDelete}
|
||||
onManageSubscription={handleManageSubscription}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{showConfirmDelete && (
|
||||
<div className='fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50 p-4'>
|
||||
<div className='w-full max-w-md rounded-2xl bg-white p-6'>
|
||||
<h3 className='mb-4 text-xl font-bold text-gray-800'>{_('Delete Your Account?')}</h3>
|
||||
<p className='mb-6 text-gray-600'>
|
||||
{_(
|
||||
'This action cannot be undone. All your data in the cloud will be permanently deleted.',
|
||||
)}
|
||||
</p>
|
||||
<div className='flex flex-col gap-3 sm:flex-row'>
|
||||
<button
|
||||
onClick={handleCancelDelete}
|
||||
className='flex-1 rounded-lg bg-gray-300 px-4 py-2 font-medium text-gray-800 hover:bg-gray-400'
|
||||
>
|
||||
{_('Cancel')}
|
||||
</button>
|
||||
<button
|
||||
onClick={handleConfirmDelete}
|
||||
className='flex-1 rounded-lg bg-red-500 px-4 py-2 font-medium text-white hover:bg-red-600'
|
||||
>
|
||||
{_('Delete Permanently')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<Toast />
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,300 @@
|
||||
'use client';
|
||||
import { Suspense, useEffect, useState } from 'react';
|
||||
import { useSearchParams, useRouter } from 'next/navigation';
|
||||
import { useTranslation } from '@/hooks/useTranslation';
|
||||
import { getAPIBaseUrl } from '@/services/environment';
|
||||
import { getAccessToken } from '@/utils/access';
|
||||
import { supabase } from '@/utils/supabase';
|
||||
import Spinner from '@/components/Spinner';
|
||||
|
||||
const WEB_STRIPE_CHECK_URL = `${getAPIBaseUrl()}/stripe/check`;
|
||||
|
||||
interface SessionStatus {
|
||||
status: 'loading' | 'complete' | 'failed' | 'processing';
|
||||
customerEmail: string;
|
||||
subscriptionId?: string;
|
||||
planName?: string;
|
||||
amount?: number;
|
||||
currency?: string;
|
||||
}
|
||||
|
||||
const SuccessPageWithSearchParams = () => {
|
||||
const _ = useTranslation();
|
||||
const [sessionStatus, setSessionStatus] = useState<SessionStatus>({
|
||||
status: 'loading',
|
||||
customerEmail: '',
|
||||
});
|
||||
const [retryCount, setRetryCount] = useState(0);
|
||||
const searchParams = useSearchParams();
|
||||
const router = useRouter();
|
||||
const sessionId = searchParams?.get('session_id');
|
||||
|
||||
async function fetchSessionStatus() {
|
||||
try {
|
||||
const token = await getAccessToken();
|
||||
const response = await fetch(WEB_STRIPE_CHECK_URL, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
body: JSON.stringify({ sessionId }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
const { session, error } = await response.json();
|
||||
|
||||
if (error) {
|
||||
setSessionStatus((prev) => ({ ...prev, status: 'failed' }));
|
||||
console.error('Session check error:', error);
|
||||
return;
|
||||
}
|
||||
|
||||
setSessionStatus({
|
||||
status:
|
||||
session.payment_status === 'paid' ? 'complete' : session.payment_status || 'processing',
|
||||
customerEmail: session.customer_email || session.customer_details?.email || '',
|
||||
subscriptionId: session.subscription,
|
||||
planName:
|
||||
session.display_items?.[0]?.custom?.name || session.line_items?.data?.[0]?.description,
|
||||
amount: session.amount_total,
|
||||
currency: session.currency,
|
||||
});
|
||||
|
||||
try {
|
||||
await supabase.auth.refreshSession();
|
||||
} catch {}
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch session status:', error);
|
||||
setSessionStatus((prev) => ({ ...prev, status: 'failed' }));
|
||||
}
|
||||
}
|
||||
|
||||
const handleRetry = () => {
|
||||
setRetryCount(0);
|
||||
setSessionStatus((prev) => ({ ...prev, status: 'loading' }));
|
||||
fetchSessionStatus();
|
||||
};
|
||||
|
||||
const handleGoToLibrary = () => {
|
||||
router.push('/library');
|
||||
};
|
||||
|
||||
const handleGoToProfile = () => {
|
||||
router.push('/user');
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!sessionId) {
|
||||
handleGoToProfile();
|
||||
return;
|
||||
}
|
||||
|
||||
fetchSessionStatus();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [sessionId, router]);
|
||||
|
||||
useEffect(() => {
|
||||
if (sessionStatus.status === 'processing' && retryCount < 3) {
|
||||
const timer = setTimeout(() => {
|
||||
setRetryCount((prev) => prev + 1);
|
||||
fetchSessionStatus();
|
||||
}, 2000);
|
||||
|
||||
return () => clearTimeout(timer);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [sessionStatus.status, retryCount]);
|
||||
|
||||
// Loading state
|
||||
if (sessionStatus.status === 'loading') {
|
||||
return (
|
||||
<div className='flex min-h-screen items-center justify-center bg-gray-50'>
|
||||
<div className='text-center'>
|
||||
<div className='mx-auto mb-4 h-12 w-12 animate-spin rounded-full border-b-2 border-blue-600'></div>
|
||||
<h2 className='mb-2 text-xl font-semibold text-gray-800'>
|
||||
{_('Processing your payment...')}
|
||||
</h2>
|
||||
<p className='text-gray-600'>{_('Please wait while we confirm your subscription.')}</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Processing state (payment still being processed)
|
||||
if (sessionStatus.status === 'processing') {
|
||||
return (
|
||||
<div className='flex min-h-screen items-center justify-center bg-gray-50'>
|
||||
<div className='max-w-md text-center'>
|
||||
<div className='mx-auto mb-4 flex h-12 w-12 animate-pulse items-center justify-center rounded-full bg-yellow-400'>
|
||||
<svg
|
||||
className='h-6 w-6 text-white'
|
||||
fill='none'
|
||||
stroke='currentColor'
|
||||
viewBox='0 0 24 24'
|
||||
>
|
||||
<path
|
||||
strokeLinecap='round'
|
||||
strokeLinejoin='round'
|
||||
strokeWidth={2}
|
||||
d='M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z'
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<h2 className='mb-2 text-xl font-semibold text-gray-800'>{_('Payment Processing')}</h2>
|
||||
<p className='mb-4 text-gray-600'>
|
||||
{_('Your payment is being processed. This usually takes a few moments.')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Failed state
|
||||
if (sessionStatus.status === 'failed') {
|
||||
return (
|
||||
<div className='flex min-h-screen items-center justify-center bg-gray-50'>
|
||||
<div className='max-w-md text-center'>
|
||||
<div className='mx-auto mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-red-100'>
|
||||
<svg
|
||||
className='h-6 w-6 text-red-600'
|
||||
fill='none'
|
||||
stroke='currentColor'
|
||||
viewBox='0 0 24 24'
|
||||
>
|
||||
<path
|
||||
strokeLinecap='round'
|
||||
strokeLinejoin='round'
|
||||
strokeWidth={2}
|
||||
d='M6 18L18 6M6 6l12 12'
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<h2 className='mb-2 text-xl font-semibold text-gray-800'>{_('Payment Failed')}</h2>
|
||||
<p className='mb-6 text-gray-600'>
|
||||
{_(
|
||||
"We couldn't process your subscription. Please try again or contact support if the issue persists.",
|
||||
)}
|
||||
</p>
|
||||
<div className='space-y-3'>
|
||||
<button
|
||||
onClick={handleRetry}
|
||||
className='w-full rounded-lg bg-blue-600 px-4 py-2 font-medium text-white transition-colors duration-200 hover:bg-blue-700'
|
||||
>
|
||||
{_('Try Again')}
|
||||
</button>
|
||||
<button
|
||||
onClick={handleGoToProfile}
|
||||
className='w-full rounded-lg bg-gray-200 px-4 py-2 font-medium text-gray-800 transition-colors duration-200 hover:bg-gray-300'
|
||||
>
|
||||
{_('Back to Profile')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Success state
|
||||
return (
|
||||
<div className='flex min-h-screen items-center justify-center bg-gray-50'>
|
||||
<div className='mx-auto max-w-2xl px-4 text-center'>
|
||||
{/* Success Icon */}
|
||||
<div className='mx-auto mb-6 flex h-16 w-16 items-center justify-center rounded-full bg-green-100'>
|
||||
<svg
|
||||
className='h-8 w-8 text-green-600'
|
||||
fill='none'
|
||||
stroke='currentColor'
|
||||
viewBox='0 0 24 24'
|
||||
>
|
||||
<path strokeLinecap='round' strokeLinejoin='round' strokeWidth={2} d='M5 13l4 4L19 7' />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
{/* Success Message */}
|
||||
<h1 className='mb-4 text-3xl font-bold text-gray-800'>
|
||||
🎉 {_('Subscription Successful!')}
|
||||
</h1>
|
||||
|
||||
<div className='mb-6 rounded-lg bg-white p-6 shadow-md'>
|
||||
<p className='mb-4 text-lg text-gray-700'>
|
||||
{_('Thank you for your subscription! Your payment has been processed successfully.')}
|
||||
</p>
|
||||
|
||||
{/* Subscription Details */}
|
||||
<div className='space-y-2 text-left text-sm text-gray-600'>
|
||||
{sessionStatus.customerEmail && (
|
||||
<div className='flex justify-between'>
|
||||
<span className='font-medium'>{_('Email:')}</span>
|
||||
<span>{sessionStatus.customerEmail}</span>
|
||||
</div>
|
||||
)}
|
||||
{sessionStatus.planName && (
|
||||
<div className='flex justify-between'>
|
||||
<span className='font-medium'>{_('Plan:')}</span>
|
||||
<span>{sessionStatus.planName}</span>
|
||||
</div>
|
||||
)}
|
||||
{sessionStatus.amount && sessionStatus.currency && (
|
||||
<div className='flex justify-between'>
|
||||
<span className='font-medium'>{_('Amount:')}</span>
|
||||
<span>
|
||||
{new Intl.NumberFormat('en-US', {
|
||||
style: 'currency',
|
||||
currency: sessionStatus.currency.toUpperCase(),
|
||||
}).format(sessionStatus.amount / 100)}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
{sessionStatus.subscriptionId && (
|
||||
<div className='flex justify-between'>
|
||||
<span className='font-medium'>{_('Subscription ID:')}</span>
|
||||
<span className='font-mono text-xs'>{sessionStatus.subscriptionId}</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Action Buttons */}
|
||||
<div className='space-y-3 sm:flex sm:justify-center sm:space-x-4 sm:space-y-0'>
|
||||
<button
|
||||
onClick={handleGoToLibrary}
|
||||
className='w-full rounded-lg bg-blue-600 px-6 py-3 font-medium text-white transition-colors duration-200 hover:bg-blue-700 sm:w-auto'
|
||||
>
|
||||
{_('Go to Library')}
|
||||
</button>
|
||||
<button
|
||||
onClick={handleGoToProfile}
|
||||
className='w-full rounded-lg bg-gray-200 px-6 py-3 font-medium text-gray-800 transition-colors duration-200 hover:bg-gray-300 sm:w-auto'
|
||||
>
|
||||
{_('Back to Profile')}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Additional Info */}
|
||||
<div className='mt-8 text-xs text-gray-500'>
|
||||
<p>{_('Need help? Contact our support team at support@readest.com')}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default function SuccessPage() {
|
||||
return (
|
||||
<Suspense
|
||||
fallback={
|
||||
<div className='fixed inset-0 z-50 flex items-center justify-center'>
|
||||
<Spinner loading />
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<SuccessPageWithSearchParams />
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
import { UserPlan } from '@/types/user';
|
||||
import { stubTranslation as _ } from '@/utils/misc';
|
||||
import { AvailablePlan } from '../page';
|
||||
|
||||
export type PlanDetails = {
|
||||
name: string;
|
||||
plan: UserPlan;
|
||||
color: string;
|
||||
price: number;
|
||||
price_id?: string;
|
||||
interval: string;
|
||||
features: string[];
|
||||
limits: Record<string, string | number>;
|
||||
};
|
||||
|
||||
export const getPlanDetails = (
|
||||
userPlan: UserPlan,
|
||||
availablePlans: AvailablePlan[],
|
||||
): PlanDetails => {
|
||||
const availablePlan = availablePlans.find((plan) => plan.plan === userPlan);
|
||||
switch (userPlan) {
|
||||
case 'free':
|
||||
return {
|
||||
name: _('Free Plan'),
|
||||
plan: userPlan,
|
||||
color: 'bg-gray-200 text-gray-800',
|
||||
price: 0,
|
||||
price_id: availablePlan?.price_id,
|
||||
interval: _('month'),
|
||||
features: [
|
||||
_('Community Support'),
|
||||
_('Unlimited Text-to-Speech Hours'),
|
||||
_('Unlimited Cloud Sync Devices'),
|
||||
_('DeepL Free Access (10K characters/day)'),
|
||||
_('500 MB Cloud Sync Space'),
|
||||
],
|
||||
limits: {
|
||||
[_('AI Translations (per day)')]: '10K',
|
||||
[_('Cloud Storage')]: '500 MB',
|
||||
},
|
||||
};
|
||||
case 'plus':
|
||||
return {
|
||||
name: _('Plus Plan'),
|
||||
plan: userPlan,
|
||||
color: 'bg-blue-200 text-blue-800',
|
||||
price: availablePlan?.price || 499,
|
||||
price_id: availablePlan?.price_id,
|
||||
interval: _('month'),
|
||||
features: [
|
||||
_('Includes All Free Plan Benefits'),
|
||||
_('Priority Support'),
|
||||
_('Basic AI Translations'),
|
||||
_('DeepL Pro Access (50K characters/day)'),
|
||||
_('2 GB Cloud Sync Space'),
|
||||
],
|
||||
limits: {
|
||||
[_('AI Translations (per day)')]: '50K',
|
||||
[_('Cloud Storage')]: '2 GB',
|
||||
},
|
||||
};
|
||||
case 'pro':
|
||||
return {
|
||||
name: _('Pro Plan'),
|
||||
plan: userPlan,
|
||||
color: 'bg-purple-200 text-purple-800',
|
||||
price: availablePlan?.price || 999,
|
||||
price_id: availablePlan?.price_id,
|
||||
interval: _('month'),
|
||||
features: [
|
||||
_('Includes All Plus Plan Benefits'),
|
||||
_('Early Feature Access'),
|
||||
_('More AI Translations'),
|
||||
_('Advanced AI Tools'),
|
||||
_('DeepL Pro Access (200K characters/day)'),
|
||||
_('10 GB Cloud Sync Space'),
|
||||
],
|
||||
limits: {
|
||||
[_('AI Translations (per day)')]: '200K',
|
||||
[_('Cloud Storage')]: '10 GB',
|
||||
},
|
||||
};
|
||||
default:
|
||||
return getPlanDetails('free', availablePlans);
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user