import React, { useState, useEffect, useCallback } from "react";
import { Globe, Search } from "lucide-react";
import SearchResultPreview from "./SearchResultPreview";
import InteractiveBrowser from "./InteractiveBrowser";
import ErrorBoundary from "./ErrorBoundary";
export default function BrowserPanel({ frames = [], reflectNotes = [], onFrameUpdate }) {
const [activeId, setActiveId] = useState(null);
useEffect(() => {
if (frames.length) setActiveId(frames[0].id);
}, [frames.length, frames[0]?.id]);
const active = frames.find((f) => f.id === activeId) || frames[0] || null;
const handleFrameUpdate = useCallback(
(next) => {
if (!active?.id) return;
onFrameUpdate?.(active.id, next);
},
[active?.id, onFrameUpdate],
);
if (!frames.length && !reflectNotes.length) {
return (
Navigateur interactif — sites ouverts par Émo ou via la barre d'URL.
);
}
return (
{reflectNotes.length > 0 && (
{reflectNotes.slice(0, 5).map((n) => (
💭
{n.thought?.slice(0, 180)}
{n.plan && → {n.plan.slice(0, 100)}}
))}
)}
{frames.map((f) => {
const isActive = active?.id === f.id;
const label = f.action === "search"
? `🔍 ${f.query || "recherche"}`
: f.action === "control" || f.screenshot_base64
? `🖱 ${f.title || f.url || "Page"}`
: f.title || f.url || "Page";
return (
);
})}
{!active ? null : active.action === "search" ? (
) : (
)}
);
}
function SearchResults({ frame }) {
return (
{frame.query}
({(frame.results || []).length} résultats)
{(frame.results || []).slice(0, 8).map((r, i) => (
))}
);
}
function PagePreview({ frame, onFrameUpdate, liveSync = true }) {
return (
);
}