"use client"; import { useEffect, useState } from "react"; import { useObjectPhotos } from "@/lib/analytics-api"; const INITIAL_LIMIT = 24; export function ObjectPhotoGallery({ objId }: { objId: number | string }) { const { data, isLoading } = useObjectPhotos(objId, 200); const [active, setActive] = useState(null); const [showAll, setShowAll] = useState(false); useEffect(() => { if (!active) return; const onKey = (e: KeyboardEvent) => { if (e.key === "Escape") setActive(null); }; window.addEventListener("keydown", onKey); return () => window.removeEventListener("keydown", onKey); }, [active]); if (isLoading) { return (
{Array.from({ length: 12 }).map((_, i) => (
))}
); } const photos = (data ?? []).filter((p) => p.photo_url); if (photos.length === 0) { return (
Фото отсутствуют.
); } const visible = showAll ? photos : photos.slice(0, INITIAL_LIMIT); const activeIdx = active ? photos.findIndex((p) => p.obj_file_id === active) : -1; const activePhoto = activeIdx >= 0 ? photos[activeIdx] : null; const move = (delta: number) => { if (activeIdx < 0) return; const next = (activeIdx + delta + photos.length) % photos.length; setActive(photos[next].obj_file_id); }; return ( <>
{visible.map((p, i) => ( ))}
{photos.length > INITIAL_LIMIT && !showAll ? (
) : null} {activePhoto ? (
setActive(null)} style={{ position: "fixed", inset: 0, background: "rgba(0,0,0,0.9)", display: "flex", alignItems: "center", justifyContent: "center", zIndex: 1000, cursor: "zoom-out", }} > {/* eslint-disable-next-line @next/next/no-img-element */} {activePhoto.photo_name
{activeIdx + 1} / {photos.length} ·{" "} {activePhoto.period_dt?.slice(0, 10)} · {activePhoto.photo_name}
) : null} ); } function navBtnStyle(side: "left" | "right"): React.CSSProperties { return { position: "absolute", top: "50%", [side]: 16, transform: "translateY(-50%)", width: 44, height: 44, borderRadius: 22, border: "none", background: "rgba(255,255,255,0.15)", color: "#fff", fontSize: 28, lineHeight: 1, cursor: "pointer", }; }