Complete Stackless parity: Activity, Deploy, Settings, header desc

- Add project description line to project header (from productVision)
- Sidebar: add Activity nav item (Projects / Activity / Settings)
- New Activity page: timeline feed with type filters (Atlas/Builds/Deploys/You)
- New Activity layout using VIBNSidebar
- Rewrite Deploy tab: Project URLs, Custom Domain, Env Vars, Deploy History
  — fully Stackless style, real data from project API, no more MOCK_PROJECT
- Rewrite Project Settings tab: remove all Firebase refs (db, auth, Firestore)
  — General (name/description), Repo link, Collaborators, Export JSON/PDF,
  — Danger Zone with double-confirm delete
  — uses /api/projects/[id] PATCH for saves

Made-with: Cursor
This commit is contained in:
2026-03-02 16:33:09 -08:00
parent 59c8ec2e02
commit d60d300a64
7 changed files with 595 additions and 366 deletions

View File

@@ -49,12 +49,13 @@ export function VIBNSidebar({ workspace }: VIBNSidebarProps) {
// Derive active top-level section
const isProjects = !activeProjectId && (pathname?.includes("/projects") || pathname?.includes("/project"));
const isActivity = pathname?.includes("/activity");
const isSettings = pathname?.includes("/settings");
const isActivity = !activeProjectId && pathname?.includes("/activity");
const isSettings = !activeProjectId && pathname?.includes("/settings");
const topNavItems = [
{ id: "projects", label: "Projects", icon: "⌗", href: `/${workspace}/projects` },
{ id: "settings", label: "Settings", icon: "", href: `/${workspace}/settings` },
{ id: "projects", label: "Projects", icon: "⌗", href: `/${workspace}/projects` },
{ id: "activity", label: "Activity", icon: "", href: `/${workspace}/activity` },
{ id: "settings", label: "Settings", icon: "⚙", href: `/${workspace}/settings` },
];
const userInitial = session?.user?.name?.[0]?.toUpperCase()
@@ -106,7 +107,8 @@ export function VIBNSidebar({ workspace }: VIBNSidebarProps) {
{/* Top nav */}
<div style={{ padding: "4px 10px" }}>
{topNavItems.map((n) => {
const isActive = n.id === "projects" ? isProjects && !activeProjectId
const isActive = n.id === "projects" ? isProjects
: n.id === "activity" ? isActivity
: n.id === "settings" ? isSettings
: false;
return (