/** * Popup.jsx * * This component displays a popup box with information about a selected shape (circle or text). * - For circles: shows page number and circle text, with a button to navigate to the corresponding page. * - For text: fetches additional info from the LLM backend and displays it. * - Supports zoomed image coordinates without scaling the popup itself. * - Provides a close button to dismiss the popup. */ import { useState, useEffect } from "react"; function Popup({ selectedShape, onClose, zoom = 1 }) { const [info, setInfo] = useState(null); useEffect(() => { if (!selectedShape || selectedShape.r) return; setInfo("Loading..."); fetch("/llm/generate_info", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ content: selectedShape.text || "Unlabeled text" }), }) .then((res) => { if (!res.ok) throw new Error(`HTTP error! status: ${res.status}`); return res.json(); }) .then((data) => setInfo(data.info)) .catch((error) => { console.error("LLM fetch error:", error); setInfo("Error generating info"); }); }, [selectedShape]); if (!selectedShape) return null; // ✅ Apply zoom only to coordinates, not to popup size const left = (selectedShape.r ? selectedShape.x + selectedShape.r + 10 : selectedShape.x2 + 10) * zoom; const top = (selectedShape.r ? selectedShape.y - selectedShape.r / 2 : selectedShape.y1) * zoom; // Redirect handler const handleRedirect = (e, pageNumber, circleText) => { e.preventDefault(); e.stopPropagation(); if (!pageNumber) { console.log("Missing navigation data:", { pageNumber }); return; } const pageImageUrl = `/images/${pageNumber}.png`; let targetUrl = `/page?image=${encodeURIComponent(pageImageUrl)}`; if (circleText) { targetUrl += `&circle=${encodeURIComponent(circleText)}`; } window.open(targetUrl, "_blank", "noopener,noreferrer"); onClose(); }; return (
e.stopPropagation()} style={{ position: "absolute", left: `${left}px`, top: `${top}px`, zIndex: 1001, backgroundColor: "orange", border: "1px solid #ccc", borderRadius: "8px", padding: "10px", boxShadow: "0 2px 10px rgba(0,0,0,0.1)", minWidth: "200px", transform: "scale(1)", }} > {selectedShape.r ? (

Circle Information

{selectedShape.page_number ? ( ) : (

No page number available for navigation.

)}
) : (

Detected Text

Text: {selectedShape.text || "Text"}

Info: {info || "Click to generate info"}

)}
); } export default Popup;