fix(i18n): Fix syntax errors and add missing translation keys - Restored broken useStore destructuring in PromptEnhancer, UXDesignerPrompt, ActionPlanGenerator, SlidesGenerator - Fixed GoogleAdsGenerator scope issue with renderMagicWandSectionContent - Added missing inputLabel keys to promptEnhancer for all languages - Fixed t.resultTitle to t.enhancedTitle in PromptEnhancer

This commit is contained in:
Gemini AI
2025-12-28 02:00:42 +04:00
Unverified
parent b859d77307
commit 238a576cb8
6 changed files with 1836 additions and 1794 deletions

View File

@@ -11,7 +11,16 @@ import { cn } from "@/lib/utils";
import { translations } from "@/lib/i18n/translations"; import { translations } from "@/lib/i18n/translations";
export default function ActionPlanGenerator() { export default function ActionPlanGenerator() {
const {
language, language,
currentPrompt,
actionPlan,
selectedProvider,
selectedModels,
availableModels,
apiKeys,
isProcessing,
error,
setCurrentPrompt, setCurrentPrompt,
setSelectedProvider, setSelectedProvider,
setActionPlan, setActionPlan,
@@ -21,15 +30,15 @@ export default function ActionPlanGenerator() {
setSelectedModel, setSelectedModel,
} = useStore(); } = useStore();
const t = translations[language].actionPlan; const t = translations[language].actionPlan;
const common = translations[language].common; const common = translations[language].common;
const [copied, setCopied] = useState(false); const [copied, setCopied] = useState(false);
const selectedModel = selectedModels[selectedProvider]; const selectedModel = selectedModels[selectedProvider];
const models = availableModels[selectedProvider] || modelAdapter.getAvailableModels(selectedProvider); const models = availableModels[selectedProvider] || modelAdapter.getAvailableModels(selectedProvider);
useEffect(() => { useEffect(() => {
if (typeof window !== "undefined") { if (typeof window !== "undefined") {
loadAvailableModels(); loadAvailableModels();
const saved = localStorage.getItem("promptarch-api-keys"); const saved = localStorage.getItem("promptarch-api-keys");
@@ -44,9 +53,9 @@ useEffect(() => {
} }
} }
} }
}, [selectedProvider]); }, [selectedProvider]);
const loadAvailableModels = async () => { const loadAvailableModels = async () => {
const fallbackModels = modelAdapter.getAvailableModels(selectedProvider); const fallbackModels = modelAdapter.getAvailableModels(selectedProvider);
setAvailableModels(selectedProvider, fallbackModels); setAvailableModels(selectedProvider, fallbackModels);
@@ -58,9 +67,9 @@ const loadAvailableModels = async () => {
} catch (error) { } catch (error) {
console.error("Failed to load models:", error); console.error("Failed to load models:", error);
} }
}; };
const handleGenerate = async () => { const handleGenerate = async () => {
if (!currentPrompt.trim()) { if (!currentPrompt.trim()) {
setError("Please enter PRD or project requirements"); setError("Please enter PRD or project requirements");
return; return;
@@ -111,17 +120,17 @@ const handleGenerate = async () => {
} finally { } finally {
setProcessing(false); setProcessing(false);
} }
}; };
const handleCopy = async () => { const handleCopy = async () => {
if (actionPlan?.rawContent) { if (actionPlan?.rawContent) {
await navigator.clipboard.writeText(actionPlan.rawContent); await navigator.clipboard.writeText(actionPlan.rawContent);
setCopied(true); setCopied(true);
setTimeout(() => setCopied(false), 2000); setTimeout(() => setCopied(false), 2000);
} }
}; };
return ( return (
<div className="mx-auto grid max-w-7xl gap-4 lg:gap-6 grid-cols-1 lg:grid-cols-2 text-start"> <div className="mx-auto grid max-w-7xl gap-4 lg:gap-6 grid-cols-1 lg:grid-cols-2 text-start">
<Card className="h-fit"> <Card className="h-fit">
<CardHeader className="p-4 lg:p-6 text-start"> <CardHeader className="p-4 lg:p-6 text-start">
@@ -257,5 +266,5 @@ return (
</CardContent> </CardContent>
</Card> </Card>
</div> </div>
); );
} }

View File

