diff options
| author | iza <59828082+izadoesdev@users.noreply.github.com> | 2025-06-25 08:31:24 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-25 08:31:24 +0300 |
| commit | 3989da93c379e319c02d47bac093e6c933e5adfe (patch) | |
| tree | 9cfdbb23fedddd365f3024b338811ca4de9df3ed /apps/web/src/components/editor | |
| parent | 402b004ef3ee61c6bb58589527b27376ecf9bada (diff) | |
| parent | 411a9a5f1cdb4b52c65f4a1344c9be7694d130d7 (diff) | |
| download | opencut-3989da93c379e319c02d47bac093e6c933e5adfe.tar.gz | |
Merge pull request #81 from pulkitgarg04/feature/project-name-editing
feature: add project name editing functionality
Diffstat (limited to 'apps/web/src/components/editor')
| -rw-r--r-- | apps/web/src/components/editor/project-name-editor.tsx | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/apps/web/src/components/editor/project-name-editor.tsx b/apps/web/src/components/editor/project-name-editor.tsx new file mode 100644 index 00000000..aa0141ae --- /dev/null +++ b/apps/web/src/components/editor/project-name-editor.tsx @@ -0,0 +1,110 @@ +"use client"; + +import { useState, useRef, useEffect } from "react"; +import { Input } from "../ui/input"; +import { useProjectStore } from "@/stores/project-store"; +import { Edit2, Check, X } from "lucide-react"; +import { Button } from "../ui/button"; + +interface ProjectNameEditorProps { + className?: string; +} + +export function ProjectNameEditor({ className }: ProjectNameEditorProps) { + const { activeProject, updateProjectName } = useProjectStore(); + const [isEditing, setIsEditing] = useState(false); + const [editValue, setEditValue] = useState(""); + const inputRef = useRef<HTMLInputElement>(null); + + useEffect(() => { + if (activeProject) { + setEditValue(activeProject.name); + } + }, [activeProject]); + + useEffect(() => { + if (isEditing && inputRef.current) { + inputRef.current.focus(); + inputRef.current.select(); + } + }, [isEditing]); + + const handleStartEdit = () => { + if (activeProject) { + setEditValue(activeProject.name); + setIsEditing(true); + } + }; + + const handleSave = () => { + if (editValue.trim()) { + updateProjectName(editValue.trim()); + setIsEditing(false); + } + }; + + const handleCancel = () => { + if (activeProject) { + setEditValue(activeProject.name); + } + setIsEditing(false); + }; + + const handleKeyDown = (e: React.KeyboardEvent) => { + if (e.key === "Enter") { + handleSave(); + } else if (e.key === "Escape") { + handleCancel(); + } + }; + + if (!activeProject) { + return <span className="text-sm text-muted-foreground">Loading...</span>; + } + + if (isEditing) { + return ( + <div className="flex items-center gap-1"> + <Input + ref={inputRef} + value={editValue} + onChange={(e) => setEditValue(e.target.value)} + onKeyDown={handleKeyDown} + className="h-7 text-sm px-3 py-1 min-w-[200px]" + size={1} + /> + <Button + size="sm" + variant="text" + onClick={handleSave} + className="h-7 w-7 p-0" + disabled={!editValue.trim()} + > + <Check className="h-3 w-3" /> + </Button> + <Button + size="sm" + variant="text" + onClick={handleCancel} + className="h-7 w-7 p-0" + > + <X className="h-3 w-3" /> + </Button> + </div> + ); + } + + return ( + <div className="flex items-center gap-1 group"> + <span className="text-sm font-medium">{activeProject.name}</span> + <Button + size="sm" + variant="text" + onClick={handleStartEdit} + className="h-6 w-6 p-0 opacity-0 group-hover:opacity-100 transition-opacity" + > + <Edit2 className="h-3 w-3" /> + </Button> + </div> + ); +}
\ No newline at end of file |
