feat(messages): update developer-related messages in multiple languages
This commit is contained in:
+28
-1
@@ -49,7 +49,8 @@
|
||||
"login": "تسجيل الدخول",
|
||||
"register": "إنشاء حساب",
|
||||
"logout": "تسجيل الخروج",
|
||||
"ide": "Prompt Builder"
|
||||
"ide": "Typed-Prompts IDE",
|
||||
"developers": "المطورون"
|
||||
},
|
||||
"brand": {
|
||||
"copyLogoSvg": "نسخ شعار SVG",
|
||||
@@ -1261,6 +1262,32 @@
|
||||
"exampleGenerated": "تم إنشاء مثال جديد!",
|
||||
"ignoreTypeErrors": "تجاهل أخطاء النوع"
|
||||
},
|
||||
"developers": {
|
||||
"title": "المطورون",
|
||||
"promptBuilder": "Typed-Prompts IDE",
|
||||
"promptEnhancer": "محسّن الأوامر",
|
||||
"desktopOnly": "للحاسوب فقط",
|
||||
"desktopOnlyDescription": "أدوات المطورين تتطلب شاشة أكبر. يرجى فتح هذه الصفحة على حاسوب مكتبي أو محمول.",
|
||||
"browsePrompts": "تصفح الأوامر",
|
||||
"inputPrompt": "أمر الإدخال",
|
||||
"inputPlaceholder": "أدخل أمراً أساسياً لتحسينه...\n\nمثال: اكتب مقالة مدونة عن الذكاء الاصطناعي",
|
||||
"outputType": "النوع",
|
||||
"outputFormat": "التنسيق",
|
||||
"enhance": "تحسين",
|
||||
"enhancing": "جاري التحسين...",
|
||||
"enhanceSuccess": "تم تحسين الأمر بنجاح!",
|
||||
"enhanceFailed": "فشل في تحسين الأمر",
|
||||
"enterPrompt": "يرجى إدخال أمر للتحسين",
|
||||
"enhancedPrompt": "الأمر المحسّن",
|
||||
"copy": "نسخ",
|
||||
"copied": "تم النسخ إلى الحافظة",
|
||||
"inspiredBy": "مستوحى من",
|
||||
"enhanceToSeeResult": "أدخل أمراً وانقر تحسين لرؤية النتيجة",
|
||||
"loginRequired": "يرجى تسجيل الدخول لاستخدام محسّن الأوامر",
|
||||
"history": "السجل",
|
||||
"storedOnDevice": "مخزن على جهازك",
|
||||
"noHistory": "لا يوجد سجل بعد"
|
||||
},
|
||||
"appBanner": {
|
||||
"message": "احصل على تطبيق prompts.chat لأجهزة iPhone وiPad وMac",
|
||||
"messageShort": "احصل على التطبيق لأجهزة Apple",
|
||||
|
||||
+28
-1
@@ -49,7 +49,8 @@
|
||||
"login": "Daxil ol",
|
||||
"register": "Qeydiyyat",
|
||||
"logout": "Çıxış",
|
||||
"ide": "Prompt Qurucusu"
|
||||
"ide": "Typed-Prompts IDE",
|
||||
"developers": "Tərtibatçılar"
|
||||
},
|
||||
"brand": {
|
||||
"copyLogoSvg": "Logo SVG-ni Kopyala",
|
||||
@@ -1261,6 +1262,32 @@
|
||||
"exampleGenerated": "Yeni nümunə yaradıldı!",
|
||||
"ignoreTypeErrors": "Tip Xətalarını İgnor et"
|
||||
},
|
||||
"developers": {
|
||||
"title": "Tərtibatçılar",
|
||||
"promptBuilder": "Typed-Prompts IDE",
|
||||
"promptEnhancer": "Prompt Təkmilləşdirici",
|
||||
"desktopOnly": "Yalnız Masaüstü",
|
||||
"desktopOnlyDescription": "Tərtibatçı alətləri daha böyük ekran tələb edir. Bu səhifəni masaüstü və ya noutbukda açın.",
|
||||
"browsePrompts": "Promptlara Bax",
|
||||
"inputPrompt": "Giriş Promptu",
|
||||
"inputPlaceholder": "Təkmilləşdirmək üçün əsas prompt daxil edin...\n\nNümunə: süni intellekt haqqında bloq yazısı yaz",
|
||||
"outputType": "Tip",
|
||||
"outputFormat": "Format",
|
||||
"enhance": "Təkmilləşdir",
|
||||
"enhancing": "Təkmilləşdirilir...",
|
||||
"enhanceSuccess": "Prompt uğurla təkmilləşdirildi!",
|
||||
"enhanceFailed": "Prompt təkmilləşdirilə bilmədi",
|
||||
"enterPrompt": "Təkmilləşdirmək üçün prompt daxil edin",
|
||||
"enhancedPrompt": "Təkmilləşdirilmiş Prompt",
|
||||
"copy": "Kopyala",
|
||||
"copied": "Buferə kopyalandı",
|
||||
"inspiredBy": "İlham mənbəyi",
|
||||
"enhanceToSeeResult": "Nəticəni görmək üçün prompt daxil edin və Təkmilləşdir düyməsinə basın",
|
||||
"loginRequired": "Prompt Təkmilləşdirici istifadə etmək üçün daxil olun",
|
||||
"history": "Tarixçə",
|
||||
"storedOnDevice": "Cihazınızda saxlanılır",
|
||||
"noHistory": "Hələ tarixçə yoxdur"
|
||||
},
|
||||
"appBanner": {
|
||||
"message": "iPhone, iPad və Mac üçün prompts.chat tətbiqini yükləyin",
|
||||
"messageShort": "Apple cihazları üçün tətbiqi yükləyin",
|
||||
|
||||
+28
-1
@@ -49,7 +49,8 @@
|
||||
"login": "Anmelden",
|
||||
"register": "Registrieren",
|
||||
"logout": "Abmelden",
|
||||
"ide": "Prompt Builder"
|
||||
"ide": "Typed-Prompts IDE",
|
||||
"developers": "Entwickler"
|
||||
},
|
||||
"brand": {
|
||||
"copyLogoSvg": "Logo SVG kopieren",
|
||||
@@ -1261,6 +1262,32 @@
|
||||
"exampleGenerated": "Neues Beispiel generiert!",
|
||||
"ignoreTypeErrors": "Typfehler ignorieren"
|
||||
},
|
||||
"developers": {
|
||||
"title": "Entwickler",
|
||||
"promptBuilder": "Typed-Prompts IDE",
|
||||
"promptEnhancer": "Prompt-Verbesserer",
|
||||
"desktopOnly": "Nur Desktop",
|
||||
"desktopOnlyDescription": "Entwicklertools erfordern einen größeren Bildschirm. Bitte öffnen Sie diese Seite auf einem Desktop- oder Laptop-Computer.",
|
||||
"browsePrompts": "Prompts durchsuchen",
|
||||
"inputPrompt": "Eingabe-Prompt",
|
||||
"inputPlaceholder": "Geben Sie einen einfachen Prompt zum Verbessern ein...\n\nBeispiel: Schreibe einen Blogbeitrag über KI",
|
||||
"outputType": "Typ",
|
||||
"outputFormat": "Format",
|
||||
"enhance": "Verbessern",
|
||||
"enhancing": "Wird verbessert...",
|
||||
"enhanceSuccess": "Prompt erfolgreich verbessert!",
|
||||
"enhanceFailed": "Prompt konnte nicht verbessert werden",
|
||||
"enterPrompt": "Bitte geben Sie einen Prompt zum Verbessern ein",
|
||||
"enhancedPrompt": "Verbesserter Prompt",
|
||||
"copy": "Kopieren",
|
||||
"copied": "In Zwischenablage kopiert",
|
||||
"inspiredBy": "Inspiriert von",
|
||||
"enhanceToSeeResult": "Geben Sie einen Prompt ein und klicken Sie auf Verbessern",
|
||||
"loginRequired": "Bitte melden Sie sich an, um den Prompt-Verbesserer zu nutzen",
|
||||
"history": "Verlauf",
|
||||
"storedOnDevice": "Auf Ihrem Gerät gespeichert",
|
||||
"noHistory": "Noch kein Verlauf"
|
||||
},
|
||||
"appBanner": {
|
||||
"message": "Hol dir die prompts.chat App für iPhone, iPad und Mac",
|
||||
"messageShort": "Hol dir die App für Apple-Geräte",
|
||||
|
||||
+28
-1
@@ -49,7 +49,8 @@
|
||||
"login": "Σύνδεση",
|
||||
"register": "Εγγραφή",
|
||||
"logout": "Αποσύνδεση",
|
||||
"ide": "Prompt Builder"
|
||||
"ide": "Typed-Prompts IDE",
|
||||
"developers": "Προγραμματιστές"
|
||||
},
|
||||
"brand": {
|
||||
"copyLogoSvg": "Αντιγραφή Logo SVG",
|
||||
@@ -1261,6 +1262,32 @@
|
||||
"exampleGenerated": "Δημιουργήθηκε νέο παράδειγμα!",
|
||||
"ignoreTypeErrors": "Αγνόηση Σφαλμάτων Τύπου"
|
||||
},
|
||||
"developers": {
|
||||
"title": "Προγραμματιστές",
|
||||
"promptBuilder": "Typed-Prompts IDE",
|
||||
"promptEnhancer": "Βελτιωτής Προτροπών",
|
||||
"desktopOnly": "Μόνο για Υπολογιστές",
|
||||
"desktopOnlyDescription": "Τα εργαλεία προγραμματιστή απαιτούν μεγαλύτερη οθόνη. Ανοίξτε αυτή τη σελίδα σε επιτραπέζιο ή φορητό υπολογιστή.",
|
||||
"browsePrompts": "Περιήγηση Προτροπών",
|
||||
"inputPrompt": "Προτροπή Εισόδου",
|
||||
"inputPlaceholder": "Εισάγετε μια βασική προτροπή για βελτίωση...\n\nΠαράδειγμα: γράψε ένα άρθρο για την AI",
|
||||
"outputType": "Τύπος",
|
||||
"outputFormat": "Μορφή",
|
||||
"enhance": "Βελτίωση",
|
||||
"enhancing": "Βελτίωση...",
|
||||
"enhanceSuccess": "Η προτροπή βελτιώθηκε επιτυχώς!",
|
||||
"enhanceFailed": "Αποτυχία βελτίωσης προτροπής",
|
||||
"enterPrompt": "Εισάγετε μια προτροπή για βελτίωση",
|
||||
"enhancedPrompt": "Βελτιωμένη Προτροπή",
|
||||
"copy": "Αντιγραφή",
|
||||
"copied": "Αντιγράφηκε στο πρόχειρο",
|
||||
"inspiredBy": "Εμπνευσμένο από",
|
||||
"enhanceToSeeResult": "Εισάγετε μια προτροπή και πατήστε Βελτίωση για να δείτε το αποτέλεσμα",
|
||||
"loginRequired": "Συνδεθείτε για να χρησιμοποιήσετε τον Βελτιωτή Προτροπών",
|
||||
"history": "Ιστορικό",
|
||||
"storedOnDevice": "Αποθηκευμένο στη συσκευή σας",
|
||||
"noHistory": "Δεν υπάρχει ιστορικό ακόμα"
|
||||
},
|
||||
"appBanner": {
|
||||
"message": "Κατεβάστε την εφαρμογή prompts.chat για iPhone, iPad και Mac",
|
||||
"messageShort": "Κατεβάστε την εφαρμογή για συσκευές Apple",
|
||||
|
||||
+28
-1
@@ -49,7 +49,8 @@
|
||||
"login": "Login",
|
||||
"register": "Register",
|
||||
"logout": "Logout",
|
||||
"ide": "Prompt Builder"
|
||||
"ide": "Typed-Prompts IDE",
|
||||
"developers": "Developers"
|
||||
},
|
||||
"brand": {
|
||||
"copyLogoSvg": "Copy Logo SVG",
|
||||
@@ -1261,6 +1262,32 @@
|
||||
"exampleGenerated": "New example generated!",
|
||||
"ignoreTypeErrors": "Ignore Type Errors"
|
||||
},
|
||||
"developers": {
|
||||
"title": "Developers",
|
||||
"promptBuilder": "Typed-Prompts IDE",
|
||||
"promptEnhancer": "Prompt Enhancer",
|
||||
"desktopOnly": "Desktop Only",
|
||||
"desktopOnlyDescription": "Developer tools require a larger screen. Please open this page on a desktop or laptop computer.",
|
||||
"browsePrompts": "Browse Prompts",
|
||||
"inputPrompt": "Input Prompt",
|
||||
"inputPlaceholder": "Enter a basic prompt to enhance...\n\nExample: write a blog post about AI",
|
||||
"outputType": "Type",
|
||||
"outputFormat": "Format",
|
||||
"enhance": "Enhance",
|
||||
"enhancing": "Enhancing...",
|
||||
"enhanceSuccess": "Prompt enhanced successfully!",
|
||||
"enhanceFailed": "Failed to enhance prompt",
|
||||
"enterPrompt": "Please enter a prompt to enhance",
|
||||
"enhancedPrompt": "Enhanced Prompt",
|
||||
"copy": "Copy",
|
||||
"copied": "Copied to clipboard",
|
||||
"inspiredBy": "Inspired by",
|
||||
"enhanceToSeeResult": "Enter a prompt and click Enhance to see the result",
|
||||
"loginRequired": "Please log in to use the Prompt Enhancer",
|
||||
"history": "History",
|
||||
"storedOnDevice": "Stored on your device",
|
||||
"noHistory": "No history yet"
|
||||
},
|
||||
"appBanner": {
|
||||
"message": "Get the prompts.chat app for iPhone, iPad, and Mac",
|
||||
"messageShort": "Get the app for Apple devices",
|
||||
|
||||
+28
-1
@@ -49,7 +49,8 @@
|
||||
"login": "Iniciar sesión",
|
||||
"register": "Registrarse",
|
||||
"logout": "Cerrar sesión",
|
||||
"ide": "Prompt Builder"
|
||||
"ide": "Typed-Prompts IDE",
|
||||
"developers": "Desarrolladores"
|
||||
},
|
||||
"brand": {
|
||||
"copyLogoSvg": "Copiar Logo SVG",
|
||||
@@ -1261,6 +1262,32 @@
|
||||
"exampleGenerated": "¡Nuevo ejemplo generado!",
|
||||
"ignoreTypeErrors": "Ignorar Errores de Tipo"
|
||||
},
|
||||
"developers": {
|
||||
"title": "Desarrolladores",
|
||||
"promptBuilder": "Typed-Prompts IDE",
|
||||
"promptEnhancer": "Mejorador de Prompts",
|
||||
"desktopOnly": "Solo Escritorio",
|
||||
"desktopOnlyDescription": "Las herramientas de desarrollo requieren una pantalla más grande. Por favor, abre esta página en un ordenador de escritorio o portátil.",
|
||||
"browsePrompts": "Explorar Prompts",
|
||||
"inputPrompt": "Prompt de Entrada",
|
||||
"inputPlaceholder": "Ingresa un prompt básico para mejorar...\n\nEjemplo: escribe una publicación de blog sobre IA",
|
||||
"outputType": "Tipo",
|
||||
"outputFormat": "Formato",
|
||||
"enhance": "Mejorar",
|
||||
"enhancing": "Mejorando...",
|
||||
"enhanceSuccess": "¡Prompt mejorado exitosamente!",
|
||||
"enhanceFailed": "Error al mejorar el prompt",
|
||||
"enterPrompt": "Por favor, ingresa un prompt para mejorar",
|
||||
"enhancedPrompt": "Prompt Mejorado",
|
||||
"copy": "Copiar",
|
||||
"copied": "Copiado al portapapeles",
|
||||
"inspiredBy": "Inspirado por",
|
||||
"enhanceToSeeResult": "Ingresa un prompt y haz clic en Mejorar para ver el resultado",
|
||||
"loginRequired": "Inicia sesión para usar el Mejorador de Prompts",
|
||||
"history": "Historial",
|
||||
"storedOnDevice": "Almacenado en tu dispositivo",
|
||||
"noHistory": "Sin historial aún"
|
||||
},
|
||||
"appBanner": {
|
||||
"message": "Obtén la app prompts.chat para iPhone, iPad y Mac",
|
||||
"messageShort": "Obtén la app para dispositivos Apple",
|
||||
|
||||
+28
-1
@@ -49,7 +49,8 @@
|
||||
"login": "ورود",
|
||||
"register": "ثبتنام",
|
||||
"logout": "خروج",
|
||||
"ide": "سازنده پرامپت"
|
||||
"ide": "Typed-Prompts IDE",
|
||||
"developers": "توسعهدهندگان"
|
||||
},
|
||||
"brand": {
|
||||
"copyLogoSvg": "کپی SVG لوگو",
|
||||
@@ -1261,6 +1262,32 @@
|
||||
"exampleGenerated": "مثال جدید تولید شد!",
|
||||
"ignoreTypeErrors": "نادیده گرفتن خطاهای نوع"
|
||||
},
|
||||
"developers": {
|
||||
"title": "توسعهدهندگان",
|
||||
"promptBuilder": "Typed-Prompts IDE",
|
||||
"promptEnhancer": "بهبود دهنده پرامپت",
|
||||
"desktopOnly": "فقط دسکتاپ",
|
||||
"desktopOnlyDescription": "ابزارهای توسعهدهنده به صفحه نمایش بزرگتری نیاز دارند. لطفاً این صفحه را در کامپیوتر رومیزی یا لپتاپ باز کنید.",
|
||||
"browsePrompts": "مرور پرامپتها",
|
||||
"inputPrompt": "پرامپت ورودی",
|
||||
"inputPlaceholder": "یک پرامپت ساده برای بهبود وارد کنید...\n\nمثال: یک پست وبلاگ درباره هوش مصنوعی بنویس",
|
||||
"outputType": "نوع",
|
||||
"outputFormat": "قالب",
|
||||
"enhance": "بهبود",
|
||||
"enhancing": "در حال بهبود...",
|
||||
"enhanceSuccess": "پرامپت با موفقیت بهبود یافت!",
|
||||
"enhanceFailed": "بهبود پرامپت ناموفق بود",
|
||||
"enterPrompt": "لطفاً یک پرامپت برای بهبود وارد کنید",
|
||||
"enhancedPrompt": "پرامپت بهبود یافته",
|
||||
"copy": "کپی",
|
||||
"copied": "در کلیپبورد کپی شد",
|
||||
"inspiredBy": "الهام گرفته از",
|
||||
"enhanceToSeeResult": "پرامپت وارد کنید و بهبود را کلیک کنید تا نتیجه را ببینید",
|
||||
"loginRequired": "برای استفاده از بهبود دهنده پرامپت وارد شوید",
|
||||
"history": "تاریخچه",
|
||||
"storedOnDevice": "در دستگاه شما ذخیره شده",
|
||||
"noHistory": "هنوز تاریخچهای نیست"
|
||||
},
|
||||
"appBanner": {
|
||||
"message": "اپلیکیشن prompts.chat را برای iPhone، iPad و Mac دریافت کنید",
|
||||
"messageShort": "اپلیکیشن را برای دستگاههای اپل دریافت کنید",
|
||||
|
||||
+28
-1
@@ -49,7 +49,8 @@
|
||||
"login": "Connexion",
|
||||
"register": "Inscription",
|
||||
"logout": "Déconnexion",
|
||||
"ide": "Prompt Builder"
|
||||
"ide": "Typed-Prompts IDE",
|
||||
"developers": "Développeurs"
|
||||
},
|
||||
"brand": {
|
||||
"copyLogoSvg": "Copier le logo SVG",
|
||||
@@ -1261,6 +1262,32 @@
|
||||
"exampleGenerated": "Nouvel exemple généré !",
|
||||
"ignoreTypeErrors": "Ignorer les erreurs de type"
|
||||
},
|
||||
"developers": {
|
||||
"title": "Développeurs",
|
||||
"promptBuilder": "Typed-Prompts IDE",
|
||||
"promptEnhancer": "Améliorateur de Prompts",
|
||||
"desktopOnly": "Bureau uniquement",
|
||||
"desktopOnlyDescription": "Les outils de développement nécessitent un écran plus grand. Veuillez ouvrir cette page sur un ordinateur de bureau ou portable.",
|
||||
"browsePrompts": "Parcourir les Prompts",
|
||||
"inputPrompt": "Prompt d'entrée",
|
||||
"inputPlaceholder": "Entrez un prompt basique à améliorer...\n\nExemple : écris un article de blog sur l'IA",
|
||||
"outputType": "Type",
|
||||
"outputFormat": "Format",
|
||||
"enhance": "Améliorer",
|
||||
"enhancing": "Amélioration...",
|
||||
"enhanceSuccess": "Prompt amélioré avec succès !",
|
||||
"enhanceFailed": "Échec de l'amélioration du prompt",
|
||||
"enterPrompt": "Veuillez entrer un prompt à améliorer",
|
||||
"enhancedPrompt": "Prompt Amélioré",
|
||||
"copy": "Copier",
|
||||
"copied": "Copié dans le presse-papiers",
|
||||
"inspiredBy": "Inspiré par",
|
||||
"enhanceToSeeResult": "Entrez un prompt et cliquez sur Améliorer pour voir le résultat",
|
||||
"loginRequired": "Veuillez vous connecter pour utiliser l'Améliorateur de Prompts",
|
||||
"history": "Historique",
|
||||
"storedOnDevice": "Stocké sur votre appareil",
|
||||
"noHistory": "Pas encore d'historique"
|
||||
},
|
||||
"appBanner": {
|
||||
"message": "Téléchargez l'app prompts.chat pour iPhone, iPad et Mac",
|
||||
"messageShort": "Téléchargez l'app pour appareils Apple",
|
||||
|
||||
+28
-1
@@ -49,7 +49,8 @@
|
||||
"login": "התחברות",
|
||||
"register": "הרשמה",
|
||||
"logout": "התנתקות",
|
||||
"ide": "Prompt Builder"
|
||||
"ide": "Typed-Prompts IDE",
|
||||
"developers": "מפתחים"
|
||||
},
|
||||
"brand": {
|
||||
"copyLogoSvg": "העתק לוגו SVG",
|
||||
@@ -1261,6 +1262,32 @@
|
||||
"exampleGenerated": "דוגמה חדשה נוצרה!",
|
||||
"ignoreTypeErrors": "התעלם משגיאות טיפוס"
|
||||
},
|
||||
"developers": {
|
||||
"title": "מפתחים",
|
||||
"promptBuilder": "Typed-Prompts IDE",
|
||||
"promptEnhancer": "משפר הנחיות",
|
||||
"desktopOnly": "למחשב בלבד",
|
||||
"desktopOnlyDescription": "כלי המפתחים דורשים מסך גדול יותר. אנא פתח דף זה במחשב שולחני או נייד.",
|
||||
"browsePrompts": "עיין בהנחיות",
|
||||
"inputPrompt": "הנחיית קלט",
|
||||
"inputPlaceholder": "הכנס הנחיה בסיסית לשיפור...\n\nדוגמה: כתוב פוסט בלוג על בינה מלאכותית",
|
||||
"outputType": "סוג",
|
||||
"outputFormat": "פורמט",
|
||||
"enhance": "שפר",
|
||||
"enhancing": "משפר...",
|
||||
"enhanceSuccess": "ההנחיה שופרה בהצלחה!",
|
||||
"enhanceFailed": "שיפור ההנחיה נכשל",
|
||||
"enterPrompt": "אנא הכנס הנחיה לשיפור",
|
||||
"enhancedPrompt": "הנחיה משופרת",
|
||||
"copy": "העתק",
|
||||
"copied": "הועתק ללוח",
|
||||
"inspiredBy": "בהשראת",
|
||||
"enhanceToSeeResult": "הכנס הנחיה ולחץ שפר כדי לראות את התוצאה",
|
||||
"loginRequired": "התחבר כדי להשתמש במשפר ההנחיות",
|
||||
"history": "היסטוריה",
|
||||
"storedOnDevice": "מאוחסן במכשיר שלך",
|
||||
"noHistory": "אין היסטוריה עדיין"
|
||||
},
|
||||
"appBanner": {
|
||||
"message": "הורד את אפליקציית prompts.chat ל-iPhone, iPad ו-Mac",
|
||||
"messageShort": "הורד את האפליקציה למכשירי Apple",
|
||||
|
||||
+28
-1
@@ -49,7 +49,8 @@
|
||||
"login": "Accedi",
|
||||
"register": "Registrati",
|
||||
"logout": "Esci",
|
||||
"ide": "Prompt Builder"
|
||||
"ide": "Typed-Prompts IDE",
|
||||
"developers": "Sviluppatori"
|
||||
},
|
||||
"brand": {
|
||||
"copyLogoSvg": "Copia Logo SVG",
|
||||
@@ -1261,6 +1262,32 @@
|
||||
"exampleGenerated": "Nuovo esempio generato!",
|
||||
"ignoreTypeErrors": "Ignora Errori di Tipo"
|
||||
},
|
||||
"developers": {
|
||||
"title": "Sviluppatori",
|
||||
"promptBuilder": "Typed-Prompts IDE",
|
||||
"promptEnhancer": "Miglioratore di Prompt",
|
||||
"desktopOnly": "Solo Desktop",
|
||||
"desktopOnlyDescription": "Gli strumenti per sviluppatori richiedono uno schermo più grande. Apri questa pagina su un computer desktop o portatile.",
|
||||
"browsePrompts": "Sfoglia Prompt",
|
||||
"inputPrompt": "Prompt di Input",
|
||||
"inputPlaceholder": "Inserisci un prompt base da migliorare...\n\nEsempio: scrivi un post sul blog sull'IA",
|
||||
"outputType": "Tipo",
|
||||
"outputFormat": "Formato",
|
||||
"enhance": "Migliora",
|
||||
"enhancing": "Miglioramento...",
|
||||
"enhanceSuccess": "Prompt migliorato con successo!",
|
||||
"enhanceFailed": "Miglioramento del prompt fallito",
|
||||
"enterPrompt": "Inserisci un prompt da migliorare",
|
||||
"enhancedPrompt": "Prompt Migliorato",
|
||||
"copy": "Copia",
|
||||
"copied": "Copiato negli appunti",
|
||||
"inspiredBy": "Ispirato da",
|
||||
"enhanceToSeeResult": "Inserisci un prompt e clicca Migliora per vedere il risultato",
|
||||
"loginRequired": "Accedi per usare il Miglioratore di Prompt",
|
||||
"history": "Cronologia",
|
||||
"storedOnDevice": "Salvato sul tuo dispositivo",
|
||||
"noHistory": "Nessuna cronologia"
|
||||
},
|
||||
"appBanner": {
|
||||
"message": "Scarica l'app prompts.chat per iPhone, iPad e Mac",
|
||||
"messageShort": "Scarica l'app per dispositivi Apple",
|
||||
|
||||
+28
-1
@@ -49,7 +49,8 @@
|
||||
"login": "ログイン",
|
||||
"register": "登録",
|
||||
"logout": "ログアウト",
|
||||
"ide": "Prompt Builder"
|
||||
"ide": "Typed-Prompts IDE",
|
||||
"developers": "開発者"
|
||||
},
|
||||
"brand": {
|
||||
"copyLogoSvg": "ロゴSVGをコピー",
|
||||
@@ -1261,6 +1262,32 @@
|
||||
"exampleGenerated": "新しい例が生成されました!",
|
||||
"ignoreTypeErrors": "型エラーを無視"
|
||||
},
|
||||
"developers": {
|
||||
"title": "開発者",
|
||||
"promptBuilder": "Typed-Prompts IDE",
|
||||
"promptEnhancer": "プロンプト改善ツール",
|
||||
"desktopOnly": "デスクトップのみ",
|
||||
"desktopOnlyDescription": "開発者ツールにはより大きな画面が必要です。デスクトップまたはノートパソコンでこのページを開いてください。",
|
||||
"browsePrompts": "プロンプトを閲覧",
|
||||
"inputPrompt": "入力プロンプト",
|
||||
"inputPlaceholder": "改善するプロンプトを入力してください...\n\n例:AIについてのブログ記事を書く",
|
||||
"outputType": "タイプ",
|
||||
"outputFormat": "フォーマット",
|
||||
"enhance": "改善",
|
||||
"enhancing": "改善中...",
|
||||
"enhanceSuccess": "プロンプトが正常に改善されました!",
|
||||
"enhanceFailed": "プロンプトの改善に失敗しました",
|
||||
"enterPrompt": "改善するプロンプトを入力してください",
|
||||
"enhancedPrompt": "改善されたプロンプト",
|
||||
"copy": "コピー",
|
||||
"copied": "クリップボードにコピーしました",
|
||||
"inspiredBy": "インスピレーション",
|
||||
"enhanceToSeeResult": "プロンプトを入力して改善をクリックすると結果が表示されます",
|
||||
"loginRequired": "プロンプト改善ツールを使用するにはログインしてください",
|
||||
"history": "履歴",
|
||||
"storedOnDevice": "お使いのデバイスに保存",
|
||||
"noHistory": "履歴はまだありません"
|
||||
},
|
||||
"appBanner": {
|
||||
"message": "iPhone、iPad、Mac用のprompts.chatアプリを入手",
|
||||
"messageShort": "Appleデバイス用アプリを入手",
|
||||
|
||||
+28
-1
@@ -49,7 +49,8 @@
|
||||
"login": "로그인",
|
||||
"register": "회원가입",
|
||||
"logout": "로그아웃",
|
||||
"ide": "Prompt Builder"
|
||||
"ide": "Typed-Prompts IDE",
|
||||
"developers": "개발자"
|
||||
},
|
||||
"brand": {
|
||||
"copyLogoSvg": "로고 SVG 복사",
|
||||
@@ -1261,6 +1262,32 @@
|
||||
"exampleGenerated": "새 예제가 생성되었습니다!",
|
||||
"ignoreTypeErrors": "타입 오류 무시"
|
||||
},
|
||||
"developers": {
|
||||
"title": "개발자",
|
||||
"promptBuilder": "Typed-Prompts IDE",
|
||||
"promptEnhancer": "프롬프트 개선기",
|
||||
"desktopOnly": "데스크톱 전용",
|
||||
"desktopOnlyDescription": "개발자 도구는 더 큰 화면이 필요합니다. 데스크톱 또는 노트북에서 이 페이지를 열어주세요.",
|
||||
"browsePrompts": "프롬프트 찾아보기",
|
||||
"inputPrompt": "입력 프롬프트",
|
||||
"inputPlaceholder": "개선할 기본 프롬프트를 입력하세요...\n\n예: AI에 대한 블로그 글 작성",
|
||||
"outputType": "유형",
|
||||
"outputFormat": "형식",
|
||||
"enhance": "개선",
|
||||
"enhancing": "개선 중...",
|
||||
"enhanceSuccess": "프롬프트가 성공적으로 개선되었습니다!",
|
||||
"enhanceFailed": "프롬프트 개선 실패",
|
||||
"enterPrompt": "개선할 프롬프트를 입력해주세요",
|
||||
"enhancedPrompt": "개선된 프롬프트",
|
||||
"copy": "복사",
|
||||
"copied": "클립보드에 복사됨",
|
||||
"inspiredBy": "영감",
|
||||
"enhanceToSeeResult": "프롬프트를 입력하고 개선을 클릭하여 결과 확인",
|
||||
"loginRequired": "프롬프트 개선기를 사용하려면 로그인하세요",
|
||||
"history": "기록",
|
||||
"storedOnDevice": "기기에 저장됨",
|
||||
"noHistory": "기록 없음"
|
||||
},
|
||||
"appBanner": {
|
||||
"message": "iPhone, iPad, Mac용 prompts.chat 앱 다운로드",
|
||||
"messageShort": "Apple 기기용 앱 다운로드",
|
||||
|
||||
+28
-1
@@ -49,7 +49,8 @@
|
||||
"login": "Entrar",
|
||||
"register": "Cadastrar",
|
||||
"logout": "Sair",
|
||||
"ide": "Prompt Builder"
|
||||
"ide": "Typed-Prompts IDE",
|
||||
"developers": "Desenvolvedores"
|
||||
},
|
||||
"brand": {
|
||||
"copyLogoSvg": "Copiar Logo SVG",
|
||||
@@ -1261,6 +1262,32 @@
|
||||
"exampleGenerated": "Novo exemplo gerado!",
|
||||
"ignoreTypeErrors": "Ignorar Erros de Tipo"
|
||||
},
|
||||
"developers": {
|
||||
"title": "Desenvolvedores",
|
||||
"promptBuilder": "Typed-Prompts IDE",
|
||||
"promptEnhancer": "Melhorador de Prompts",
|
||||
"desktopOnly": "Apenas Desktop",
|
||||
"desktopOnlyDescription": "As ferramentas de desenvolvedor requerem uma tela maior. Por favor, abra esta página em um computador desktop ou laptop.",
|
||||
"browsePrompts": "Explorar Prompts",
|
||||
"inputPrompt": "Prompt de Entrada",
|
||||
"inputPlaceholder": "Digite um prompt básico para melhorar...\n\nExemplo: escreva um post de blog sobre IA",
|
||||
"outputType": "Tipo",
|
||||
"outputFormat": "Formato",
|
||||
"enhance": "Melhorar",
|
||||
"enhancing": "Melhorando...",
|
||||
"enhanceSuccess": "Prompt melhorado com sucesso!",
|
||||
"enhanceFailed": "Falha ao melhorar o prompt",
|
||||
"enterPrompt": "Por favor, digite um prompt para melhorar",
|
||||
"enhancedPrompt": "Prompt Melhorado",
|
||||
"copy": "Copiar",
|
||||
"copied": "Copiado para a área de transferência",
|
||||
"inspiredBy": "Inspirado por",
|
||||
"enhanceToSeeResult": "Digite um prompt e clique em Melhorar para ver o resultado",
|
||||
"loginRequired": "Faça login para usar o Melhorador de Prompts",
|
||||
"history": "Histórico",
|
||||
"storedOnDevice": "Armazenado no seu dispositivo",
|
||||
"noHistory": "Sem histórico ainda"
|
||||
},
|
||||
"appBanner": {
|
||||
"message": "Baixe o app prompts.chat para iPhone, iPad e Mac",
|
||||
"messageShort": "Baixe o app para dispositivos Apple",
|
||||
|
||||
+28
-1
@@ -49,7 +49,8 @@
|
||||
"login": "Войти",
|
||||
"register": "Регистрация",
|
||||
"logout": "Выйти",
|
||||
"ide": "Prompt Builder"
|
||||
"ide": "Typed-Prompts IDE",
|
||||
"developers": "Разработчикам"
|
||||
},
|
||||
"brand": {
|
||||
"copyLogoSvg": "Скопировать логотип SVG",
|
||||
@@ -1261,6 +1262,32 @@
|
||||
"exampleGenerated": "Новый пример сгенерирован!",
|
||||
"ignoreTypeErrors": "Игнорировать ошибки типов"
|
||||
},
|
||||
"developers": {
|
||||
"title": "Разработчикам",
|
||||
"promptBuilder": "Typed-Prompts IDE",
|
||||
"promptEnhancer": "Улучшатель промптов",
|
||||
"desktopOnly": "Только для ПК",
|
||||
"desktopOnlyDescription": "Инструменты разработчика требуют большего экрана. Откройте эту страницу на настольном компьютере или ноутбуке.",
|
||||
"browsePrompts": "Просмотр промптов",
|
||||
"inputPrompt": "Входной промпт",
|
||||
"inputPlaceholder": "Введите базовый промпт для улучшения...\n\nПример: напиши пост в блог об ИИ",
|
||||
"outputType": "Тип",
|
||||
"outputFormat": "Формат",
|
||||
"enhance": "Улучшить",
|
||||
"enhancing": "Улучшение...",
|
||||
"enhanceSuccess": "Промпт успешно улучшен!",
|
||||
"enhanceFailed": "Не удалось улучшить промпт",
|
||||
"enterPrompt": "Введите промпт для улучшения",
|
||||
"enhancedPrompt": "Улучшенный промпт",
|
||||
"copy": "Копировать",
|
||||
"copied": "Скопировано в буфер обмена",
|
||||
"inspiredBy": "Вдохновлено",
|
||||
"enhanceToSeeResult": "Введите промпт и нажмите Улучшить для просмотра результата",
|
||||
"loginRequired": "Войдите, чтобы использовать Улучшатель промптов",
|
||||
"history": "История",
|
||||
"storedOnDevice": "Сохранено на вашем устройстве",
|
||||
"noHistory": "История пуста"
|
||||
},
|
||||
"appBanner": {
|
||||
"message": "Скачайте приложение prompts.chat для iPhone, iPad и Mac",
|
||||
"messageShort": "Скачайте приложение для устройств Apple",
|
||||
|
||||
+28
-1
@@ -49,7 +49,8 @@
|
||||
"login": "Giriş Yap",
|
||||
"register": "Kayıt Ol",
|
||||
"logout": "Çıkış Yap",
|
||||
"ide": "Prompt Builder"
|
||||
"ide": "Typed-Prompts IDE",
|
||||
"developers": "Geliştiriciler"
|
||||
},
|
||||
"brand": {
|
||||
"copyLogoSvg": "Logo SVG'sini Kopyala",
|
||||
@@ -1261,6 +1262,32 @@
|
||||
"exampleGenerated": "Yeni örnek oluşturuldu!",
|
||||
"ignoreTypeErrors": "Tip Hatalarını Yoksay"
|
||||
},
|
||||
"developers": {
|
||||
"title": "Geliştiriciler",
|
||||
"promptBuilder": "Typed-Prompts IDE",
|
||||
"promptEnhancer": "Prompt Geliştirici",
|
||||
"desktopOnly": "Sadece Masaüstü",
|
||||
"desktopOnlyDescription": "Geliştirici araçları daha büyük bir ekran gerektirir. Lütfen bu sayfayı masaüstü veya dizüstü bilgisayarda açın.",
|
||||
"browsePrompts": "Promptlara Göz At",
|
||||
"inputPrompt": "Geliştirilecek Prompt",
|
||||
"inputPlaceholder": "Geliştirilecek bir prompt girin...\n\nÖrnek: yapay zeka hakkında bir blog yazısı yaz",
|
||||
"outputType": "Tür",
|
||||
"outputFormat": "Format",
|
||||
"enhance": "Geliştir",
|
||||
"enhancing": "Geliştiriliyor...",
|
||||
"enhanceSuccess": "Prompt başarıyla geliştirildi!",
|
||||
"enhanceFailed": "Prompt geliştirilemedi",
|
||||
"enterPrompt": "Lütfen geliştirilecek bir prompt girin",
|
||||
"enhancedPrompt": "Geliştirilmiş Prompt",
|
||||
"copy": "Kopyala",
|
||||
"copied": "Panoya kopyalandı",
|
||||
"inspiredBy": "İlham kaynağı",
|
||||
"enhanceToSeeResult": "Sonucu görmek için bir prompt girin ve Geliştir'e tıklayın",
|
||||
"loginRequired": "Prompt Geliştirici'yi kullanmak için giriş yapın",
|
||||
"history": "Geçmiş",
|
||||
"storedOnDevice": "Cihazınızda saklanıyor",
|
||||
"noHistory": "Henüz geçmiş yok"
|
||||
},
|
||||
"appBanner": {
|
||||
"message": "iPhone, iPad ve Mac için prompts.chat uygulamasını indirin",
|
||||
"messageShort": "Apple cihazlar için uygulamayı indirin",
|
||||
|
||||
+28
-1
@@ -49,7 +49,8 @@
|
||||
"login": "登录",
|
||||
"register": "注册",
|
||||
"logout": "退出登录",
|
||||
"ide": "Prompt Builder"
|
||||
"ide": "Typed-Prompts IDE",
|
||||
"developers": "开发者"
|
||||
},
|
||||
"brand": {
|
||||
"copyLogoSvg": "复制Logo SVG",
|
||||
@@ -1261,6 +1262,32 @@
|
||||
"exampleGenerated": "新示例已生成!",
|
||||
"ignoreTypeErrors": "忽略类型错误"
|
||||
},
|
||||
"developers": {
|
||||
"title": "开发者",
|
||||
"promptBuilder": "Typed-Prompts IDE",
|
||||
"promptEnhancer": "提示词优化器",
|
||||
"desktopOnly": "仅限桌面端",
|
||||
"desktopOnlyDescription": "开发者工具需要更大的屏幕。请在台式机或笔记本电脑上打开此页面。",
|
||||
"browsePrompts": "浏览提示词",
|
||||
"inputPrompt": "输入提示词",
|
||||
"inputPlaceholder": "输入一个基础提示词进行优化...\n\n示例:写一篇关于人工智能的博客文章",
|
||||
"outputType": "类型",
|
||||
"outputFormat": "格式",
|
||||
"enhance": "优化",
|
||||
"enhancing": "优化中...",
|
||||
"enhanceSuccess": "提示词优化成功!",
|
||||
"enhanceFailed": "提示词优化失败",
|
||||
"enterPrompt": "请输入要优化的提示词",
|
||||
"enhancedPrompt": "优化后的提示词",
|
||||
"copy": "复制",
|
||||
"copied": "已复制到剪贴板",
|
||||
"inspiredBy": "灵感来源",
|
||||
"enhanceToSeeResult": "输入提示词并点击优化以查看结果",
|
||||
"loginRequired": "请登录以使用提示词优化器",
|
||||
"history": "历史记录",
|
||||
"storedOnDevice": "存储在您的设备上",
|
||||
"noHistory": "暂无历史记录"
|
||||
},
|
||||
"appBanner": {
|
||||
"message": "下载适用于 iPhone、iPad 和 Mac 的 prompts.chat 应用",
|
||||
"messageShort": "下载 Apple 设备应用",
|
||||
|
||||
@@ -3,6 +3,7 @@ import { z } from "zod";
|
||||
import { improvePrompt } from "@/lib/ai/improve-prompt";
|
||||
import { db } from "@/lib/db";
|
||||
import { isValidApiKeyFormat } from "@/lib/api-key";
|
||||
import { auth } from "@/lib/auth";
|
||||
|
||||
const requestSchema = z.object({
|
||||
prompt: z.string().min(1, "Prompt is required").max(10000, "Prompt too long"),
|
||||
@@ -11,7 +12,13 @@ const requestSchema = z.object({
|
||||
});
|
||||
|
||||
async function authenticateRequest(request: NextRequest) {
|
||||
// Check for API key in headers
|
||||
// First check session auth
|
||||
const session = await auth();
|
||||
if (session?.user?.id) {
|
||||
return { id: session.user.id, username: session.user.name || "user" };
|
||||
}
|
||||
|
||||
// Fall back to API key auth
|
||||
const apiKey = request.headers.get("x-api-key") ||
|
||||
request.headers.get("authorization")?.replace("Bearer ", "") ||
|
||||
request.headers.get("prompts-api-key");
|
||||
@@ -30,11 +37,11 @@ async function authenticateRequest(request: NextRequest) {
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
try {
|
||||
// Authenticate request
|
||||
// Authenticate request (session or API key)
|
||||
const user = await authenticateRequest(request);
|
||||
if (!user) {
|
||||
return NextResponse.json(
|
||||
{ error: "Authentication required. Please provide a valid API key." },
|
||||
{ error: "Authentication required. Please log in or provide a valid API key." },
|
||||
{ status: 401 }
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,45 +1,5 @@
|
||||
"use client";
|
||||
import { redirect } from "next/navigation";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { PromptIde } from "@/components/ide/prompt-ide";
|
||||
import { Monitor } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
||||
export default function IdePage() {
|
||||
const t = useTranslations("ide");
|
||||
const [isMobile, setIsMobile] = useState(false);
|
||||
const [mounted, setMounted] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true);
|
||||
const checkMobile = () => {
|
||||
setIsMobile(window.innerWidth < 1024);
|
||||
};
|
||||
checkMobile();
|
||||
window.addEventListener("resize", checkMobile);
|
||||
return () => window.removeEventListener("resize", checkMobile);
|
||||
}, []);
|
||||
|
||||
if (!mounted) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isMobile) {
|
||||
return (
|
||||
<div className="container flex flex-col items-center justify-center min-h-[60vh] px-4 text-center">
|
||||
<Monitor className="h-16 w-16 text-muted-foreground mb-6" />
|
||||
<h1 className="text-2xl font-bold mb-2">{t("desktopOnly")}</h1>
|
||||
<p className="text-muted-foreground mb-6 max-w-md">
|
||||
{t("desktopOnlyDescription")}
|
||||
</p>
|
||||
<Button asChild>
|
||||
<Link href="/prompts">{t("browsePrompts")}</Link>
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return <PromptIde />;
|
||||
export default function BuilderPage() {
|
||||
redirect("/developers");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState, useCallback } from "react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { PromptIde } from "@/components/ide/prompt-ide";
|
||||
import { PromptEnhancer } from "@/components/developers/prompt-enhancer";
|
||||
import { Monitor, Code2, Sparkles } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
|
||||
const VALID_TABS = ["builder", "enhancer"] as const;
|
||||
type TabValue = (typeof VALID_TABS)[number];
|
||||
|
||||
export default function DevelopersPage() {
|
||||
const t = useTranslations("developers");
|
||||
const [isMobile, setIsMobile] = useState(false);
|
||||
const [mounted, setMounted] = useState(false);
|
||||
const [activeTab, setActiveTab] = useState<TabValue>("builder");
|
||||
|
||||
// Read hash from URL on mount and hash changes
|
||||
const updateTabFromHash = useCallback(() => {
|
||||
const hash = window.location.hash.replace("#", "");
|
||||
if (VALID_TABS.includes(hash as TabValue)) {
|
||||
setActiveTab(hash as TabValue);
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true);
|
||||
|
||||
// Check mobile
|
||||
const checkMobile = () => {
|
||||
setIsMobile(window.innerWidth < 1024);
|
||||
};
|
||||
checkMobile();
|
||||
window.addEventListener("resize", checkMobile);
|
||||
|
||||
// Read initial hash
|
||||
updateTabFromHash();
|
||||
|
||||
// Listen for hash changes
|
||||
window.addEventListener("hashchange", updateTabFromHash);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("resize", checkMobile);
|
||||
window.removeEventListener("hashchange", updateTabFromHash);
|
||||
};
|
||||
}, [updateTabFromHash]);
|
||||
|
||||
// Update URL hash when tab changes
|
||||
const handleTabChange = (value: string) => {
|
||||
setActiveTab(value as TabValue);
|
||||
window.history.replaceState(null, "", `#${value}`);
|
||||
};
|
||||
|
||||
if (!mounted) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isMobile) {
|
||||
return (
|
||||
<div className="container flex flex-col items-center justify-center min-h-[60vh] px-4 text-center">
|
||||
<Monitor className="h-16 w-16 text-muted-foreground mb-6" />
|
||||
<h1 className="text-2xl font-bold mb-2">{t("desktopOnly")}</h1>
|
||||
<p className="text-muted-foreground mb-6 max-w-md">
|
||||
{t("desktopOnlyDescription")}
|
||||
</p>
|
||||
<Button asChild>
|
||||
<Link href="/prompts">{t("browsePrompts")}</Link>
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-col h-[calc(100vh-4rem-1.65rem)] overflow-hidden">
|
||||
<Tabs value={activeTab} onValueChange={handleTabChange} className="flex flex-col h-full gap-0 overflow-hidden">
|
||||
<div className="h-10 border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60 px-4 shrink-0 flex items-center">
|
||||
<TabsList className="h-9 bg-transparent border-0 p-0 gap-2">
|
||||
<TabsTrigger
|
||||
value="builder"
|
||||
className="h-9 border-0 border-b-2 border-b-transparent data-[state=active]:border-b-primary data-[state=active]:bg-transparent data-[state=active]:shadow-none focus-visible:ring-0 focus-visible:ring-offset-0 focus:outline-none rounded-none px-3 py-2 gap-1.5 text-sm"
|
||||
>
|
||||
<Code2 className="h-3.5 w-3.5" />
|
||||
{t("promptBuilder")}
|
||||
</TabsTrigger>
|
||||
<TabsTrigger
|
||||
value="enhancer"
|
||||
className="h-9 border-0 border-b-2 border-b-transparent data-[state=active]:border-b-primary data-[state=active]:bg-transparent data-[state=active]:shadow-none focus-visible:ring-0 focus-visible:ring-offset-0 focus:outline-none rounded-none px-3 py-2 gap-1.5 text-sm"
|
||||
>
|
||||
<Sparkles className="h-3.5 w-3.5" />
|
||||
{t("promptEnhancer")}
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
</div>
|
||||
|
||||
<TabsContent value="builder" className="flex-1 mt-0 min-h-0 overflow-hidden data-[state=inactive]:hidden">
|
||||
<PromptIde />
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="enhancer" className="flex-1 mt-0 min-h-0 overflow-hidden data-[state=inactive]:hidden">
|
||||
<PromptEnhancer />
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,387 @@
|
||||
"use client";
|
||||
|
||||
import { useState, useEffect } from "react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useTheme } from "next-themes";
|
||||
import Editor from "@monaco-editor/react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import { Loader2, Sparkles, Copy, Check, Trash2, HardDrive } from "lucide-react";
|
||||
import { toast } from "sonner";
|
||||
import { RunPromptButton } from "@/components/prompts/run-prompt-button";
|
||||
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||
|
||||
const OUTPUT_TYPES = [
|
||||
{ value: "text", label: "Text" },
|
||||
{ value: "image", label: "Image" },
|
||||
{ value: "video", label: "Video" },
|
||||
{ value: "sound", label: "Sound" },
|
||||
] as const;
|
||||
|
||||
const OUTPUT_FORMATS = [
|
||||
{ value: "text", label: "Text" },
|
||||
{ value: "structured_json", label: "JSON" },
|
||||
{ value: "structured_yaml", label: "YAML" },
|
||||
] as const;
|
||||
|
||||
type OutputType = (typeof OUTPUT_TYPES)[number]["value"];
|
||||
type OutputFormat = (typeof OUTPUT_FORMATS)[number]["value"];
|
||||
|
||||
interface EnhanceResponse {
|
||||
original: string;
|
||||
improved: string;
|
||||
outputType: OutputType;
|
||||
outputFormat: OutputFormat;
|
||||
inspirations: Array<{ id: string; slug: string | null; title: string; similarity: number }>;
|
||||
model: string;
|
||||
}
|
||||
|
||||
interface SavedPrompt {
|
||||
id: string;
|
||||
input: string;
|
||||
output: string;
|
||||
outputType: OutputType;
|
||||
outputFormat: OutputFormat;
|
||||
createdAt: number;
|
||||
}
|
||||
|
||||
const STORAGE_KEY = "promptEnhancerHistory";
|
||||
const MAX_HISTORY = 50;
|
||||
|
||||
function loadHistory(): SavedPrompt[] {
|
||||
if (typeof window === "undefined") return [];
|
||||
try {
|
||||
const saved = localStorage.getItem(STORAGE_KEY);
|
||||
return saved ? JSON.parse(saved) : [];
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
function saveHistory(history: SavedPrompt[]) {
|
||||
if (typeof window === "undefined") return;
|
||||
localStorage.setItem(STORAGE_KEY, JSON.stringify(history.slice(0, MAX_HISTORY)));
|
||||
}
|
||||
|
||||
export function PromptEnhancer() {
|
||||
const t = useTranslations("developers");
|
||||
const { theme } = useTheme();
|
||||
const [prompt, setPrompt] = useState("");
|
||||
const [outputType, setOutputType] = useState<OutputType>("text");
|
||||
const [outputFormat, setOutputFormat] = useState<OutputFormat>("text");
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [result, setResult] = useState<EnhanceResponse | null>(null);
|
||||
const [copied, setCopied] = useState(false);
|
||||
const [history, setHistory] = useState<SavedPrompt[]>([]);
|
||||
const [selectedId, setSelectedId] = useState<string | null>(null);
|
||||
|
||||
// Load history from localStorage on mount
|
||||
useEffect(() => {
|
||||
setHistory(loadHistory());
|
||||
}, []);
|
||||
|
||||
// Determine language for Monaco based on output format
|
||||
const getEditorLanguage = () => {
|
||||
if (outputFormat === "structured_json") return "json";
|
||||
if (outputFormat === "structured_yaml") return "yaml";
|
||||
return "markdown";
|
||||
};
|
||||
|
||||
const addToHistory = (input: string, output: string, type: OutputType, format: OutputFormat) => {
|
||||
const newItem: SavedPrompt = {
|
||||
id: Date.now().toString(),
|
||||
input,
|
||||
output,
|
||||
outputType: type,
|
||||
outputFormat: format,
|
||||
createdAt: Date.now(),
|
||||
};
|
||||
const newHistory = [newItem, ...history].slice(0, MAX_HISTORY);
|
||||
setHistory(newHistory);
|
||||
saveHistory(newHistory);
|
||||
setSelectedId(newItem.id);
|
||||
};
|
||||
|
||||
const deleteFromHistory = (id: string) => {
|
||||
const newHistory = history.filter((item) => item.id !== id);
|
||||
setHistory(newHistory);
|
||||
saveHistory(newHistory);
|
||||
if (selectedId === id) {
|
||||
setSelectedId(null);
|
||||
setResult(null);
|
||||
setPrompt("");
|
||||
}
|
||||
};
|
||||
|
||||
const loadFromHistory = (item: SavedPrompt) => {
|
||||
setPrompt(item.input);
|
||||
setOutputType(item.outputType);
|
||||
setOutputFormat(item.outputFormat);
|
||||
setResult({
|
||||
original: item.input,
|
||||
improved: item.output,
|
||||
outputType: item.outputType,
|
||||
outputFormat: item.outputFormat,
|
||||
inspirations: [],
|
||||
model: "",
|
||||
});
|
||||
setSelectedId(item.id);
|
||||
};
|
||||
|
||||
const handleEnhance = async () => {
|
||||
if (!prompt.trim()) {
|
||||
toast.error(t("enterPrompt"));
|
||||
return;
|
||||
}
|
||||
|
||||
setIsLoading(true);
|
||||
|
||||
try {
|
||||
const response = await fetch("/api/improve-prompt", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ prompt: prompt.trim(), outputType, outputFormat }),
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || t("enhanceFailed"));
|
||||
}
|
||||
|
||||
setResult(data);
|
||||
addToHistory(prompt.trim(), data.improved, outputType, outputFormat);
|
||||
toast.success(t("enhanceSuccess"));
|
||||
} catch (error) {
|
||||
toast.error(
|
||||
error instanceof Error ? error.message : t("enhanceFailed")
|
||||
);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleCopy = async () => {
|
||||
if (result?.improved) {
|
||||
await navigator.clipboard.writeText(result.improved);
|
||||
setCopied(true);
|
||||
toast.success(t("copied"));
|
||||
setTimeout(() => setCopied(false), 2000);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="h-full flex overflow-hidden">
|
||||
{/* History Sidebar */}
|
||||
<div className="w-64 h-full flex flex-col border-r bg-muted/20 shrink-0">
|
||||
<div className="p-3 border-b">
|
||||
<h3 className="text-sm font-medium">{t("history")}</h3>
|
||||
<p className="text-xs text-muted-foreground flex items-center gap-1 mt-1">
|
||||
<HardDrive className="h-3 w-3" />
|
||||
{t("storedOnDevice")}
|
||||
</p>
|
||||
</div>
|
||||
<ScrollArea className="flex-1">
|
||||
<div className="p-2 space-y-1">
|
||||
{history.length === 0 ? (
|
||||
<p className="text-xs text-muted-foreground text-center py-4">
|
||||
{t("noHistory")}
|
||||
</p>
|
||||
) : (
|
||||
history.map((item) => (
|
||||
<div
|
||||
key={item.id}
|
||||
className={`group relative p-2 rounded-md cursor-pointer text-xs hover:bg-muted transition-colors overflow-hidden ${
|
||||
selectedId === item.id ? "bg-muted" : ""
|
||||
}`}
|
||||
onClick={() => loadFromHistory(item)}
|
||||
>
|
||||
<p className="font-medium truncate pr-6">{item.input.slice(0, 30)}</p>
|
||||
<p className="text-muted-foreground truncate mt-0.5">
|
||||
→ {item.output.slice(0, 25)}
|
||||
</p>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="absolute top-1 right-1 h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
deleteFromHistory(item.id);
|
||||
}}
|
||||
>
|
||||
<Trash2 className="h-3 w-3" />
|
||||
</Button>
|
||||
</div>
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
</ScrollArea>
|
||||
</div>
|
||||
|
||||
{/* Left Panel - Input */}
|
||||
<div className="flex-1 h-full flex flex-col border-r min-w-0 overflow-hidden">
|
||||
<div className="h-10 px-4 border-b bg-muted/30 flex items-center justify-between shrink-0">
|
||||
<span className="text-sm font-medium text-muted-foreground">{t("inputPrompt")}</span>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="flex items-center gap-1">
|
||||
<label className="text-xs text-muted-foreground">{t("outputType")}:</label>
|
||||
<Select value={outputType} onValueChange={(v) => setOutputType(v as OutputType)}>
|
||||
<SelectTrigger className="!h-6 w-[72px] text-xs !py-0 px-1.5">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{OUTPUT_TYPES.map((type) => (
|
||||
<SelectItem key={type.value} value={type.value} className="text-xs">
|
||||
{type.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="flex items-center gap-1">
|
||||
<label className="text-xs text-muted-foreground">{t("outputFormat")}:</label>
|
||||
<Select value={outputFormat} onValueChange={(v) => setOutputFormat(v as OutputFormat)}>
|
||||
<SelectTrigger className="!h-6 w-[64px] text-xs !py-0 px-1.5">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{OUTPUT_FORMATS.map((format) => (
|
||||
<SelectItem key={format.value} value={format.value} className="text-xs">
|
||||
{format.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex-1 flex flex-col min-h-0">
|
||||
<Textarea
|
||||
placeholder={t("inputPlaceholder")}
|
||||
value={prompt}
|
||||
onChange={(e) => setPrompt(e.target.value)}
|
||||
className="flex-1 resize-none font-mono text-sm min-h-0 rounded-none border-0"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="h-10 px-4 border-t bg-background flex items-center justify-between shrink-0">
|
||||
<div className="text-xs text-muted-foreground">
|
||||
{prompt.length.toLocaleString()} / 10,000
|
||||
</div>
|
||||
<Button
|
||||
onClick={handleEnhance}
|
||||
disabled={isLoading || !prompt.trim()}
|
||||
size="sm"
|
||||
className="h-7 gap-1.5"
|
||||
>
|
||||
{isLoading ? (
|
||||
<>
|
||||
<Loader2 className="h-3.5 w-3.5 animate-spin" />
|
||||
{t("enhancing")}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Sparkles className="h-3.5 w-3.5" />
|
||||
{t("enhance")}
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Right Panel - Output */}
|
||||
<div className="flex-1 h-full flex flex-col min-w-0 overflow-hidden">
|
||||
<div className="h-10 px-4 border-b bg-muted/30 flex items-center justify-between shrink-0">
|
||||
<span className="text-sm font-medium text-muted-foreground">{t("enhancedPrompt")}</span>
|
||||
{result && (
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-xs text-muted-foreground">
|
||||
{result.model}
|
||||
</span>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={handleCopy}
|
||||
className="h-6 w-6"
|
||||
>
|
||||
{copied ? (
|
||||
<Check className="h-3 w-3" />
|
||||
) : (
|
||||
<Copy className="h-3 w-3" />
|
||||
)}
|
||||
</Button>
|
||||
<RunPromptButton
|
||||
content={result.improved}
|
||||
size="sm"
|
||||
variant="default"
|
||||
className="h-7 bg-green-600 hover:bg-green-700 text-white"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex-1 min-h-0 overflow-hidden">
|
||||
{result ? (
|
||||
<Editor
|
||||
height="100%"
|
||||
language={getEditorLanguage()}
|
||||
value={result.improved}
|
||||
theme={theme === "dark" ? "vs-dark" : "light"}
|
||||
options={{
|
||||
readOnly: true,
|
||||
minimap: { enabled: false },
|
||||
fontSize: 13,
|
||||
lineNumbers: "on",
|
||||
wordWrap: "on",
|
||||
scrollBeyondLastLine: false,
|
||||
automaticLayout: true,
|
||||
padding: { top: 8, bottom: 8 },
|
||||
folding: true,
|
||||
renderLineHighlight: "none",
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<div className="h-full flex items-center justify-center text-muted-foreground text-sm">
|
||||
{t("enhanceToSeeResult")}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{result && result.inspirations.length > 0 && (
|
||||
<div className="p-4 pt-2 space-y-2 border-t">
|
||||
<p className="text-xs font-medium text-muted-foreground">
|
||||
{t("inspiredBy")}:
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-1.5">
|
||||
{result.inspirations.map((ins) => {
|
||||
const promptPath = `/prompts/${ins.id}${ins.slug ? `_${ins.slug}` : ""}`;
|
||||
return (
|
||||
<a
|
||||
key={ins.id}
|
||||
href={promptPath}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex items-center gap-1 rounded-full bg-primary/10 px-2 py-0.5 text-xs hover:bg-primary/20 transition-colors"
|
||||
>
|
||||
{ins.title}
|
||||
<span className="text-muted-foreground">
|
||||
{ins.similarity}%
|
||||
</span>
|
||||
</a>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -672,47 +672,9 @@ export function PromptIde() {
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col h-[calc(100vh-48px)]">
|
||||
{/* Toolbar */}
|
||||
<div className="flex items-center justify-between border-b px-4 py-2 bg-background">
|
||||
<div className="flex items-center gap-3">
|
||||
<Code2 className="h-5 w-5 text-muted-foreground" />
|
||||
<div>
|
||||
<h1 className="text-lg font-semibold leading-tight">{t("title")}</h1>
|
||||
<p className="text-xs text-muted-foreground">{t("subtitle")}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
asChild
|
||||
className="gap-2"
|
||||
>
|
||||
<a href="https://github.com/f/awesome-chatgpt-prompts/blob/main/packages/prompts.chat/API.md" target="_blank" rel="noopener noreferrer">
|
||||
<FileText className="h-4 w-4" />
|
||||
Docs
|
||||
</a>
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={createPrompt}
|
||||
className="gap-2"
|
||||
>
|
||||
<Plus className="h-4 w-4" />
|
||||
{t("createPrompt")}
|
||||
</Button>
|
||||
<RunPromptButton
|
||||
content={output || lastValidOutput}
|
||||
size="sm"
|
||||
variant="default"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col h-full overflow-hidden">
|
||||
{/* Main content */}
|
||||
<div className="flex flex-1 overflow-hidden">
|
||||
<div className="flex flex-1 overflow-hidden min-h-0">
|
||||
{/* API Docs sidebar */}
|
||||
<div className="relative flex flex-col">
|
||||
<ApiDocsSidebar selectedItem={selectedApiItem} onSelectItem={setSelectedApiItem} />
|
||||
@@ -722,8 +684,8 @@ export function PromptIde() {
|
||||
</div>
|
||||
|
||||
{/* Editor panel */}
|
||||
<div className="flex-1 flex flex-col border-r min-w-0">
|
||||
<div className="h-10 px-4 border-b bg-muted/30 flex items-center justify-between">
|
||||
<div className="flex-1 flex flex-col border-r min-w-0 min-h-0 overflow-hidden">
|
||||
<div className="h-10 px-4 border-b bg-muted/30 flex items-center justify-between shrink-0">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-sm font-medium text-muted-foreground">{t("editor")}</span>
|
||||
<span className="text-[10px] text-muted-foreground/60 bg-muted px-1.5 py-0.5 rounded">⌥ + Space</span>
|
||||
@@ -806,8 +768,8 @@ export function PromptIde() {
|
||||
</div>
|
||||
|
||||
{/* Preview panel */}
|
||||
<div className="flex-1 flex flex-col min-w-0">
|
||||
<div className="h-10 px-4 border-b bg-muted/30 flex items-center justify-between">
|
||||
<div className="flex-1 flex flex-col min-w-0 min-h-0 overflow-hidden">
|
||||
<div className="h-10 px-4 border-b bg-muted/30 flex items-center justify-between shrink-0">
|
||||
<span className="text-sm font-medium text-muted-foreground">{t("preview")}</span>
|
||||
<div className="flex items-center gap-2">
|
||||
<Tabs value={outputFormat} onValueChange={(v) => setOutputFormat(v as OutputFormat)}>
|
||||
@@ -990,8 +952,39 @@ export function PromptIde() {
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Action buttons above console */}
|
||||
<div className="border-t bg-background px-4 py-2 flex items-center justify-between shrink-0">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
asChild
|
||||
className="gap-2"
|
||||
>
|
||||
<a href="https://github.com/f/awesome-chatgpt-prompts/blob/main/packages/prompts.chat/API.md" target="_blank" rel="noopener noreferrer">
|
||||
<FileText className="h-4 w-4" />
|
||||
Docs
|
||||
</a>
|
||||
</Button>
|
||||
<div className="flex items-center gap-2">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={createPrompt}
|
||||
className="gap-2"
|
||||
>
|
||||
<Plus className="h-4 w-4" />
|
||||
{t("createPrompt")}
|
||||
</Button>
|
||||
<RunPromptButton
|
||||
content={output || lastValidOutput}
|
||||
size="sm"
|
||||
variant="default"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Console panel - inside preview section */}
|
||||
<div className="border-t bg-background">
|
||||
<div className="border-t bg-background shrink-0">
|
||||
{/* Resize handle */}
|
||||
{isConsoleOpen && (
|
||||
<div
|
||||
|
||||
@@ -11,7 +11,7 @@ export function Footer() {
|
||||
const t = useTranslations("footer");
|
||||
|
||||
return (
|
||||
<footer className="border-t">
|
||||
<footer className="border-t shrink-0">
|
||||
<div className="container flex flex-col items-center gap-3 py-4 text-xs text-muted-foreground sm:flex-row sm:justify-between sm:h-10 sm:py-0 sm:gap-4">
|
||||
<span className="flex items-center gap-1.5">
|
||||
<Image src="/logo.svg" alt="" width={14} height={14} className="dark:invert" />
|
||||
|
||||
@@ -103,7 +103,7 @@ export function Header({ authProvider = "credentials", allowRegistration = true
|
||||
|
||||
return (
|
||||
<header className="sticky top-0 z-50 w-full border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
|
||||
<div className={`flex h-12 items-center gap-4 ${pathname === "/builder" ? "px-4" : "container"}`}>
|
||||
<div className={`flex h-12 items-center gap-4 ${pathname === "/developers" ? "px-4" : "container"}`}>
|
||||
{/* Mobile menu */}
|
||||
<Sheet open={mobileMenuOpen} onOpenChange={setMobileMenuOpen}>
|
||||
<SheetTrigger asChild className="md:hidden">
|
||||
@@ -293,10 +293,10 @@ export function Header({ authProvider = "credentials", allowRegistration = true
|
||||
{t("nav.promptmasters")}
|
||||
</Link>
|
||||
<Link
|
||||
href="/builder"
|
||||
href="/developers"
|
||||
className="hidden lg:block px-3 py-1.5 rounded-md text-muted-foreground transition-colors hover:text-foreground hover:bg-accent"
|
||||
>
|
||||
{t("nav.ide")}
|
||||
{t("nav.developers")}
|
||||
</Link>
|
||||
</nav>
|
||||
|
||||
|
||||
@@ -56,6 +56,8 @@ messages:
|
||||
- Keep improvements practical and actionable
|
||||
- Use clear, professional language
|
||||
- For media prompts (IMAGE/VIDEO/AUDIO), include relevant technical specifications
|
||||
- For text prompts, use "Act as" role-playing format: "Act as a [role]. You are [description]..."
|
||||
- For media prompts (IMAGE/VIDEO/AUDIO), NEVER use Role Playing format
|
||||
|
||||
## Response Rules
|
||||
- Output ONLY the improved prompt content
|
||||
|
||||
@@ -37,7 +37,7 @@ export interface ImprovePromptResult {
|
||||
improved: string;
|
||||
outputType: OutputType;
|
||||
outputFormat: OutputFormat;
|
||||
inspirations: Array<{ title: string; similarity: number }>;
|
||||
inspirations: Array<{ id: string; slug: string | null; title: string; similarity: number }>;
|
||||
model: string;
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ async function findSimilarPrompts(
|
||||
query: string,
|
||||
outputType: OutputType,
|
||||
limit: number = 3
|
||||
): Promise<Array<{ title: string; content: string; similarity: number }>> {
|
||||
): Promise<Array<{ id: string; slug: string | null; title: string; content: string; similarity: number }>> {
|
||||
const aiSearchEnabled = await isAISearchEnabled();
|
||||
if (!aiSearchEnabled) {
|
||||
console.log("[improve-prompt] AI search is not enabled");
|
||||
@@ -87,6 +87,8 @@ async function findSimilarPrompts(
|
||||
...(dbType ? { type: dbType } : {}),
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
slug: true,
|
||||
title: true,
|
||||
content: true,
|
||||
embedding: true,
|
||||
@@ -103,6 +105,8 @@ async function findSimilarPrompts(
|
||||
const embedding = prompt.embedding as number[];
|
||||
const similarity = cosineSimilarity(queryEmbedding, embedding);
|
||||
return {
|
||||
id: prompt.id,
|
||||
slug: prompt.slug,
|
||||
title: prompt.title,
|
||||
content: prompt.content,
|
||||
similarity,
|
||||
@@ -184,6 +188,8 @@ export async function improvePrompt(input: ImprovePromptInput): Promise<ImproveP
|
||||
outputType,
|
||||
outputFormat,
|
||||
inspirations: similarPrompts.map((p) => ({
|
||||
id: p.id,
|
||||
slug: p.slug,
|
||||
title: p.title,
|
||||
similarity: Math.round(p.similarity * 100),
|
||||
})),
|
||||
|
||||
@@ -10,9 +10,9 @@ export function setLocale(locale: string): void {
|
||||
// Set cookie with 1 year expiry
|
||||
document.cookie = `${LOCALE_COOKIE}=${locale}; path=/; max-age=${60 * 60 * 24 * 365}; SameSite=Lax`;
|
||||
|
||||
// Force a hard navigation to the same URL to ensure server re-renders with new locale
|
||||
// Using href assignment instead of reload() for more reliable behavior in Next.js
|
||||
window.location.href = window.location.href;
|
||||
// Force a hard navigation to ensure server re-renders with new locale
|
||||
// Using reload() to ensure proper refresh even with hash URLs
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user