import { useState } from "react"; import { useStore } from "../store/useStore"; import { downloadFile, type ToolCall } from "../api/client"; import { DownloadIcon } from "../components/Icon"; type TabId = "preview" | "code" | "logs"; /** Panneau droit : onglets Aperçu / Code / Logs. */ export function PreviewPanel() { const { previewPath, previewContent, messages, streamTools } = useStore(); const [tab, setTab] = useState("preview"); const [width, setWidth] = useState(() => { const saved = Number(window.localStorage.getItem("loki.preview.width")); return Number.isFinite(saved) && saved >= 300 ? saved : 452; }); const updateWidth = (next: number) => { const bounded = Math.max(300, Math.min(next, window.innerWidth - 520)); setWidth(bounded); window.localStorage.setItem("loki.preview.width", String(bounded)); }; const startResize = (event: React.PointerEvent) => { event.preventDefault(); const startX = event.clientX; const startWidth = width; const onMove = (move: PointerEvent) => updateWidth(startWidth + startX - move.clientX); const onUp = () => { window.removeEventListener("pointermove", onMove); window.removeEventListener("pointerup", onUp); }; window.addEventListener("pointermove", onMove); window.addEventListener("pointerup", onUp); }; const isHtml = previewPath ? /\.html?$/.test(previewPath) : false; // Journal d'activité : tous les appels d'outils de la session + en cours. const logs: ToolCall[] = [ ...messages.flatMap((m) => m.meta?.tools ?? []), ...streamTools, ]; return (
{ if (event.key === "ArrowLeft") updateWidth(width + 20); if (event.key === "ArrowRight") updateWidth(width - 20); }} className="absolute -left-[6px] top-0 z-20 h-full w-[9px] cursor-col-resize bg-transparent hover:bg-accent/50 focus:bg-accent/50 focus:outline-none" title="Glisser pour redimensionner" /> {/* Onglets */}
setTab("preview")}> Aperçu setTab("code")}> Code setTab("logs")}> Logs {logs.length}
{/* URL bar */}
🔒 {previewPath ? `workspace/${previewPath}` : "workspace/"}
{previewPath && ( )}
{/* Onglet Logs (fond sombre) */} {tab === "logs" ? (
{logs.length === 0 ? (
Aucune activité d'outil pour cette session.
) : ( logs.map((l, i) => (
{l.status === "error" ? "✕" : l.status === "pending" ? "⏸" : l.status === "running" ? "…" : "✓"} {l.name} {(l.args?.path as string) ?? (l.args?.query as string) ?? (l.args?.command as string) ?? ""} {l.summary}
)) )}
) : ( /* Viewport Aperçu / Code (fond clair) */
{!previewPath ? ( L'aperçu s'affichera ici dès que l'agent générera un fichier (clique aussi un fichier à gauche). ) : tab === "code" ? (
              {previewContent}
            
) : isHtml ? (