// Sidebar — sessions, collections, smart filters // On mobile (< 768px): slide-over drawer with backdrop // On desktop: inline sidebar function Sidebar({ open, setOpen, events, activeEvent, setActiveEvent, activeShootId, onCreateEvent, onActivateEvent, onDeleteEvent, collections, activeCollection, setActiveCollection, onDeleteCollection, tagFilter, setTagFilter, ratingFilter, setRatingFilter, flagFilter, setFlagFilter, fileTypeFilter, setFileTypeFilter, tagCounts, stats, onNewCollection, shareCount, onOpenShares, onOpenWatermark, onOpenShortcuts, onOpenBranding, displayName, profilePhotoUrl, onOpenProfile, onLogout }) { const [isMobile, setIsMobile] = React.useState(() => window.innerWidth < 768); React.useEffect(() => { const fn = () => setIsMobile(window.innerWidth < 768); window.addEventListener('resize', fn); return () => window.removeEventListener('resize', fn); }, []); // Auto-close on mobile when a filter row is clicked const mobileClose = () => { if (isMobile) setOpen(false); }; const inner = (
{/* Brand */}
Studio
Dashboard
Live
{/* Close button — mobile only */} {isMobile && ( )}
{/* Events */}
}> { setActiveEvent(null); mobileClose(); }} icon={} label="All events" badge={{stats.total}}/> {stats.unassigned > 0 && ( { setActiveEvent('_unassigned'); mobileClose(); }} icon={} label="Unassigned" badge={{stats.unassigned}}/> )} {(events || []).map(e => ( { setActiveEvent(e.id); mobileClose(); }} onActivate={() => onActivateEvent(e.id)} onDeactivate={() => onActivateEvent(null)} onDelete={() => onDeleteEvent(e.id)} /> ))} {(!events || events.length === 0) && (
No events yet — click + to create one
)}
{/* Flag filters */}
{ setFlagFilter('all'); mobileClose(); }} icon={} label="All photos" badge={{stats.total}}/> { setFlagFilter('picks'); mobileClose(); }} icon={} label="Picks" badge={{stats.picks}}/> { setFlagFilter('rejects'); mobileClose(); }} icon={} label="Rejects" badge={{stats.rejects}}/> { setFlagFilter('unflagged'); mobileClose(); }} icon={} label="Unflagged" badge={{stats.unflagged}}/>
{[0,1,2,3,4,5].map(r => ( ))}
{['all','RAW','JPG'].map(t => ( ))}
{/* Collections */}
}> { setActiveCollection(null); mobileClose(); }} icon={} label="None"/> {collections.map(c => ( { setActiveCollection(c.name); mobileClose(); }} icon={} label={c.name} badge={{c.count || (c.files && c.files.length) || 0}} onDelete={onDeleteCollection ? () => onDeleteCollection(c.name) : null}/> ))}
{/* Tags */} {Object.keys(tagCounts).length > 0 && (
{Object.entries(tagCounts).sort((a,b) => b[1] - a[1]).map(([tag, count]) => ( ))}
)}
{/* Footer actions */}
} label={`Share links · ${shareCount}`} onClick={() => { onOpenShares(); mobileClose(); }}/> } label="Watermark" onClick={() => { onOpenWatermark(); mobileClose(); }}/> } label="Branding" onClick={() => { onOpenBranding(); mobileClose(); }}/> } label="Shortcuts" onClick={() => { onOpenShortcuts(); mobileClose(); }}/>
{/* Profile footer */}
{displayName}
); // ── Mobile: slide-over drawer ────────────────────────────────────────────── if (isMobile) { return ( <> {/* Backdrop */} {open && (
setOpen(false)} style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.55)', zIndex: 290, backdropFilter: 'blur(2px)', animation: 'fade-in 160ms', }}/> )} {/* Drawer */} ); } // ── Desktop: inline sidebar ──────────────────────────────────────────────── return ( ); } function Section({ title, action, children }) { return (
{title} {action}
{children}
); } function Row({ icon, label, badge, active, onClick }) { return ( ); } function DeletableRow({ icon, label, badge, active, onClick, onDelete }) { const [hover, setHover] = React.useState(false); return (
setHover(true)} onMouseLeave={() => setHover(false)} style={{ display: 'flex', alignItems: 'center', margin: '1px 8px', borderRadius: 4, background: active ? 'var(--bg-3)' : hover ? 'var(--bg-2)' : 'transparent', transition: 'background 100ms', cursor: 'pointer' }} onClick={onClick}> {icon} {label} {badge && !hover && badge} {hover && onDelete && ( )}
); } function EventRow({ event, active, isLive, onClick, onActivate, onDeactivate, onDelete }) { const [hover, setHover] = React.useState(false); return (
setHover(true)} onMouseLeave={() => setHover(false)} onClick={onClick} style={{ position: 'relative', display: 'flex', alignItems: 'center', margin: '1px 8px', borderRadius: 4, background: active ? 'var(--bg-3)' : hover ? 'var(--bg-2)' : 'transparent', transition: 'background 100ms', cursor: 'pointer', }}>
{isLive ? : }
{isLive && Live} {event.name}
{event.date} · {event.count || 0}
{hover && (
e.stopPropagation()}> {isLive ? ( ) : ( )}
)}
); } Object.assign(window, { Sidebar });