"use client"; import { useI18n } from "@/components/I18nProvider"; import { useEffect, useRef, useState } from "react"; import { Panorama } from "./Panorama"; import { api } from "./StartGame"; import { ChevronLeft, ChevronRight, X, Move, Expand, Minimize, } from "lucide-react"; export function PanoramaPreview({ endpoint, initialId, onClose, }: { endpoint: string; initialId?: string; onClose: () => void; }) { const { t } = useI18n(); const dialog = useRef(null); const closeButton = useRef(null); const [expanded, setExpanded] = useState(false); const [locations, setLocations] = useState([]), [selected, setSelected] = useState(initialId ?? ""), [urls, setUrls] = useState(null), [ready, setReady] = useState(false), [error, setError] = useState(""); const [labels, setLabels] = useState>({}); useEffect(() => { const element = dialog.current; const previousFocus = document.activeElement instanceof HTMLElement ? document.activeElement : null; const overflow = document.body.style.overflow; if (element && !element.open) element.showModal(); document.body.style.overflow = "hidden"; closeButton.current?.focus(); let disposed = false; api<{ locations: string[]; labels?: Record }>(endpoint) .then((d) => { if (disposed) return; if (!Array.isArray(d.locations)) throw new Error( "Could not load the submitted locations. Please try again.", ); setLocations(d.locations); setLabels(d.labels ?? {}); setSelected((s) => d.locations.includes(s) ? s : (d.locations[0] ?? ""), ); }) .catch((e) => { if (!disposed) setError(e.message); }); return () => { disposed = true; element?.close(); document.body.style.overflow = overflow; previousFocus?.focus(); }; }, [endpoint]); useEffect(() => { if (!selected) return; let disposed = false; setUrls(null); setReady(false); setError(""); api<{ faces: string[] }>(`${endpoint}/${selected}`) .then((d) => { if (!disposed) setUrls(d.faces); }) .catch((e) => { if (!disposed) setError(e.message); }); return () => { disposed = true; }; }, [endpoint, selected]); const index = locations.indexOf(selected); return ( { e.preventDefault(); onClose(); }} onClick={(e) => { if (e.target === e.currentTarget) { const box = e.currentTarget.getBoundingClientRect(); if ( e.clientX < box.left || e.clientX > box.right || e.clientY < box.top || e.clientY > box.bottom ) onClose(); } }} >
{t("360° PANORAMA")}

{t("A closer look.")}

{index >= 0 ? index + 1 : 0} / {locations.length}
{urls && ( setReady(true)} onError={setError} /> )} {error ? (

{t(error)}

) : ( !ready && (

{t("Loading panorama…")}

) )}
); }