Spaces:
Running
Running
| import { useState, useEffect, useCallback } from 'react'; | |
| import { Wand2, Undo2 } from 'lucide-react'; | |
| import { Button } from '../ui/button'; | |
| interface PromptInputProps { | |
| value: string; | |
| onChange: (value: string) => void; | |
| } | |
| export default function PromptInput({ value, onChange }: PromptInputProps) { | |
| const [isEnhancing, setIsEnhancing] = useState(false); | |
| const [previousPrompt, setPreviousPrompt] = useState(''); | |
| const [isEnhanced, setIsEnhanced] = useState(false); | |
| const enhancePrompt = useCallback(async () => { | |
| if (!value.trim() || isEnhancing) return; | |
| setIsEnhancing(true); | |
| setPreviousPrompt(value); | |
| try { | |
| const response = await fetch('/api/enhance-prompt', { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| }, | |
| body: JSON.stringify({ prompt: value }), | |
| }); | |
| if (!response.ok) { | |
| throw new Error('Failed to enhance prompt'); | |
| } | |
| const data = await response.json(); | |
| onChange(data.enhancedPrompt); | |
| setIsEnhanced(true); | |
| } catch (error) { | |
| console.error('Error enhancing prompt:', error); | |
| } finally { | |
| setIsEnhancing(false); | |
| } | |
| }, [value, onChange]); | |
| const undoEnhance = useCallback(() => { | |
| onChange(previousPrompt); | |
| setIsEnhanced(false); | |
| }, [previousPrompt, onChange]); | |
| useEffect(() => { | |
| const handleKeyDown = (event: KeyboardEvent) => { | |
| if ((event.ctrlKey || event.metaKey) && event.key === 'i') { | |
| event.preventDefault(); | |
| enhancePrompt(); | |
| } | |
| }; | |
| document.addEventListener('keydown', handleKeyDown); | |
| return () => { | |
| document.removeEventListener('keydown', handleKeyDown); | |
| }; | |
| }, [enhancePrompt]); | |
| return ( | |
| <div className="flex flex-col w-full gap-2 px-4 py-3"> | |
| <div className="flex justify-between items-center"> | |
| <label htmlFor="prompt-input" className="text-[#141414] dark:text-white text-base font-medium leading-normal"> | |
| Prompt | |
| </label> | |
| <div className="flex gap-2"> | |
| {isEnhanced && ( | |
| <Button | |
| variant="ghost" | |
| size="icon" | |
| onClick={undoEnhance} | |
| title="Undo enhance" | |
| className="h-8 w-8" | |
| > | |
| <Undo2 className="h-4 w-4" /> | |
| </Button> | |
| )} | |
| <Button | |
| variant="ghost" | |
| size="icon" | |
| onClick={enhancePrompt} | |
| disabled={isEnhancing || !value.trim()} | |
| title="Enhance prompt (Ctrl+I / Cmd+I)" | |
| className="h-8 w-8" | |
| > | |
| <Wand2 className={`h-4 w-4 ${isEnhancing ? 'animate-pulse' : ''}`} /> | |
| </Button> | |
| </div> | |
| </div> | |
| <textarea | |
| id="prompt-input" | |
| value={value} | |
| onChange={(e) => onChange(e.target.value)} | |
| placeholder="Type your prompt here" | |
| className="w-full min-h-[150px] p-4 rounded-xl text-[#141414] dark:text-white focus:outline-none focus:ring-0 border-none bg-[#ededed] dark:bg-gray-900 placeholder:text-neutral-500 dark:placeholder:text-gray-400 text-base font-normal leading-normal resize-none" | |
| /> | |
| </div> | |
| ); | |
| } | |