diff --git a/frontend/src/components/DetailPanel.tsx b/frontend/src/components/DetailPanel.tsx index 8c32dbe..deb09c5 100644 --- a/frontend/src/components/DetailPanel.tsx +++ b/frontend/src/components/DetailPanel.tsx @@ -1,4 +1,4 @@ -import { useRef } from 'react' +import { useRef, useState, useEffect } from 'react' interface Clip { id: string @@ -32,10 +32,40 @@ const modelName = (modelId: string) => { export default function DetailPanel({ clip, onClose, onRename, onDelete, onUploadArtwork, onRemoveArtwork }: Props) { const artworkInputRef = useRef(null) - const handleRename = () => { - const newTitle = window.prompt('Rename track:', clip.title || '') - if (newTitle !== null) { - onRename(clip.id, newTitle) + const [isEditingTitle, setIsEditingTitle] = useState(false) + const [editTitle, setEditTitle] = useState(clip.title || '') + const titleInputRef = useRef(null) + + // Focus and select when entering edit mode + useEffect(() => { + if (isEditingTitle && titleInputRef.current) { + titleInputRef.current.focus() + titleInputRef.current.select() + } + }, [isEditingTitle]) + + const startEditing = () => { + setEditTitle(clip.title || '') + setIsEditingTitle(true) + } + + const saveTitle = () => { + if (editTitle.trim() !== (clip.title || '')) { + onRename(clip.id, editTitle.trim()) + } + setIsEditingTitle(false) + } + + const cancelEditing = () => { + setEditTitle(clip.title || '') + setIsEditingTitle(false) + } + + const handleTitleKeyDown = (e: React.KeyboardEvent) => { + if (e.key === 'Enter') { + saveTitle() + } else if (e.key === 'Escape') { + cancelEditing() } } @@ -152,20 +182,38 @@ export default function DetailPanel({ clip, onClose, onRename, onDelete, onUploa )} - {/* Title */} + {/* Title — inline editable */}
- + {!isEditingTitle && ( + + )}
-

- {clip.title || Untitled} -

+ {isEditingTitle ? ( + setEditTitle(e.target.value)} + onBlur={saveTitle} + onKeyDown={handleTitleKeyDown} + className="w-full bg-white/5 border border-lyria-accent/50 rounded-md px-3 py-2 text-white text-lg font-medium outline-none focus:border-lyria-accent focus:ring-1 focus:ring-lyria-accent/30 transition-all" + placeholder="Track title..." + /> + ) : ( +

+ {clip.title || Untitled} +

+ )}
{/* Prompt */}