"use client"; import { use, useState, useEffect } from "react"; import { Card } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { Palette, Plus, MessageSquare, History, Loader2, CheckCircle2, Circle, Clock, Sparkles, ExternalLink, } from "lucide-react"; import { Separator } from "@/components/ui/separator"; import Link from "next/link"; import { toast } from "sonner"; import { TreeView, TreeNode } from "@/components/ui/tree-view"; import { CollapsibleSidebar } from "@/components/ui/collapsible-sidebar"; interface WorkItem { id: string; title: string; path: string; status: "built" | "in_progress" | "missing"; state?: "draft" | "final"; category: string; priority: string; startDate: string | null; endDate: string | null; sessionsCount: number; commitsCount: number; estimatedCost?: number; requirements: Array<{ id: number; text: string; status: string; }>; versionCount?: number; messageCount?: number; } export default function DesignPage({ params, }: { params: Promise<{ workspace: string; projectId: string }>; }) { const { workspace, projectId } = use(params); // Helper function to count nodes by status recursively const countNodesByStatus = (node: TreeNode, status: string): number => { let count = node.status === status ? 1 : 0; if (node.children) { count += node.children.reduce((acc, child) => acc + countNodesByStatus(child, status), 0); } return count; }; const [workItems, setWorkItems] = useState([]); const [loading, setLoading] = useState(true); const [filterState, setFilterState] = useState<"all" | "draft" | "final">("all"); const [selectedItem, setSelectedItem] = useState(null); const [selectedTreeNodeId, setSelectedTreeNodeId] = useState(null); // Sample tree structure - will be populated from AI-generated data const [treeData] = useState([ { id: "navigation", label: "Navigation", children: [ { id: "sidebar", label: "Sidebar", status: "in_progress", children: [ { id: "dashboard", label: "Dashboard", status: "built", metadata: { sessionsCount: 12, commitsCount: 5 } }, { id: "projects", label: "Projects", status: "in_progress", metadata: { sessionsCount: 8, commitsCount: 3 } }, { id: "account", label: "Account", status: "missing" }, ], }, { id: "topnav", label: "Top Nav", status: "built", children: [ { id: "search", label: "Search", status: "built", metadata: { sessionsCount: 6, commitsCount: 2 } }, { id: "notifications", label: "Notifications", status: "built", metadata: { sessionsCount: 4, commitsCount: 1 } }, ], }, ], }, { id: "site", label: "Site", children: [ { id: "home", label: "Home", status: "built", children: [ { id: "hero", label: "Hero", status: "built", metadata: { sessionsCount: 10, commitsCount: 4 } }, { id: "features", label: "Features", status: "built", metadata: { sessionsCount: 15, commitsCount: 6 } }, { id: "testimonials", label: "Testimonials", status: "in_progress", metadata: { sessionsCount: 3, commitsCount: 1 } }, { id: "cta", label: "CTA", status: "built", metadata: { sessionsCount: 5, commitsCount: 2 } }, ], }, { id: "blog", label: "Blog", status: "missing", children: [ { id: "post-list", label: "Post List", status: "missing" }, { id: "post-page", label: "Post Page", status: "missing" }, ], }, { id: "pricing", label: "Pricing", status: "built", metadata: { sessionsCount: 7, commitsCount: 3 }, }, ], }, { id: "onboarding", label: "Onboarding", children: [ { id: "signup", label: "Signup", status: "built", metadata: { sessionsCount: 9, commitsCount: 4 } }, { id: "magic-link", label: "Magic Link Confirmation", status: "in_progress", metadata: { sessionsCount: 2, commitsCount: 1 } }, { id: "welcome", label: "Welcome Tour", status: "missing" }, ], }, ]); useEffect(() => { loadDesignItems(); }, [projectId]); const loadDesignItems = async () => { try { setLoading(true); const response = await fetch(`/api/projects/${projectId}/timeline-view`); if (response.ok) { const data = await response.json(); // Filter for design/user-facing items only const designItems = data.workItems.filter((item: WorkItem) => isTouchpoint(item) ); setWorkItems(designItems); } } catch (error) { console.error("Error loading design items:", error); toast.error("Failed to load design items"); } finally { setLoading(false); } }; const isTouchpoint = (item: WorkItem): boolean => { const path = item.path.toLowerCase(); const title = item.title.toLowerCase(); // Exclude APIs and backend systems if (path.startsWith('/api/')) return false; if (title.includes(' api') || title.includes('api ')) return false; // Exclude pure auth infrastructure (OAuth endpoints) if (path.includes('oauth') && !path.includes('button') && !path.includes('signin')) return false; // Include everything else - screens, pages, flows, etc. return true; }; const toggleState = async (itemId: string, newState: "draft" | "final") => { try { // TODO: Implement API call to update state setWorkItems(items => items.map(item => item.id === itemId ? { ...item, state: newState } : item ) ); toast.success(`Marked as ${newState}`); } catch (error) { toast.error("Failed to update state"); } }; const openInV0 = (item: WorkItem) => { // TODO: Integrate with v0 API toast.info("Opening in v0 designer..."); }; const getStatusIcon = (status: string) => { if (status === "built") return ; if (status === "in_progress") return ; return ; }; const getStatusLabel = (status: string) => { if (status === "built") return "Done"; if (status === "in_progress") return "Started"; return "To-do"; }; const filteredItems = workItems.filter(item => { if (filterState === "all") return true; return item.state === filterState; }); return (
{/* Left Sidebar */}

Design Assets

{workItems.length}
{/* Tree View */} { setSelectedTreeNodeId(node.id); toast.info(`Selected: ${node.label}`); }} /> {/* Quick Stats at Bottom */}
Built {treeData.reduce((acc, node) => acc + countNodesByStatus(node, "built"), 0)}
In Progress {treeData.reduce((acc, node) => acc + countNodesByStatus(node, "in_progress"), 0)}
To Build {treeData.reduce((acc, node) => acc + countNodesByStatus(node, "missing"), 0)}
{/* Main Content */}
{/* Header */}

Design

User-facing screens, features, and design assets

{/* Filters */}
{filteredItems.length} items
{/* Work Items List */}
{loading ? (
) : filteredItems.length === 0 ? (

No design items yet

Design items are user-facing elements like screens and features

) : (
{filteredItems.map((item) => (
{getStatusIcon(item.status)}
{/* Title and Status */}

{item.title}

{getStatusLabel(item.status)} {item.state && ( {item.state === "final" ? "Final" : "Draft"} )}
{/* Path */}

{item.path}

{/* Stats */}
{item.sessionsCount} sessions {item.commitsCount} commits {item.estimatedCost && ( <> ${item.estimatedCost.toFixed(2)} )} {item.versionCount && ( <> {item.versionCount} versions )} {item.messageCount && ( <> {item.messageCount} messages )}
{/* Requirements Preview */} {item.requirements.length > 0 && (

{item.requirements.filter(r => r.status === "built").length} of{" "} {item.requirements.length} requirements complete

)}
{/* Actions */}
{/* State Toggle */} {item.state !== "final" && ( )} {item.state === "final" && ( )}
))}
)}
{/* End Main Content */}
); }