@@ -394,10 +394,9 @@ export default function GoogleAdsGenerator() {
default: default:
return <pre className="whitespace-pre-wrap text-xs">{googleAdsResult.rawContent}</pre>; return <pre className="whitespace-pre-wrap text-xs">{googleAdsResult.rawContent}</pre>;
} }
} };
};
const renderMagicWandSectionContent = (sectionId: string) => { const renderMagicWandSectionContent = (sectionId: string) => {
if (!magicWandResult) return null; if (!magicWandResult) return null;
switch (sectionId) { switch (sectionId) {
@@ -546,10 +545,10 @@ const renderMagicWandSectionContent = (sectionId: string) => {
default: default:
return <pre className="whitespace-pre-wrap text-xs">{magicWandResult.rawContent}</pre>; return <pre className="whitespace-pre-wrap text-xs">{magicWandResult.rawContent}</pre>;
} }
}; };
return ( return (
<div className="mx-auto grid max-w-7xl gap-4 lg:gap-6 grid-cols-1 lg:grid-cols-2"> <div className="mx-auto grid max-w-7xl gap-4 lg:gap-6 grid-cols-1 lg:grid-cols-2">
<Card className="h-fit"> <Card className="h-fit">
<CardHeader className="p-4 lg:p-6 text-start"> <CardHeader className="p-4 lg:p-6 text-start">
@@ -797,5 +796,5 @@ return (
</CardContent> </CardContent>
</Card> </Card>
</div> </div>
); );
} }

View File

