// screens-library.jsx function Library({ navigate, onOpenAsset, openProject }) { const { ASSETS: ALL_ASSETS, BINS, PROJECTS } = window.ZAMPP_DATA; const [view, setView] = React.useState('grid'); const [filter, setFilter] = React.useState('all'); const [search, setSearch] = React.useState(''); let assets = openProject ? ALL_ASSETS.filter(a => a.project_id === openProject.id) : ALL_ASSETS; if (filter !== 'all') assets = assets.filter(a => a.status === filter); if (search) assets = assets.filter(a => a.name.toLowerCase().includes(search.toLowerCase())); const displayTitle = openProject ? openProject.name : 'All Assets'; const errorCount = ALL_ASSETS.filter(a => a.status === 'error').length; const recentCount = ALL_ASSETS.filter(a => (Date.now() - new Date(a.created_at)) < 86400000).length; return (
{displayTitle}
· {assets.length} assets
setSearch(e.target.value)} placeholder="Filter assets…" />
{['all', 'ready', 'processing', 'live', 'error'].map(f => ( ))}
{assets.length === 0 ? (
No assets match this filter.
) : view === 'grid' ? (
{assets.map(a => onOpenAsset(a)} />)}
) : (
Name
Duration
Resolution
Codec
Size
Updated
{assets.map(a => (
onOpenAsset(a)} style={{ cursor: 'pointer' }}>
{a.name}
{a.status}
{a.duration}
{a.res}
{a.codec || '—'}
{a.size}
{a.updated}
))}
)}
); } function AssetCard({ asset, onOpen }) { return (
{asset.status === 'live' && LIVE} {asset.status === 'processing' && Processing} {asset.status === 'error' && Error}
{(asset.type === 'video' || !asset.type) && asset.duration !== '—' &&
{asset.duration}
}
{asset.name}
{asset.res} · {asset.size}
); } function binIcon(name) { return { grid: 'library', live: 'record', film: 'film', proxy: 'proxy', audio: 'audio', package: 'package' }[name] || 'folder'; } window.Library = Library; window.AssetCard = AssetCard;