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 | |
| 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')
| -rw-r--r-- | apps/web/src/components/editor-header.tsx | 17 | ||||
| -rw-r--r-- | apps/web/src/components/editor/project-name-editor.tsx | 110 |
2 files changed, 120 insertions, 7 deletions
diff --git a/apps/web/src/components/editor-header.tsx b/apps/web/src/components/editor-header.tsx index c6cecbe8..6f9f0b2f 100644 --- a/apps/web/src/components/editor-header.tsx +++ b/apps/web/src/components/editor-header.tsx @@ -6,6 +6,7 @@ import { ChevronLeft, Download } from "lucide-react"; import { useProjectStore } from "@/stores/project-store";
import { useTimelineStore } from "@/stores/timeline-store";
import { HeaderBase } from "./header-base";
+import { ProjectNameEditor } from "./editor/project-name-editor";
export function EditorHeader() {
const { activeProject } = useProjectStore();
@@ -24,13 +25,15 @@ export function EditorHeader() { };
const leftContent = (
- <Link
- href="/"
- className="font-medium tracking-tight flex items-center gap-2 hover:opacity-80 transition-opacity"
- >
- <ChevronLeft className="h-4 w-4" />
- <span className="text-sm">{activeProject?.name || "Loading..."}</span>
- </Link>
+ <div className="flex items-center gap-2">
+ <Link
+ href="/"
+ className="font-medium tracking-tight flex items-center gap-2 hover:opacity-80 transition-opacity"
+ >
+ <ChevronLeft className="h-4 w-4" />
+ </Link>
+ <ProjectNameEditor />
+ </div>
);
const centerContent = (
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 |