@@ -11,7 +11,16 @@ import { cn } from "@/lib/utils";
import { translations } from "@/lib/i18n/translations"; import { translations } from "@/lib/i18n/translations";
export default function PromptEnhancer() { export default function PromptEnhancer() {
const {
language, language,
currentPrompt,
enhancedPrompt,
selectedProvider,
selectedModels,
availableModels,
apiKeys,
isProcessing,
error,
setSelectedProvider, setSelectedProvider,
setCurrentPrompt, setCurrentPrompt,
setEnhancedPrompt, setEnhancedPrompt,
@@ -21,15 +30,15 @@ export default function PromptEnhancer() {
setSelectedModel, setSelectedModel,
} = useStore(); } = useStore();
const t = translations[language].promptEnhancer; const t = translations[language].promptEnhancer;
const common = translations[language].common; const common = translations[language].common;
const [copied, setCopied] = useState(false); const [copied, setCopied] = useState(false);
const selectedModel = selectedModels[selectedProvider]; const selectedModel = selectedModels[selectedProvider];
const models = availableModels[selectedProvider] || modelAdapter.getAvailableModels(selectedProvider); const models = availableModels[selectedProvider] || modelAdapter.getAvailableModels(selectedProvider);
useEffect(() => { useEffect(() => {
if (typeof window !== "undefined") { if (typeof window !== "undefined") {
loadAvailableModels(); loadAvailableModels();
const saved = localStorage.getItem("promptarch-api-keys"); const saved = localStorage.getItem("promptarch-api-keys");
@@ -44,9 +53,9 @@ useEffect(() => {
} }
} }
} }
}, [selectedProvider]); }, [selectedProvider]);
const loadAvailableModels = async () => { const loadAvailableModels = async () => {
const fallbackModels = modelAdapter.getAvailableModels(selectedProvider); const fallbackModels = modelAdapter.getAvailableModels(selectedProvider);
setAvailableModels(selectedProvider, fallbackModels); setAvailableModels(selectedProvider, fallbackModels);
@@ -58,9 +67,9 @@ const loadAvailableModels = async () => {
} catch (error) { } catch (error) {
console.error("Failed to load models:", error); console.error("Failed to load models:", error);
} }
}; };
const handleEnhance = async () => { const handleEnhance = async () => {
if (!currentPrompt.trim()) { if (!currentPrompt.trim()) {
setError("Please enter a prompt to enhance"); setError("Please enter a prompt to enhance");
return; return;
@@ -96,23 +105,23 @@ const handleEnhance = async () => {
} finally { } finally {
setProcessing(false); setProcessing(false);
} }
}; };
const handleCopy = async () => { const handleCopy = async () => {
if (enhancedPrompt) { if (enhancedPrompt) {
await navigator.clipboard.writeText(enhancedPrompt); await navigator.clipboard.writeText(enhancedPrompt);
setCopied(true); setCopied(true);
setTimeout(() => setCopied(false), 2000); setTimeout(() => setCopied(false), 2000);
} }
}; };
const handleClear = () => { const handleClear = () => {
setCurrentPrompt(""); setCurrentPrompt("");
setEnhancedPrompt(null); setEnhancedPrompt(null);
setError(null); setError(null);
}; };
return ( return (
<div className="mx-auto grid max-w-7xl gap-4 lg:gap-6 grid-cols-1 lg:grid-cols-2 text-start"> <div className="mx-auto grid max-w-7xl gap-4 lg:gap-6 grid-cols-1 lg:grid-cols-2 text-start">
<Card className="h-fit"> <Card className="h-fit">
<CardHeader className="p-4 lg:p-6 text-start"> <CardHeader className="p-4 lg:p-6 text-start">
@@ -209,7 +218,7 @@ return (
<CardTitle className="flex items-center justify-between text-base lg:text-lg"> <CardTitle className="flex items-center justify-between text-base lg:text-lg">
<span className="flex items-center gap-2"> <span className="flex items-center gap-2">
<CheckCircle2 className="h-4 w-4 lg:h-5 lg:w-5 text-green-500" /> <CheckCircle2 className="h-4 w-4 lg:h-5 lg:w-5 text-green-500" />
{t.resultTitle} {t.enhancedTitle}
</span> </span>
{enhancedPrompt && ( {enhancedPrompt && (
<Button variant="ghost" size="icon" onClick={handleCopy} className="h-8 w-8 lg:h-9 lg:w-9"> <Button variant="ghost" size="icon" onClick={handleCopy} className="h-8 w-8 lg:h-9 lg:w-9">
@@ -238,5 +247,5 @@ return (
</CardContent> </CardContent>
</Card> </Card>
</div> </div>
); );
} }

View File

@@ -108,36 +108,49 @@ const ACCEPTED_FILE_TYPES = {
const ALL_ACCEPTED = Object.values(ACCEPTED_FILE_TYPES).flat().join(","); const ALL_ACCEPTED = Object.values(ACCEPTED_FILE_TYPES).flat().join(",");
export default function SlidesGenerator() { export default function SlidesGenerator() {
const {
selectedProvider,
selectedModels,
availableModels,
apiKeys,
isProcessing,
error,
slidesPresentation,
setSelectedProvider,
setSlidesPresentation,
setProcessing,
setError,
setAvailableModels,
setSelectedModel, setSelectedModel,
language: uiLanguage, language: uiLanguage,
} = useStore(); } = useStore();
const t = translations[uiLanguage].slidesGen; const t = translations[uiLanguage].slidesGen;
const common = translations[uiLanguage].common; const common = translations[uiLanguage].common;
const [topic, setTopic] = useState(""); const [topic, setTopic] = useState("");
const [language, setLanguage] = useState("en"); const [language, setLanguage] = useState("en");
const [theme, setTheme] = useState("executive-dark"); const [theme, setTheme] = useState("executive-dark");
const [audience, setAudience] = useState("executives"); const [audience, setAudience] = useState("executives");
const [organization, setOrganization] = useState(""); const [organization, setOrganization] = useState("");
const [slideCount, setSlideCount] = useState(10); const [slideCount, setSlideCount] = useState(10);
const [animationStyle, setAnimationStyle] = useState("professional"); const [animationStyle, setAnimationStyle] = useState("professional");
const [copied, setCopied] = useState(false); const [copied, setCopied] = useState(false);
const [currentSlide, setCurrentSlide] = useState(0); const [currentSlide, setCurrentSlide] = useState(0);
const [isFullscreen, setIsFullscreen] = useState(false); const [isFullscreen, setIsFullscreen] = useState(false);
const [isAutoPlaying, setIsAutoPlaying] = useState(false); const [isAutoPlaying, setIsAutoPlaying] = useState(false);
const [showAdvanced, setShowAdvanced] = useState(false); const [showAdvanced, setShowAdvanced] = useState(false);
const [attachedFiles, setAttachedFiles] = useState<AttachedFile[]>([]); const [attachedFiles, setAttachedFiles] = useState<AttachedFile[]>([]);
const [isDragOver, setIsDragOver] = useState(false); const [isDragOver, setIsDragOver] = useState(false);
const [uploadProgress, setUploadProgress] = useState<string | null>(null); const [uploadProgress, setUploadProgress] = useState<string | null>(null);
const slideContainerRef = useRef<HTMLDivElement>(null); const slideContainerRef = useRef<HTMLDivElement>(null);
const autoPlayRef = useRef<NodeJS.Timeout | null>(null); const autoPlayRef = useRef<NodeJS.Timeout | null>(null);
const fileInputRef = useRef<HTMLInputElement>(null); const fileInputRef = useRef<HTMLInputElement>(null);
const selectedModel = selectedModels[selectedProvider]; const selectedModel = selectedModels[selectedProvider];
const models = availableModels[selectedProvider] || modelAdapter.getAvailableModels(selectedProvider); const models = availableModels[selectedProvider] || modelAdapter.getAvailableModels(selectedProvider);
useEffect(() => { useEffect(() => {
if (typeof window !== "undefined") { if (typeof window !== "undefined") {
loadAvailableModels(); loadAvailableModels();
const saved = localStorage.getItem("promptarch-api-keys"); const saved = localStorage.getItem("promptarch-api-keys");
@@ -152,9 +165,9 @@ useEffect(() => {
} }
} }
} }
}, [selectedProvider]); }, [selectedProvider]);
useEffect(() => { useEffect(() => {
if (isAutoPlaying && slidesPresentation?.slides) { if (isAutoPlaying && slidesPresentation?.slides) {
autoPlayRef.current = setInterval(() => { autoPlayRef.current = setInterval(() => {
setCurrentSlide((prev) => setCurrentSlide((prev) =>
@@ -167,9 +180,9 @@ useEffect(() => {
clearInterval(autoPlayRef.current); clearInterval(autoPlayRef.current);
} }
}; };
}, [isAutoPlaying, slidesPresentation?.slides?.length]); }, [isAutoPlaying, slidesPresentation?.slides?.length]);
const loadAvailableModels = async () => { const loadAvailableModels = async () => {
const fallbackModels = modelAdapter.getAvailableModels(selectedProvider); const fallbackModels = modelAdapter.getAvailableModels(selectedProvider);
setAvailableModels(selectedProvider, fallbackModels); setAvailableModels(selectedProvider, fallbackModels);
@@ -181,10 +194,10 @@ const loadAvailableModels = async () => {
} catch (error) { } catch (error) {
console.error("Failed to load models:", error); console.error("Failed to load models:", error);
} }
}; };
// Extract colors from image // Extract colors from image
const extractColorsFromImage = (file: File): Promise<string[]> => { const extractColorsFromImage = (file: File): Promise<string[]> => {
return new Promise((resolve) => { return new Promise((resolve) => {
const img = document.createElement("img"); const img = document.createElement("img");
const canvas = document.createElement("canvas"); const canvas = document.createElement("canvas");
@@ -221,10 +234,10 @@ const extractColorsFromImage = (file: File): Promise<string[]> => {
img.src = URL.createObjectURL(file); img.src = URL.createObjectURL(file);
}); });
}; };
// Process uploaded file // Process uploaded file
const processFile = async (file: File): Promise<AttachedFile | null> => { const processFile = async (file: File): Promise<AttachedFile | null> => {
const id = Math.random().toString(36).substr(2, 9); const id = Math.random().toString(36).substr(2, 9);
const ext = file.name.split(".").pop()?.toLowerCase() || ""; const ext = file.name.split(".").pop()?.toLowerCase() || "";
@@ -276,17 +289,17 @@ const processFile = async (file: File): Promise<AttachedFile | null> => {
console.error("Error processing file:", err); console.error("Error processing file:", err);
return attachedFile; return attachedFile;
} }
}; };
const handleFileDrop = useCallback(async (e: React.DragEvent) => { const handleFileDrop = useCallback(async (e: React.DragEvent) => {
e.preventDefault(); e.preventDefault();
setIsDragOver(false); setIsDragOver(false);
const files = Array.from(e.dataTransfer.files); const files = Array.from(e.dataTransfer.files);
await handleFileUpload(files); await handleFileUpload(files);
}, []); }, []);
const handleFileUpload = async (files: File[]) => { const handleFileUpload = async (files: File[]) => {
setUploadProgress("Processing files..."); setUploadProgress("Processing files...");
const newFiles: AttachedFile[] = []; const newFiles: AttachedFile[] = [];
@@ -300,9 +313,9 @@ const handleFileUpload = async (files: File[]) => {
setAttachedFiles(prev => [...prev, ...newFiles]); setAttachedFiles(prev => [...prev, ...newFiles]);
setUploadProgress(null); setUploadProgress(null);
}; };
const removeFile = (id: string) => { const removeFile = (id: string) => {
setAttachedFiles(prev => { setAttachedFiles(prev => {
const file = prev.find(f => f.id === id); const file = prev.find(f => f.id === id);
if (file?.preview) { if (file?.preview) {
@@ -310,16 +323,16 @@ const removeFile = (id: string) => {
} }
return prev.filter(f => f.id !== id); return prev.filter(f => f.id !== id);
}); });
}; };
const getFileIcon = (type: string, name: string) => { const getFileIcon = (type: string, name: string) => {
if (name.match(/\.(png|jpg|jpeg|svg|webp|gif)$/i)) return <ImageIcon className="h-4 w-4" />; if (name.match(/\.(png|jpg|jpeg|svg|webp|gif)$/i)) return <ImageIcon className="h-4 w-4" />;
if (name.match(/\.(pdf|doc|docx|txt|md)$/i)) return <FileText className="h-4 w-4" />; if (name.match(/\.(pdf|doc|docx|txt|md)$/i)) return <FileText className="h-4 w-4" />;
if (name.match(/\.(pptx|ppt|key)$/i)) return <Presentation className="h-4 w-4" />; if (name.match(/\.(pptx|ppt|key)$/i)) return <Presentation className="h-4 w-4" />;
return <File className="h-4 w-4" />; return <File className="h-4 w-4" />;
}; };
const buildFileContext = (): string => { const buildFileContext = (): string => {
if (attachedFiles.length === 0) return ""; if (attachedFiles.length === 0) return "";
let context = "\n\n## ATTACHED FILES CONTEXT:\n"; let context = "\n\n## ATTACHED FILES CONTEXT:\n";
@@ -342,9 +355,9 @@ const buildFileContext = (): string => {
} }
return context; return context;
}; };
const parseSlides = (content: string): SlidesPresentation | null => { const parseSlides = (content: string): SlidesPresentation | null => {
try { try {
const jsonMatch = content.match(/```(?:json)?\s*([\s\S]*?)```/); const jsonMatch = content.match(/```(?:json)?\s*([\s\S]*?)```/);
const jsonStr = jsonMatch ? jsonMatch[1].trim() : content.trim(); const jsonStr = jsonMatch ? jsonMatch[1].trim() : content.trim();
@@ -377,9 +390,9 @@ const parseSlides = (content: string): SlidesPresentation | null => {
console.error("Failed to parse slides:", e); console.error("Failed to parse slides:", e);
} }
return null; return null;
}; };
const generateAnimatedHtml = (slide: any, index: number): string => { const generateAnimatedHtml = (slide: any, index: number): string => {
const themeConfig = THEMES.find(t => t.id === theme) || THEMES[1]; const themeConfig = THEMES.find(t => t.id === theme) || THEMES[1];
const [bg, accent, secondary, text] = themeConfig.colors; const [bg, accent, secondary, text] = themeConfig.colors;
const gradient = themeConfig.gradient; const gradient = themeConfig.gradient;
@@ -476,9 +489,9 @@ const generateAnimatedHtml = (slide: any, index: number): string => {
</style> </style>
</div> </div>
`; `;
}; };
const handleGenerate = async () => { const handleGenerate = async () => {
if (!topic.trim()) { if (!topic.trim()) {
setError("Please enter a topic for your presentation"); setError("Please enter a topic for your presentation");
return; return;
@@ -574,17 +587,17 @@ const handleGenerate = async () => {
} finally { } finally {
setProcessing(false); setProcessing(false);
} }
}; };
const handleCopy = async () => { const handleCopy = async () => {
if (slidesPresentation?.rawContent) { if (slidesPresentation?.rawContent) {
await navigator.clipboard.writeText(slidesPresentation.rawContent); await navigator.clipboard.writeText(slidesPresentation.rawContent);
setCopied(true); setCopied(true);
setTimeout(() => setCopied(false), 2000); setTimeout(() => setCopied(false), 2000);
} }
}; };
const handleDownloadHtml = () => { const handleDownloadHtml = () => {
if (!slidesPresentation) return; if (!slidesPresentation) return;
const themeConfig = THEMES.find(t => t.id === slidesPresentation.theme) || THEMES[1]; const themeConfig = THEMES.find(t => t.id === slidesPresentation.theme) || THEMES[1];
@@ -786,9 +799,9 @@ const handleDownloadHtml = () => {
a.download = `${slidesPresentation.title.replace(/[^a-z0-9]/gi, '_')}_animated_presentation.html`; a.download = `${slidesPresentation.title.replace(/[^a-z0-9]/gi, '_')}_animated_presentation.html`;
a.click(); a.click();
URL.revokeObjectURL(url); URL.revokeObjectURL(url);
}; };
const toggleFullscreen = () => { const toggleFullscreen = () => {
if (!slideContainerRef.current) return; if (!slideContainerRef.current) return;
if (!document.fullscreenElement) { if (!document.fullscreenElement) {
@@ -798,21 +811,21 @@ const toggleFullscreen = () => {
document.exitFullscreen(); document.exitFullscreen();
setIsFullscreen(false); setIsFullscreen(false);
} }
}; };
const goToSlide = (index: number) => { const goToSlide = (index: number) => {
if (slidesPresentation?.slides) { if (slidesPresentation?.slides) {
setCurrentSlide(Math.max(0, Math.min(index, slidesPresentation.slides.length - 1))); setCurrentSlide(Math.max(0, Math.min(index, slidesPresentation.slides.length - 1)));
} }
}; };
const formatFileSize = (bytes: number) => { const formatFileSize = (bytes: number) => {
if (bytes < 1024) return bytes + " B"; if (bytes < 1024) return bytes + " B";
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + " KB"; if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + " KB";
return (bytes / (1024 * 1024)).toFixed(1) + " MB"; return (bytes / (1024 * 1024)).toFixed(1) + " MB";
}; };
return ( return (
<div className="mx-auto grid max-w-7xl gap-4 lg:gap-6 grid-cols-1 xl:grid-cols-2 text-start"> <div className="mx-auto grid max-w-7xl gap-4 lg:gap-6 grid-cols-1 xl:grid-cols-2 text-start">
{/* Input Panel */} {/* Input Panel */}
<Card className="h-fit"> <Card className="h-fit">
@@ -1279,5 +1292,5 @@ return (
</CardContent> </CardContent>
</Card> </Card>
</div> </div>
); );
} }

View File

@@ -11,7 +11,16 @@ import { cn } from "@/lib/utils";
import { translations } from "@/lib/i18n/translations"; import { translations } from "@/lib/i18n/translations";
export default function UXDesignerPrompt() { export default function UXDesignerPrompt() {
const {
language, language,
currentPrompt,
enhancedPrompt,
selectedProvider,
selectedModels,
availableModels,
apiKeys,
isProcessing,
error,
setSelectedProvider, setSelectedProvider,
setCurrentPrompt, setCurrentPrompt,
setEnhancedPrompt, setEnhancedPrompt,
@@ -21,16 +30,16 @@ export default function UXDesignerPrompt() {
setSelectedModel, setSelectedModel,
} = useStore(); } = useStore();
const t = translations[language].uxDesigner; const t = translations[language].uxDesigner;
const common = translations[language].common; const common = translations[language].common;
const [copied, setCopied] = useState(false); const [copied, setCopied] = useState(false);
const [generatedPrompt, setGeneratedPrompt] = useState<string | null>(null); const [generatedPrompt, setGeneratedPrompt] = useState<string | null>(null);
const selectedModel = selectedModels[selectedProvider]; const selectedModel = selectedModels[selectedProvider];
const models = availableModels[selectedProvider] || modelAdapter.getAvailableModels(selectedProvider); const models = availableModels[selectedProvider] || modelAdapter.getAvailableModels(selectedProvider);
useEffect(() => { useEffect(() => {
if (typeof window !== "undefined") { if (typeof window !== "undefined") {
loadAvailableModels(); loadAvailableModels();
const saved = localStorage.getItem("promptarch-api-keys"); const saved = localStorage.getItem("promptarch-api-keys");
@@ -44,9 +53,9 @@ useEffect(() => {
} }
} }
} }
}, [selectedProvider]); }, [selectedProvider]);
const loadAvailableModels = async () => { const loadAvailableModels = async () => {
const fallbackModels = modelAdapter.getAvailableModels(selectedProvider); const fallbackModels = modelAdapter.getAvailableModels(selectedProvider);
setAvailableModels(selectedProvider, fallbackModels); setAvailableModels(selectedProvider, fallbackModels);
@@ -58,9 +67,9 @@ const loadAvailableModels = async () => {
} catch (error) { } catch (error) {
console.error("Failed to load models:", error); console.error("Failed to load models:", error);
} }
}; };
const handleGenerate = async () => { const handleGenerate = async () => {
if (!currentPrompt.trim()) { if (!currentPrompt.trim()) {
setError("Please enter an app description"); setError("Please enter an app description");
return; return;
@@ -98,24 +107,24 @@ const handleGenerate = async () => {
} finally { } finally {
setProcessing(false); setProcessing(false);
} }
}; };
const handleCopy = async () => { const handleCopy = async () => {
if (generatedPrompt) { if (generatedPrompt) {
await navigator.clipboard.writeText(generatedPrompt); await navigator.clipboard.writeText(generatedPrompt);
setCopied(true); setCopied(true);
setTimeout(() => setCopied(false), 2000); setTimeout(() => setCopied(false), 2000);
} }
}; };
const handleClear = () => { const handleClear = () => {
setCurrentPrompt(""); setCurrentPrompt("");
setGeneratedPrompt(null); setGeneratedPrompt(null);
setEnhancedPrompt(null); setEnhancedPrompt(null);
setError(null); setError(null);
}; };
return ( return (
<div className="mx-auto grid max-w-7xl gap-4 lg:gap-6 grid-cols-1 lg:grid-cols-2 text-start"> <div className="mx-auto grid max-w-7xl gap-4 lg:gap-6 grid-cols-1 lg:grid-cols-2 text-start">
<Card className="h-fit"> <Card className="h-fit">
<CardHeader className="p-4 lg:p-6 text-start"> <CardHeader className="p-4 lg:p-6 text-start">
@@ -245,5 +254,5 @@ return (
</CardContent> </CardContent>
</Card> </Card>
</div> </div>
); );
} }

View File

@@ -29,6 +29,7 @@ export const translations = {
title: "Prompt Enhancer", title: "Prompt Enhancer",
description: "Transform your simple ideas into professional, high-quality prompts", description: "Transform your simple ideas into professional, high-quality prompts",
placeholder: "Enter your prompt here...", placeholder: "Enter your prompt here...",
inputLabel: "Your Prompt",
enhancedTitle: "Enhanced Prompt", enhancedTitle: "Enhanced Prompt",
enhancedDesc: "Your prompt has been optimized for better AI performance", enhancedDesc: "Your prompt has been optimized for better AI performance",
}, },
@@ -150,6 +151,7 @@ export const translations = {
title: "Улучшение промптов", title: "Улучшение промптов",
description: "Превратите ваши простые идеи в профессиональные, качественные промпты", description: "Превратите ваши простые идеи в профессиональные, качественные промпты",
placeholder: "Введите ваш промпт здесь...", placeholder: "Введите ваш промпт здесь...",
inputLabel: "Ваш промпт",
enhancedTitle: "Улучшенный промпт", enhancedTitle: "Улучшенный промпт",
enhancedDesc: "Ваш промпт оптимизирован для лучшей работы ИИ", enhancedDesc: "Ваш промпт оптимизирован для лучшей работы ИИ",
}, },
@@ -271,6 +273,7 @@ export const translations = {
title: "משפר פרומפטים", title: "משפר פרומפטים",
description: "הפוך רעיונות פשוטים לפרומפטים מקצועיים באיכות גבוהה", description: "הפוך רעיונות פשוטים לפרומפטים מקצועיים באיכות גבוהה",
placeholder: "הזן את הפרומפט שלך כאן...", placeholder: "הזן את הפרומפט שלך כאן...",
inputLabel: "הפרומפט שלך",
enhancedTitle: "פרומפט משופר", enhancedTitle: "פרומפט משופר",
enhancedDesc: "הפרומפט שלך הותאם לביצועי בינה מלאכותית טובים יותר", enhancedDesc: "הפרומפט שלך הותאם לביצועי בינה מלאכותית טובים יותר",
}, },