Files
vibn-frontend/components/layout/project-shell.tsx
2026-03-08 13:00:54 -07:00

84 lines
2.4 KiB
TypeScript

"use client";
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<string, string>;
createdAt?: string;
updatedAt?: string;
featureCount?: number;
creationMode?: "fresh" | "chat-import" | "code-import" | "migration";
}
const ALL_TABS = [
{ id: "overview", label: "Atlas", path: "overview" },
{ id: "prd", label: "PRD", path: "prd" },
{ id: "build", label: "Build", path: "build" },
{ id: "growth", label: "Growth", path: "growth" },
{ id: "assist", label: "Assist", path: "assist" },
{ id: "analytics", label: "Analytics", path: "analytics" },
];
function getTabsForMode(
mode: "fresh" | "chat-import" | "code-import" | "migration" = "fresh"
) {
switch (mode) {
case "code-import":
return ALL_TABS.filter(t => t.id !== "prd");
case "migration":
return ALL_TABS
.filter(t => t.id !== "prd")
.map(t => t.id === "overview" ? { ...t, label: "Migration Plan" } : t);
default:
return ALL_TABS;
}
}
export function ProjectShell({
children,
workspace,
projectId,
creationMode,
}: ProjectShellProps) {
const pathname = usePathname();
const TABS = getTabsForMode(creationMode);
const activeTab = TABS.find(t => pathname?.includes(`/${t.path}`))?.id ?? "overview";
return (
<>
<style>{`
@media (max-width: 768px) {
.vibn-left-sidebar { display: none !important; }
.vibn-page-content { padding-bottom: env(safe-area-inset-bottom); }
}
`}</style>
<div style={{ display: "flex", height: "100dvh", background: "#f6f4f0", overflow: "hidden" }}>
{/* Left sidebar — includes project tabs */}
<div className="vibn-left-sidebar" style={{ display: "flex" }}>
<VIBNSidebar workspace={workspace} tabs={TABS} activeTab={activeTab} />
</div>
{/* Page content — extends to the very top */}
<div className="vibn-page-content" style={{ flex: 1, overflow: "auto", minWidth: 0 }}>
{children}
</div>
</div>
<Toaster position="top-center" />
</>
);
}