diff --git a/components/layout/project-shell.tsx b/components/layout/project-shell.tsx index 3adb5e3..89eac67 100644 --- a/components/layout/project-shell.tsx +++ b/components/layout/project-shell.tsx @@ -1,7 +1,7 @@ "use client"; import { usePathname, useSearchParams, useRouter } from "next/navigation"; -import { ReactNode, Suspense } from "react"; +import { ReactNode, Suspense, useRef, useState, useCallback } from "react"; import Link from "next/link"; import { signOut, useSession } from "next-auth/react"; import { CooChat } from "./coo-chat"; @@ -24,7 +24,9 @@ interface ProjectShellProps { creationMode?: "fresh" | "chat-import" | "code-import" | "migration"; } -const CHAT_W = 320; +const CHAT_W_DEFAULT = 320; +const CHAT_W_MIN = 200; +const CHAT_W_MAX = 560; const SECTIONS = [ { id: "build", label: "Build", path: "build" }, @@ -61,6 +63,34 @@ function ProjectShellInner({ const router = useRouter(); const { data: session } = useSession(); + const [chatWidth, setChatWidth] = useState(CHAT_W_DEFAULT); + const dragging = useRef(false); + const startX = useRef(0); + const startW = useRef(0); + + const onDragStart = useCallback((e: React.MouseEvent) => { + dragging.current = true; + startX.current = e.clientX; + startW.current = chatWidth; + document.body.style.cursor = "col-resize"; + document.body.style.userSelect = "none"; + + const onMove = (e: MouseEvent) => { + if (!dragging.current) return; + const delta = e.clientX - startX.current; + setChatWidth(Math.min(CHAT_W_MAX, Math.max(CHAT_W_MIN, startW.current + delta))); + }; + const onUp = () => { + dragging.current = false; + document.body.style.cursor = ""; + document.body.style.userSelect = ""; + document.removeEventListener("mousemove", onMove); + document.removeEventListener("mouseup", onUp); + }; + document.addEventListener("mousemove", onMove); + document.addEventListener("mouseup", onUp); + }, [chatWidth]); + const activeSection = pathname?.includes("/build") ? "build" : pathname?.includes("/growth") ? "market" : @@ -98,7 +128,7 @@ function ProjectShellInner({ {/* Left — aligns with chat panel */}
+ {/* Drag handle */} +
(e.currentTarget.style.background = "#e8e4dc")} + onMouseLeave={e => (e.currentTarget.style.background = "transparent")} + /> + {/* Right: content */}
{children}