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:
@@ -11,7 +11,16 @@ import { cn } from "@/lib/utils";
|
||||
import { translations } from "@/lib/i18n/translations";
|
||||
|
||||
export default function ActionPlanGenerator() {
|
||||
const {
|
||||
language,
|
||||
currentPrompt,
|
||||
actionPlan,
|
||||
selectedProvider,
|
||||
selectedModels,
|
||||
availableModels,
|
||||
apiKeys,
|
||||
isProcessing,
|
||||
error,
|
||||
setCurrentPrompt,
|
||||
setSelectedProvider,
|
||||
setActionPlan,
|
||||
@@ -21,15 +30,15 @@ export default function ActionPlanGenerator() {
|
||||
setSelectedModel,
|
||||
} = useStore();
|
||||
|
||||
const t = translations[language].actionPlan;
|
||||
const common = translations[language].common;
|
||||
const t = translations[language].actionPlan;
|
||||
const common = translations[language].common;
|
||||
|
||||
const [copied, setCopied] = useState(false);
|
||||
const [copied, setCopied] = useState(false);
|
||||
|
||||
const selectedModel = selectedModels[selectedProvider];
|
||||
const models = availableModels[selectedProvider] || modelAdapter.getAvailableModels(selectedProvider);
|
||||
const selectedModel = selectedModels[selectedProvider];
|
||||
const models = availableModels[selectedProvider] || modelAdapter.getAvailableModels(selectedProvider);
|
||||
|
||||
useEffect(() => {
|
||||
useEffect(() => {
|
||||
if (typeof window !== "undefined") {
|
||||
loadAvailableModels();
|
||||
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);
|
||||
setAvailableModels(selectedProvider, fallbackModels);
|
||||
|
||||
@@ -58,9 +67,9 @@ const loadAvailableModels = async () => {
|
||||
} catch (error) {
|
||||
console.error("Failed to load models:", error);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const handleGenerate = async () => {
|
||||
const handleGenerate = async () => {
|
||||
if (!currentPrompt.trim()) {
|
||||
setError("Please enter PRD or project requirements");
|
||||
return;
|
||||
@@ -111,17 +120,17 @@ const handleGenerate = async () => {
|
||||
} finally {
|
||||
setProcessing(false);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const handleCopy = async () => {
|
||||
const handleCopy = async () => {
|
||||
if (actionPlan?.rawContent) {
|
||||
await navigator.clipboard.writeText(actionPlan.rawContent);
|
||||
setCopied(true);
|
||||
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">
|
||||
<Card className="h-fit">
|
||||
<CardHeader className="p-4 lg:p-6 text-start">
|
||||
@@ -257,5 +266,5 @@ return (
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
@@ -394,10 +394,9 @@ export default function GoogleAdsGenerator() {
|
||||
default:
|
||||
return <pre className="whitespace-pre-wrap text-xs">{googleAdsResult.rawContent}</pre>;
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const renderMagicWandSectionContent = (sectionId: string) => {
|
||||
const renderMagicWandSectionContent = (sectionId: string) => {
|
||||
if (!magicWandResult) return null;
|
||||
|
||||
switch (sectionId) {
|
||||
@@ -546,10 +545,10 @@ const renderMagicWandSectionContent = (sectionId: string) => {
|
||||
default:
|
||||
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">
|
||||
<Card className="h-fit">
|
||||
<CardHeader className="p-4 lg:p-6 text-start">
|
||||
@@ -797,5 +796,5 @@ return (
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,16 @@ import { cn } from "@/lib/utils";
|
||||
import { translations } from "@/lib/i18n/translations";
|
||||
|
||||
export default function PromptEnhancer() {
|
||||
const {
|
||||
language,
|
||||
currentPrompt,
|
||||
enhancedPrompt,
|
||||
selectedProvider,
|
||||
selectedModels,
|
||||
availableModels,
|
||||
apiKeys,
|
||||
isProcessing,
|
||||
error,
|
||||
setSelectedProvider,
|
||||
setCurrentPrompt,
|
||||
setEnhancedPrompt,
|
||||
@@ -21,15 +30,15 @@ export default function PromptEnhancer() {
|
||||
setSelectedModel,
|
||||
} = useStore();
|
||||
|
||||
const t = translations[language].promptEnhancer;
|
||||
const common = translations[language].common;
|
||||
const t = translations[language].promptEnhancer;
|
||||
const common = translations[language].common;
|
||||
|
||||
const [copied, setCopied] = useState(false);
|
||||
const [copied, setCopied] = useState(false);
|
||||
|
||||
const selectedModel = selectedModels[selectedProvider];
|
||||
const models = availableModels[selectedProvider] || modelAdapter.getAvailableModels(selectedProvider);
|
||||
const selectedModel = selectedModels[selectedProvider];
|
||||
const models = availableModels[selectedProvider] || modelAdapter.getAvailableModels(selectedProvider);
|
||||
|
||||
useEffect(() => {
|
||||
useEffect(() => {
|
||||
if (typeof window !== "undefined") {
|
||||
loadAvailableModels();
|
||||
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);
|
||||
setAvailableModels(selectedProvider, fallbackModels);
|
||||
|
||||
@@ -58,9 +67,9 @@ const loadAvailableModels = async () => {
|
||||
} catch (error) {
|
||||
console.error("Failed to load models:", error);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const handleEnhance = async () => {
|
||||
const handleEnhance = async () => {
|
||||
if (!currentPrompt.trim()) {
|
||||
setError("Please enter a prompt to enhance");
|
||||
return;
|
||||
@@ -96,23 +105,23 @@ const handleEnhance = async () => {
|
||||
} finally {
|
||||
setProcessing(false);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const handleCopy = async () => {
|
||||
const handleCopy = async () => {
|
||||
if (enhancedPrompt) {
|
||||
await navigator.clipboard.writeText(enhancedPrompt);
|
||||
setCopied(true);
|
||||
setTimeout(() => setCopied(false), 2000);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const handleClear = () => {
|
||||
const handleClear = () => {
|
||||
setCurrentPrompt("");
|
||||
setEnhancedPrompt(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">
|
||||
<Card className="h-fit">
|
||||
<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">
|
||||
<span className="flex items-center gap-2">
|
||||
<CheckCircle2 className="h-4 w-4 lg:h-5 lg:w-5 text-green-500" />
|
||||
{t.resultTitle}
|
||||
{t.enhancedTitle}
|
||||
</span>
|
||||
{enhancedPrompt && (
|
||||
<Button variant="ghost" size="icon" onClick={handleCopy} className="h-8 w-8 lg:h-9 lg:w-9">
|
||||
@@ -238,5 +247,5 @@ return (
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
@@ -108,36 +108,49 @@ const ACCEPTED_FILE_TYPES = {
|
||||
const ALL_ACCEPTED = Object.values(ACCEPTED_FILE_TYPES).flat().join(",");
|
||||
|
||||
export default function SlidesGenerator() {
|
||||
const {
|
||||
selectedProvider,
|
||||
selectedModels,
|
||||
availableModels,
|
||||
apiKeys,
|
||||
isProcessing,
|
||||
error,
|
||||
slidesPresentation,
|
||||
setSelectedProvider,
|
||||
setSlidesPresentation,
|
||||
setProcessing,
|
||||
setError,
|
||||
setAvailableModels,
|
||||
setSelectedModel,
|
||||
language: uiLanguage,
|
||||
} = useStore();
|
||||
|
||||
const t = translations[uiLanguage].slidesGen;
|
||||
const common = translations[uiLanguage].common;
|
||||
const t = translations[uiLanguage].slidesGen;
|
||||
const common = translations[uiLanguage].common;
|
||||
|
||||
const [topic, setTopic] = useState("");
|
||||
const [language, setLanguage] = useState("en");
|
||||
const [theme, setTheme] = useState("executive-dark");
|
||||
const [audience, setAudience] = useState("executives");
|
||||
const [organization, setOrganization] = useState("");
|
||||
const [slideCount, setSlideCount] = useState(10);
|
||||
const [animationStyle, setAnimationStyle] = useState("professional");
|
||||
const [copied, setCopied] = useState(false);
|
||||
const [currentSlide, setCurrentSlide] = useState(0);
|
||||
const [isFullscreen, setIsFullscreen] = useState(false);
|
||||
const [isAutoPlaying, setIsAutoPlaying] = useState(false);
|
||||
const [showAdvanced, setShowAdvanced] = useState(false);
|
||||
const [attachedFiles, setAttachedFiles] = useState<AttachedFile[]>([]);
|
||||
const [isDragOver, setIsDragOver] = useState(false);
|
||||
const [uploadProgress, setUploadProgress] = useState<string | null>(null);
|
||||
const slideContainerRef = useRef<HTMLDivElement>(null);
|
||||
const autoPlayRef = useRef<NodeJS.Timeout | null>(null);
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
const [topic, setTopic] = useState("");
|
||||
const [language, setLanguage] = useState("en");
|
||||
const [theme, setTheme] = useState("executive-dark");
|
||||
const [audience, setAudience] = useState("executives");
|
||||
const [organization, setOrganization] = useState("");
|
||||
const [slideCount, setSlideCount] = useState(10);
|
||||
const [animationStyle, setAnimationStyle] = useState("professional");
|
||||
const [copied, setCopied] = useState(false);
|
||||
const [currentSlide, setCurrentSlide] = useState(0);
|
||||
const [isFullscreen, setIsFullscreen] = useState(false);
|
||||
const [isAutoPlaying, setIsAutoPlaying] = useState(false);
|
||||
const [showAdvanced, setShowAdvanced] = useState(false);
|
||||
const [attachedFiles, setAttachedFiles] = useState<AttachedFile[]>([]);
|
||||
const [isDragOver, setIsDragOver] = useState(false);
|
||||
const [uploadProgress, setUploadProgress] = useState<string | null>(null);
|
||||
const slideContainerRef = useRef<HTMLDivElement>(null);
|
||||
const autoPlayRef = useRef<NodeJS.Timeout | null>(null);
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
const selectedModel = selectedModels[selectedProvider];
|
||||
const models = availableModels[selectedProvider] || modelAdapter.getAvailableModels(selectedProvider);
|
||||
const selectedModel = selectedModels[selectedProvider];
|
||||
const models = availableModels[selectedProvider] || modelAdapter.getAvailableModels(selectedProvider);
|
||||
|
||||
useEffect(() => {
|
||||
useEffect(() => {
|
||||
if (typeof window !== "undefined") {
|
||||
loadAvailableModels();
|
||||
const saved = localStorage.getItem("promptarch-api-keys");
|
||||
@@ -152,9 +165,9 @@ useEffect(() => {
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [selectedProvider]);
|
||||
}, [selectedProvider]);
|
||||
|
||||
useEffect(() => {
|
||||
useEffect(() => {
|
||||
if (isAutoPlaying && slidesPresentation?.slides) {
|
||||
autoPlayRef.current = setInterval(() => {
|
||||
setCurrentSlide((prev) =>
|
||||
@@ -167,9 +180,9 @@ useEffect(() => {
|
||||
clearInterval(autoPlayRef.current);
|
||||
}
|
||||
};
|
||||
}, [isAutoPlaying, slidesPresentation?.slides?.length]);
|
||||
}, [isAutoPlaying, slidesPresentation?.slides?.length]);
|
||||
|
||||
const loadAvailableModels = async () => {
|
||||
const loadAvailableModels = async () => {
|
||||
const fallbackModels = modelAdapter.getAvailableModels(selectedProvider);
|
||||
setAvailableModels(selectedProvider, fallbackModels);
|
||||
|
||||
@@ -181,10 +194,10 @@ const loadAvailableModels = async () => {
|
||||
} catch (error) {
|
||||
console.error("Failed to load models:", error);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Extract colors from image
|
||||
const extractColorsFromImage = (file: File): Promise<string[]> => {
|
||||
// Extract colors from image
|
||||
const extractColorsFromImage = (file: File): Promise<string[]> => {
|
||||
return new Promise((resolve) => {
|
||||
const img = document.createElement("img");
|
||||
const canvas = document.createElement("canvas");
|
||||
@@ -221,10 +234,10 @@ const extractColorsFromImage = (file: File): Promise<string[]> => {
|
||||
|
||||
img.src = URL.createObjectURL(file);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
// Process uploaded file
|
||||
const processFile = async (file: File): Promise<AttachedFile | null> => {
|
||||
// Process uploaded file
|
||||
const processFile = async (file: File): Promise<AttachedFile | null> => {
|
||||
const id = Math.random().toString(36).substr(2, 9);
|
||||
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);
|
||||
return attachedFile;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const handleFileDrop = useCallback(async (e: React.DragEvent) => {
|
||||
const handleFileDrop = useCallback(async (e: React.DragEvent) => {
|
||||
e.preventDefault();
|
||||
setIsDragOver(false);
|
||||
|
||||
const files = Array.from(e.dataTransfer.files);
|
||||
await handleFileUpload(files);
|
||||
}, []);
|
||||
}, []);
|
||||
|
||||
const handleFileUpload = async (files: File[]) => {
|
||||
const handleFileUpload = async (files: File[]) => {
|
||||
setUploadProgress("Processing files...");
|
||||
|
||||
const newFiles: AttachedFile[] = [];
|
||||
@@ -300,9 +313,9 @@ const handleFileUpload = async (files: File[]) => {
|
||||
|
||||
setAttachedFiles(prev => [...prev, ...newFiles]);
|
||||
setUploadProgress(null);
|
||||
};
|
||||
};
|
||||
|
||||
const removeFile = (id: string) => {
|
||||
const removeFile = (id: string) => {
|
||||
setAttachedFiles(prev => {
|
||||
const file = prev.find(f => f.id === id);
|
||||
if (file?.preview) {
|
||||
@@ -310,16 +323,16 @@ const removeFile = (id: string) => {
|
||||
}
|
||||
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(/\.(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" />;
|
||||
return <File className="h-4 w-4" />;
|
||||
};
|
||||
};
|
||||
|
||||
const buildFileContext = (): string => {
|
||||
const buildFileContext = (): string => {
|
||||
if (attachedFiles.length === 0) return "";
|
||||
|
||||
let context = "\n\n## ATTACHED FILES CONTEXT:\n";
|
||||
@@ -342,9 +355,9 @@ const buildFileContext = (): string => {
|
||||
}
|
||||
|
||||
return context;
|
||||
};
|
||||
};
|
||||
|
||||
const parseSlides = (content: string): SlidesPresentation | null => {
|
||||
const parseSlides = (content: string): SlidesPresentation | null => {
|
||||
try {
|
||||
const jsonMatch = content.match(/```(?:json)?\s*([\s\S]*?)```/);
|
||||
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);
|
||||
}
|
||||
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 [bg, accent, secondary, text] = themeConfig.colors;
|
||||
const gradient = themeConfig.gradient;
|
||||
@@ -476,9 +489,9 @@ const generateAnimatedHtml = (slide: any, index: number): string => {
|
||||
</style>
|
||||
</div>
|
||||
`;
|
||||
};
|
||||
};
|
||||
|
||||
const handleGenerate = async () => {
|
||||
const handleGenerate = async () => {
|
||||
if (!topic.trim()) {
|
||||
setError("Please enter a topic for your presentation");
|
||||
return;
|
||||
@@ -574,17 +587,17 @@ const handleGenerate = async () => {
|
||||
} finally {
|
||||
setProcessing(false);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const handleCopy = async () => {
|
||||
const handleCopy = async () => {
|
||||
if (slidesPresentation?.rawContent) {
|
||||
await navigator.clipboard.writeText(slidesPresentation.rawContent);
|
||||
setCopied(true);
|
||||
setTimeout(() => setCopied(false), 2000);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const handleDownloadHtml = () => {
|
||||
const handleDownloadHtml = () => {
|
||||
if (!slidesPresentation) return;
|
||||
|
||||
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.click();
|
||||
URL.revokeObjectURL(url);
|
||||
};
|
||||
};
|
||||
|
||||
const toggleFullscreen = () => {
|
||||
const toggleFullscreen = () => {
|
||||
if (!slideContainerRef.current) return;
|
||||
|
||||
if (!document.fullscreenElement) {
|
||||
@@ -798,21 +811,21 @@ const toggleFullscreen = () => {
|
||||
document.exitFullscreen();
|
||||
setIsFullscreen(false);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const goToSlide = (index: number) => {
|
||||
const goToSlide = (index: number) => {
|
||||
if (slidesPresentation?.slides) {
|
||||
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 * 1024) return (bytes / 1024).toFixed(1) + " KB";
|
||||
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">
|
||||
{/* Input Panel */}
|
||||
<Card className="h-fit">
|
||||
@@ -1279,5 +1292,5 @@ return (
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,16 @@ import { cn } from "@/lib/utils";
|
||||
import { translations } from "@/lib/i18n/translations";
|
||||
|
||||
export default function UXDesignerPrompt() {
|
||||
const {
|
||||
language,
|
||||
currentPrompt,
|
||||
enhancedPrompt,
|
||||
selectedProvider,
|
||||
selectedModels,
|
||||
availableModels,
|
||||
apiKeys,
|
||||
isProcessing,
|
||||
error,
|
||||
setSelectedProvider,
|
||||
setCurrentPrompt,
|
||||
setEnhancedPrompt,
|
||||
@@ -21,16 +30,16 @@ export default function UXDesignerPrompt() {
|
||||
setSelectedModel,
|
||||
} = useStore();
|
||||
|
||||
const t = translations[language].uxDesigner;
|
||||
const common = translations[language].common;
|
||||
const t = translations[language].uxDesigner;
|
||||
const common = translations[language].common;
|
||||
|
||||
const [copied, setCopied] = useState(false);
|
||||
const [generatedPrompt, setGeneratedPrompt] = useState<string | null>(null);
|
||||
const [copied, setCopied] = useState(false);
|
||||
const [generatedPrompt, setGeneratedPrompt] = useState<string | null>(null);
|
||||
|
||||
const selectedModel = selectedModels[selectedProvider];
|
||||
const models = availableModels[selectedProvider] || modelAdapter.getAvailableModels(selectedProvider);
|
||||
const selectedModel = selectedModels[selectedProvider];
|
||||
const models = availableModels[selectedProvider] || modelAdapter.getAvailableModels(selectedProvider);
|
||||
|
||||
useEffect(() => {
|
||||
useEffect(() => {
|
||||
if (typeof window !== "undefined") {
|
||||
loadAvailableModels();
|
||||
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);
|
||||
setAvailableModels(selectedProvider, fallbackModels);
|
||||
|
||||
@@ -58,9 +67,9 @@ const loadAvailableModels = async () => {
|
||||
} catch (error) {
|
||||
console.error("Failed to load models:", error);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const handleGenerate = async () => {
|
||||
const handleGenerate = async () => {
|
||||
if (!currentPrompt.trim()) {
|
||||
setError("Please enter an app description");
|
||||
return;
|
||||
@@ -98,24 +107,24 @@ const handleGenerate = async () => {
|
||||
} finally {
|
||||
setProcessing(false);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const handleCopy = async () => {
|
||||
const handleCopy = async () => {
|
||||
if (generatedPrompt) {
|
||||
await navigator.clipboard.writeText(generatedPrompt);
|
||||
setCopied(true);
|
||||
setTimeout(() => setCopied(false), 2000);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const handleClear = () => {
|
||||
const handleClear = () => {
|
||||
setCurrentPrompt("");
|
||||
setGeneratedPrompt(null);
|
||||
setEnhancedPrompt(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">
|
||||
<Card className="h-fit">
|
||||
<CardHeader className="p-4 lg:p-6 text-start">
|
||||
@@ -245,5 +254,5 @@ return (
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ export const translations = {
|
||||
title: "Prompt Enhancer",
|
||||
description: "Transform your simple ideas into professional, high-quality prompts",
|
||||
placeholder: "Enter your prompt here...",
|
||||
inputLabel: "Your Prompt",
|
||||
enhancedTitle: "Enhanced Prompt",
|
||||
enhancedDesc: "Your prompt has been optimized for better AI performance",
|
||||
},
|
||||
@@ -150,6 +151,7 @@ export const translations = {
|
||||
title: "Улучшение промптов",
|
||||
description: "Превратите ваши простые идеи в профессиональные, качественные промпты",
|
||||
placeholder: "Введите ваш промпт здесь...",
|
||||
inputLabel: "Ваш промпт",
|
||||
enhancedTitle: "Улучшенный промпт",
|
||||
enhancedDesc: "Ваш промпт оптимизирован для лучшей работы ИИ",
|
||||
},
|
||||
@@ -271,6 +273,7 @@ export const translations = {
|
||||
title: "משפר פרומפטים",
|
||||
description: "הפוך רעיונות פשוטים לפרומפטים מקצועיים באיכות גבוהה",
|
||||
placeholder: "הזן את הפרומפט שלך כאן...",
|
||||
inputLabel: "הפרומפט שלך",
|
||||
enhancedTitle: "פרומפט משופר",
|
||||
enhancedDesc: "הפרומפט שלך הותאם לביצועי בינה מלאכותית טובים יותר",
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user