// Pledge photos viewer — Komek Lombard v2 // Full-screen first photo + thumbnail strip; tap a thumb or swipe to switch. const PV_TEAL = '#1B7F70'; const PV_TEAL_DEEP = '#176A5D'; const PV_BG = '#EBEBEC'; const PV_PANEL = '#FFFFFF'; const PV_PHOTO_BG = '#F4F4F6'; const PV_LABEL = '#0B0B0C'; const PV_SUBTLE = '#8A8A8E'; // The photo list the backend returns for a ticket. `src` is the real photo URL. const PHOTOS = [ { id: 'p1', label: 'Кольцо, фото 1', src: 'uploads/ring-1.jpg' }, { id: 'p2', label: 'Кольцо, фото 2', src: 'uploads/ring-2.jpg' }, { id: 'p3', label: 'Кольцо, фото 3', src: 'uploads/ring-3.jpg' }, ]; function PhotoFrame({ photo, big }) { // Real backend photo (object-fit: cover for thumbs, contain for the big view). return (
{photo.label}
); } function PhotoGalleryScreen({ onBack, photos = PHOTOS }) { const [idx, setIdx] = React.useState(0); const count = photos.length; const go = (n) => setIdx((prev) => (n + count) % count); const stripRef = React.useRef(null); const drag = React.useRef({ x: 0, dx: 0, active: false }); // keep the active thumbnail in view React.useEffect(() => { const strip = stripRef.current; if (!strip) return; const el = strip.children[idx]; if (el) { const left = el.offsetLeft - (strip.clientWidth - el.clientWidth) / 2; strip.scrollTo({ left, behavior: 'smooth' }); } }, [idx]); const onStart = (x) => { drag.current = { x, dx: 0, active: true }; }; const onMove = (x) => { if (drag.current.active) drag.current.dx = x - drag.current.x; }; const onEnd = () => { if (!drag.current.active) return; const dx = drag.current.dx; drag.current.active = false; if (dx <= -44) go(idx + 1); else if (dx >= 44) go(idx - 1); }; return (
{/* top bar */}
Фотографии
№ VV000000082
{idx + 1} / {count}
{/* full-size photo (swipeable) */}
onStart(e.touches[0].clientX)} onTouchMove={(e) => onMove(e.touches[0].clientX)} onTouchEnd={onEnd} onMouseDown={(e) => onStart(e.clientX)} onMouseMove={(e) => drag.current.active && onMove(e.clientX)} onMouseUp={onEnd} onMouseLeave={onEnd} > {/* sliding track */}
{photos.map((p) => (
))}
{/* edge arrows (desktop affordance) */} {count > 1 && ( go(idx - 1)}/> go(idx + 1)}/> )} {/* dots */}
{photos.map((p, i) => ( ))}
{/* thumbnail strip */}
{photos.map((p, i) => { const active = i === idx; return ( ); })}
); } function NavArrow({ side, onClick }) { return ( ); } Object.assign(window, { PhotoGalleryScreen });