Files
Astronome/frontend/src/components/gallery/LightboxView.tsx
T
2026-04-09 23:37:10 +02:00

110 lines
3.3 KiB
TypeScript

import { useState } from 'react';
import type { GalleryImage } from '../../api/types';
import { api } from '../../api';
import { useQueryClient } from '@tanstack/react-query';
interface Props {
images: GalleryImage[];
catalogId: string;
}
export default function LightboxView({ images, catalogId }: Props) {
const [lightbox, setLightbox] = useState<GalleryImage | null>(null);
const qc = useQueryClient();
if (images.length === 0) {
return (
<div style={{ color: 'var(--text-lo)', fontFamily: 'var(--font-mono)', fontSize: 12, padding: '8px 0' }}>
No images yet.
</div>
);
}
return (
<>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 6 }}>
{images.map(img => (
<div
key={img.id}
onClick={() => setLightbox(img)}
style={{
cursor: 'pointer',
borderRadius: 3,
overflow: 'hidden',
background: 'var(--bg-deep)',
aspectRatio: '1',
position: 'relative',
}}
>
<img
src={img.url}
alt={img.caption ?? img.filename}
style={{ width: '100%', height: '100%', objectFit: 'cover' }}
/>
</div>
))}
</div>
{lightbox && (
<div
onClick={() => setLightbox(null)}
style={{
position: 'fixed',
inset: 0,
background: 'rgba(0,0,0,0.92)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
zIndex: 1000,
}}
>
<div onClick={e => e.stopPropagation()} style={{ position: 'relative', maxWidth: '90vw', maxHeight: '90vh' }}>
<img
src={lightbox.url}
alt={lightbox.caption ?? lightbox.filename}
style={{ maxWidth: '100%', maxHeight: '85vh', borderRadius: 4 }}
/>
<div style={{ marginTop: 8, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
{lightbox.caption && (
<span style={{ color: 'var(--text-mid)', fontSize: 12, fontFamily: 'var(--font-sans)' }}>
{lightbox.caption}
</span>
)}
<button
onClick={() => {
api.gallery.delete(lightbox.id).then(() => {
qc.invalidateQueries({ queryKey: ['gallery', catalogId] });
setLightbox(null);
});
}}
style={{ color: 'var(--danger)', fontSize: 12, marginLeft: 'auto' }}
>
Delete
</button>
</div>
<button
onClick={() => setLightbox(null)}
style={{
position: 'absolute',
top: -12,
right: -12,
color: 'var(--text-hi)',
fontSize: 20,
background: 'var(--bg-panel)',
borderRadius: '50%',
width: 28,
height: 28,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
>
</button>
</div>
</div>
)}
</>
);
}