import { FileText, FileUp, History, Pencil } from "lucide-react" import type React from "react" import { useDictionary } from "@/hooks/use-dictionary" import { getAssetUrl } from "@/lib/base-path" import { cn } from "@/lib/utils" import { useChatEngine } from "./chat-engine" import { Composer } from "./composer" import { SessionMenu } from "./session-menu" interface Example { key: string title: string description: string /** Picture of the result (or of the input, for "replicate" examples) */ image?: string prompt: string /** Bundled file sent with the prompt; matches the cached example */ file?: { path: string; name: string; type: string } } async function loadExampleFile(file: NonNullable) { const response = await fetch(getAssetUrl(file.path)) const blob = await response.blob() return new File([blob], file.name, { type: file.type }) } /** One start-screen choice: a small picture, a title and one line */ function ExampleCard({ onClick, title, description, picture, plain, testId, }: { onClick: () => void title: string description: string picture: React.ReactNode /** An icon on a tinted tile instead of a diagram on paper */ plain?: boolean testId?: string }) { return ( ) } /** * Start screen over an empty canvas: one large message box and the cached * examples (they answer instantly without calling a model). */ export function LobbyHero({ onDrawYourself, onOpenFile, compact = false, }: { onDrawYourself: () => void onOpenFile: () => void /** Phone layout: no example pictures, tighter spacing */ compact?: boolean }) { const dict = useDictionary() const t = dict.lobby const engine = useChatEngine() // Prompts and file names must stay as they are: cached responses match them const examples: Example[] = [ { key: "paper", title: dict.examples.paperToDiagram, description: dict.examples.paperDescription, prompt: "Summarize this paper as a diagram", file: { path: "/chain-of-thought.txt", name: "chain-of-thought.txt", type: "text/plain", }, }, { key: "animated", title: dict.examples.animatedDiagram, description: dict.examples.animatedDescription, image: "/animated_connectors.svg", prompt: "Give me a **animated connector** diagram of transformer's architecture", }, { key: "aws", title: dict.examples.awsArchitecture, description: dict.examples.awsDescription, image: "/aws_demo.svg", prompt: "Replicate this in aws style", file: { path: "/architecture.png", name: "architecture.png", type: "image/png", }, }, { key: "flowchart", title: dict.examples.replicateFlowchart, description: dict.examples.replicateDescription, image: "/example.png", prompt: "Replicate this flowchart.", file: { path: "/example.png", name: "example.png", type: "image/png", }, }, { key: "cat", title: dict.examples.creativeDrawing, description: dict.examples.creativeDescription, image: "/cat_demo.svg", prompt: "Draw a cat for me", }, ] const pickExample = async (example: Example) => { engine.setInput(example.prompt) if (!example.file) { engine.setFiles([]) return } try { engine.setFiles([await loadExampleFile(example.file)]) } catch (error) { console.error(dict.errors.failedToLoadExample, error) } } return (

{t.title}

{t.lede}

{examples.map((example) => compact ? ( ) : ( pickExample(example)} title={example.title} description={example.description} testId={`example-${example.key}`} picture={ example.image ? ( // biome-ignore lint/performance/noImgElement: static preview ) : ( ) } plain={!example.image} /> ), )} {!compact && ( } plain /> )}

{dict.examples.cachedNote}

{engine.sessions.length > 0 && ( )} {compact && ( )}
) }