diff --git a/app-preview-awaiting.png b/app-preview-awaiting.png new file mode 100644 index 0000000000..d62d670c7c Binary files /dev/null and b/app-preview-awaiting.png differ diff --git a/app-preview-completed.png b/app-preview-completed.png new file mode 100644 index 0000000000..b58a127754 Binary files /dev/null and b/app-preview-completed.png differ diff --git a/app-preview-current.png b/app-preview-current.png new file mode 100644 index 0000000000..fce343386e Binary files /dev/null and b/app-preview-current.png differ diff --git a/app-preview-full.png b/app-preview-full.png new file mode 100644 index 0000000000..0be1f673c3 Binary files /dev/null and b/app-preview-full.png differ diff --git a/app-preview-pending.png b/app-preview-pending.png new file mode 100644 index 0000000000..eb6771e60c Binary files /dev/null and b/app-preview-pending.png differ diff --git a/app-preview-plan-ready.png b/app-preview-plan-ready.png new file mode 100644 index 0000000000..e614338535 Binary files /dev/null and b/app-preview-plan-ready.png differ diff --git a/apps/landing/src/components/AppPreview/AppPreview.tsx b/apps/landing/src/components/AppPreview/AppPreview.tsx deleted file mode 100644 index a0b646d6c6..0000000000 --- a/apps/landing/src/components/AppPreview/AppPreview.tsx +++ /dev/null @@ -1,483 +0,0 @@ -"use client"; - -import { useMemo, useState } from "react"; -import { - ArrowDownIcon, - ArrowDownUpIcon, - ChevronDownIcon, - ChevronRightIcon, - CornerDownLeftIcon, - EyeIcon, - FolderIcon, - GitBranchIcon, - GlobeIcon, - ImageIcon, - LockIcon, - PencilIcon, - PlusIcon, - SearchIcon, - ShieldIcon, - TerminalIcon, - WrenchIcon, - ZapIcon, -} from "lucide-react"; -import { - ACCESS_LABELS, - MODELS, - previewProjects, - previewThreads, - previewTurns, - type PreviewAccessMode, - type PreviewTurn, -} from "./data"; - -type ToolCallKind = "command" | "read" | "edit" | "search" | "fetch"; - -const TOOL_ICONS: Record = { - command: TerminalIcon, - read: EyeIcon, - edit: PencilIcon, - search: SearchIcon, - fetch: GlobeIcon, -}; - -const ACCESS_ICONS: Record = { - "approval-required": ShieldIcon, - "auto-accept-edits": LockIcon, - "full-access": ZapIcon, -}; - -const ACCESS_ACCENTS: Record = { - "approval-required": "text-sunbyte", - "auto-accept-edits": "text-curious-sky", - "full-access": "text-rebel-mint", -}; - -const MODEL_DOT_BG: Record<"fresh-syntax" | "rebel-mint" | "dream-shift" | "curious-sky", string> = - { - "fresh-syntax": "bg-fresh-syntax", - "rebel-mint": "bg-rebel-mint", - "dream-shift": "bg-dream-shift", - "curious-sky": "bg-curious-sky", - }; - -function ProjectIcon({ icon }: { icon: "marcode" | "round" | "lawn" | "folder" }) { - if (icon === "marcode") { - return ( - - - M - - - ); - } - if (icon === "round") { - return ( - - - - ); - } - if (icon === "lawn") { - return ( - - - - - - ); - } - return ( - - - - ); -} - -function ToolCallRow({ call }: { call: { kind: ToolCallKind; heading: string; preview: string } }) { - const Icon = TOOL_ICONS[call.kind]; - return ( -
- -
-
{call.heading}
-
{call.preview}
-
-
- ); -} - -function TurnView({ turn }: { turn: PreviewTurn }) { - if (turn.type === "user") { - return ( -
-
- {turn.text} -
-
- ); - } - - if (turn.type === "tool") { - return ( -
- - - -
-
{turn.title}
-
- {turn.calls.map((call, i) => ( - - ))} -
-
-
- ); - } - - return ( -
- - - M - - -
- {turn.text} -
-
- ); -} - -function StatusDot({ status }: { status: "Working" | "Completed" }) { - if (status === "Working") { - return ( - - - - - ); - } - return ; -} - -function PopoverButton({ - label, - value, - icon, - accent, -}: { - label: string; - value: string; - icon?: React.ReactNode; - accent?: string; -}) { - return ( - - ); -} - -export function AppPreview() { - const [activeThreadId, setActiveThreadId] = useState(previewThreads[0]!.id); - const [activeModel, setActiveModel] = useState(MODELS[0]!.model); - const [collapsedProjects, setCollapsedProjects] = useState>(new Set()); - - const activeThread = useMemo( - () => previewThreads.find((t) => t.id === activeThreadId) ?? previewThreads[0]!, - [activeThreadId], - ); - const activeTurns = previewTurns[activeThreadId] ?? []; - const AccessIcon = ACCESS_ICONS[activeThread.access]; - const accessAccent = ACCESS_ACCENTS[activeThread.access]; - - const modelMeta = MODELS.find((m) => m.model === activeModel) ?? MODELS[0]!; - - const toggleProject = (projectId: string) => { - setCollapsedProjects((prev) => { - const next = new Set(prev); - if (next.has(projectId)) next.delete(projectId); - else next.add(projectId); - return next; - }); - }; - - return ( -
- {/* Decorative glow */} -
-
-
-
- -
-
- {/* ── Sidebar ─────────────────────────────────────────── */} - - - {/* ── Main pane ───────────────────────────────────────── */} -
- {/* Header */} -
-
-
- {activeThread.title} -
-
- p.id === activeThread.projectId)?.icon ?? "folder" - } - /> - {previewProjects.find((p) => p.id === activeThread.projectId)?.title} - · - {activeThread.age} -
-
- {activeThread.status === "Working" ? ( - - - Working - - ) : activeThread.status === "Completed" ? ( - - - Completed - - ) : null} -
- - {/* Timeline */} -
-
- {activeTurns.length === 0 ? ( -
- Send a prompt to begin a new turn. -
- ) : ( - activeTurns.map((turn, i) => ) - )} - {activeThread.status === "Working" && ( -
- - Working... -
- )} -
-
- - {/* Composer */} -
-
-