"use client"; import * as React from "react"; import { Brain, EyeOff, Trophy, X } from "lucide-react"; import { ProviderIcon } from "@/components/brand/provider-icon"; import { Badge } from "@/components/ui/badge"; import { SimpleMarkdown } from "@/components/markdown/simple-markdown"; import { useIsMobile, useSnapCarousel } from "@/lib/client/hooks"; import type { ArenaShareSnapshot } from "@/lib/arena/export"; import type { LiveMetrics } from "@/lib/arena/metrics"; import { providerName } from "@/lib/client/providers"; import { cn } from "@/lib/utils"; import { ModelTabs } from "./model-tabs"; import { MetricsStrip } from "./metrics-strip"; import { ComparisonTable } from "./comparison-table"; import { WinnerCard } from "./winner-card"; import type { ColumnStatus } from "./types"; function statusOf(s: string): ColumnStatus { return s === "complete" ? "done" : s === "error" ? "error" : "stopped"; } function metricsOf(r: ArenaShareSnapshot["responses"][number]): LiveMetrics { const out = r.usage?.outputTokens ?? null; const gen = typeof r.latencyMs === "number" ? Math.max(1, r.latencyMs - (r.ttftMs ?? 0)) : null; return { status: statusOf(r.status), elapsedMs: r.latencyMs ?? 0, ttftMs: r.ttftMs, inputTokens: r.usage?.inputTokens ?? null, outputTokens: out, reasoningTokens: r.usage?.reasoningTokens ?? null, cachedTokens: null, tokensPerSecond: out && gen ? Math.round((out / gen) * 1000) : null, costUsd: r.costUsd, exact: true }; } const GRID: Record = { 1: "md:grid-cols-1", 2: "md:grid-cols-2", 3: "md:grid-cols-2 xl:grid-cols-3", 4: "md:grid-cols-2" }; /** Public, read-only rendering of a shared Arena snapshot: swipe carousel on phones, grid on desktop. */ export function SharedArenaView({ snapshot: s }: { snapshot: ArenaShareSnapshot }) { const isMobile = useIsMobile(); const responses = s.responses; const { ref, index, scrollTo } = useSnapCarousel(responses.length); const winnerKey = s.winner?.responseId ?? null; const metrics = React.useMemo(() => responses.map(metricsOf), [responses]); const tabs = responses.map((r, i) => ({ key: r.id, name: r.displayName, provider: r.provider, status: statusOf(r.status), tokensPerSecond: metrics[i].tokensPerSecond, isWinner: r.id === winnerKey, blindIndex: i })); const rows = responses.map((r, i) => ({ key: r.id, name: r.displayName, provider: r.provider, blindIndex: i, metrics: metrics[i], criteriaWon: r.criteriaWon, isWinner: r.id === winnerKey })); return (
{isMobile ? ( <>
scrollTo(i)} />
{responses.map((r, i) => (
))}

Swipe to compare · {index + 1} / {responses.length}

) : (
{responses.map((r, i) => ( ))}
)} {s.winner ? r.id === s.winner!.responseId)?.displayName ?? s.winner.modelKey} provider={responses.find((r) => r.id === s.winner!.responseId)?.provider ?? null} /> : null}
); } function ResponseCard({ r, metrics, isWinner }: { r: ArenaShareSnapshot["responses"][number]; metrics: LiveMetrics; isWinner: boolean }) { return (

{r.displayName}

{providerName(r.provider)}

{isWinner ? ( Winner ) : null} {r.criteriaWon.length && !isWinner ? {r.criteriaWon.length} vote{r.criteriaWon.length === 1 ? "" : "s"} : null}
{r.reasoning ? (
Reasoning Show Hide
{r.reasoning}
) : null} {r.error ? (
{r.error.message}
{r.error.code}
) : null} {r.content ? {r.content} : !r.error ?

{r.status === "stopped" ? "Stopped before any output." : "Empty response."}

: null}
); } export function BlindNotice() { return (

Blind Arena — identities were hidden until the vote

); }