Initial Commit

This commit is contained in:
2026-03-06 11:54:19 -05:00
parent ee68c4704f
commit 4517746692
36 changed files with 4262 additions and 0 deletions

View File

@@ -0,0 +1,78 @@
import { useEffect, useRef, useState } from 'react';
export default function ImageLightbox({ src, onClose }) {
const overlayRef = useRef(null);
const imgRef = useRef(null);
// Close on Escape
useEffect(() => {
const handler = (e) => { if (e.key === 'Escape') onClose(); };
window.addEventListener('keydown', handler);
return () => window.removeEventListener('keydown', handler);
}, [onClose]);
return (
<div
ref={overlayRef}
onClick={(e) => e.target === overlayRef.current && onClose()}
style={{
position: 'fixed', inset: 0, zIndex: 2000,
background: 'rgba(0,0,0,0.92)',
display: 'flex', alignItems: 'center', justifyContent: 'center',
touchAction: 'pinch-zoom',
}}
>
{/* Close button */}
<button
onClick={onClose}
style={{
position: 'absolute', top: 16, right: 16,
background: 'rgba(255,255,255,0.15)', border: 'none',
borderRadius: '50%', width: 40, height: 40,
display: 'flex', alignItems: 'center', justifyContent: 'center',
cursor: 'pointer', color: 'white', zIndex: 2001,
}}
>
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
<line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/>
</svg>
</button>
{/* Download button */}
<a
href={src}
download
style={{
position: 'absolute', top: 16, right: 64,
background: 'rgba(255,255,255,0.15)', border: 'none',
borderRadius: '50%', width: 40, height: 40,
display: 'flex', alignItems: 'center', justifyContent: 'center',
cursor: 'pointer', color: 'white', zIndex: 2001, textDecoration: 'none',
}}
title="Download"
>
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
<polyline points="7 10 12 15 17 10"/>
<line x1="12" y1="15" x2="12" y2="3"/>
</svg>
</a>
{/* Image — fit to screen, browser handles pinch-zoom natively */}
<img
ref={imgRef}
src={src}
alt="Full size"
style={{
maxWidth: '95vw',
maxHeight: '95vh',
objectFit: 'contain',
borderRadius: 8,
userSelect: 'none',
touchAction: 'pinch-zoom',
}}
onClick={(e) => e.stopPropagation()}
/>
</div>
);
}