feat(messages): update developer-related messages in multiple languages

This commit is contained in:
Fatih Kadir Akın
2026-01-03 23:19:55 +03:00
parent d4287db9e3
commit 0d6a230793
26 changed files with 1011 additions and 116 deletions
+28 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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 设备应用",
+10 -3
View File
@@ -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 }
);
}
+3 -43
View File
@@ -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");
}
+108
View File
@@ -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>
);
}
+38 -45
View File
@@ -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
+1 -1
View File
@@ -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" />
+3 -3
View File
@@ -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>
+2
View File
@@ -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
+8 -2
View File
@@ -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),
})),
+3 -3
View File
@@ -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();
}
/**