Files
shpm/client/src/components/MonthGroup.jsx
T
nmemmertandClaude Sonnet 4.6 e0f4e8ff0d feat: initial Luma implementation
Full self-hosted photo manager with:
- Ingestion worker (chokidar + sharp + exifr, dHash perceptual hashing)
- SQLite schema with WAL mode (photos, tags, collections, duplicate_pairs)
- Express API with keyset pagination, tag/collection/search/date filters
- React + Vite UI: timeline, lightbox, detail panel, tag/collection editors
- Duplicate detection (Union-Find grouping) with review + dismiss UI
- Map view (Leaflet + OpenStreetMap, marker clustering)
- Docker multi-stage build + Compose with inline env config
- GitHub Actions: CI build check + ghcr.io image publish on main/tags

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-17 16:33:55 -04:00

37 lines
921 B
React

import PhotoCard from './PhotoCard.jsx';
export default function MonthGroup({ label, photos, startIdx, onSelect }) {
return (
<section style={{ marginBottom: 8 }}>
<h2 style={{
padding: '18px 6px 8px',
fontSize: 13,
fontWeight: 600,
color: '#666',
letterSpacing: 0.4,
textTransform: 'uppercase',
userSelect: 'none',
}}>
{label}
<span style={{ marginLeft: 8, color: '#3a3a3a', fontWeight: 400 }}>
{photos.length.toLocaleString()}
</span>
</h2>
<div style={{
display: 'grid',
gridTemplateColumns: 'repeat(auto-fill, minmax(160px, 1fr))',
gap: 3,
}}>
{photos.map((photo, i) => (
<PhotoCard
key={photo.id}
photo={photo}
onClick={() => onSelect(startIdx + i)}
/>
))}
</div>
</section>
);
}