"use client"; import Link from "next/link"; import { usePathname } from "next/navigation"; import { ReactNode } from "react"; import { VIBNSidebar } from "./vibn-sidebar"; import { Toaster } from "sonner"; interface ProjectShellProps { children: ReactNode; workspace: string; projectId: string; projectName: string; projectDescription?: string; projectStatus?: string; projectProgress?: number; discoveryPhase?: number; capturedData?: Record; createdAt?: string; updatedAt?: string; featureCount?: number; } const TABS = [ { id: "overview", label: "Atlas", path: "overview" }, { id: "prd", label: "PRD", path: "prd" }, { id: "design", label: "Design", path: "design" }, { id: "build", label: "Build", path: "build" }, { id: "deployment", label: "Launch", path: "deployment" }, { id: "grow", label: "Grow", path: "grow" }, { id: "insights", label: "Insights", path: "insights" }, { id: "settings", label: "Settings", path: "settings" }, ]; const DISCOVERY_PHASES = [ "Big Picture", "Users & Personas", "Features", "Business Model", "Screens", "Risks", ]; function timeAgo(dateStr?: string): string { if (!dateStr) return "—"; const date = new Date(dateStr); if (isNaN(date.getTime())) return "—"; const diff = (Date.now() - date.getTime()) / 1000; if (diff < 60) return "just now"; if (diff < 3600) return `${Math.floor(diff / 60)}m ago`; if (diff < 86400) return `${Math.floor(diff / 3600)}h ago`; const days = Math.floor(diff / 86400); if (days === 1) return "Yesterday"; if (days < 7) return `${days}d ago`; return new Date(dateStr).toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" }); } function SectionLabel({ children }: { children: ReactNode }) { return (
{children}
); } function StatusTag({ status }: { status?: string }) { const label = status === "live" ? "Live" : status === "building" ? "Building" : "Defining"; const color = status === "live" ? "#2e7d32" : status === "building" ? "#3d5afe" : "#9a7b3a"; const bg = status === "live" ? "#2e7d3210" : status === "building" ? "#3d5afe10" : "#d4a04a12"; return ( {label} ); } export function ProjectShell({ children, workspace, projectId, projectName, projectDescription, projectStatus, projectProgress, discoveryPhase = 0, capturedData = {}, createdAt, updatedAt, featureCount = 0, }: ProjectShellProps) { const pathname = usePathname(); const activeTab = TABS.find((t) => pathname?.includes(`/${t.path}`))?.id ?? "overview"; const progress = projectProgress ?? 0; const capturedEntries = Object.entries(capturedData); return ( <>
{/* Left sidebar */} {/* Main column */}
{/* Project header */}
{projectName[0]?.toUpperCase() ?? "P"}

{projectName}

{projectDescription && (

{projectDescription}

)}
{progress}%
{/* Tab bar */}
{TABS.map((t) => ( {t.label} ))}
{/* Page content */}
{children}
{/* Right panel */}
{/* Discovery phases */} Discovery {DISCOVERY_PHASES.map((phase, i) => { const isDone = i < discoveryPhase; const isActive = i === discoveryPhase; return (
{isDone ? "✓" : isActive ? "→" : i + 1}
{phase}
); })}
{/* Captured data */} Captured {capturedEntries.length > 0 ? ( capturedEntries.map(([k, v], i) => (
{k}
{v}
)) ) : (

Atlas will capture key details here as you chat.

)}
{/* Project info */} Project Info {[ { k: "Created", v: timeAgo(createdAt) }, { k: "Last active", v: timeAgo(updatedAt) }, { k: "Features", v: featureCount > 0 ? `${featureCount} defined` : "None yet" }, ].map((item, i) => (
{item.k}
{item.v}
))}
); }