Phase 2: playlists UI shows display count, auto-generated filter toggle

List view: auto-generated playlists hidden by default with toggle checkbox.
Cards show 'auto' badge and display count. Detail view shows display count
in the header.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
ScreenTinker 2026-04-11 22:10:48 -05:00
parent 40fcbbc32a
commit a66feab53e

View file

@ -39,6 +39,8 @@ export function cleanup() {
// ==================== LIST VIEW ====================
let showAutoGenerated = false;
async function renderList(container) {
container.innerHTML = `
<div class="page-header">
@ -46,7 +48,13 @@ async function renderList(container) {
<h1>Playlists</h1>
<div class="subtitle">Create and manage content playlists</div>
</div>
<button class="btn btn-primary" id="createPlaylistBtn">+ New Playlist</button>
<div style="display:flex;gap:8px;align-items:center">
<label style="display:flex;align-items:center;gap:6px;font-size:13px;color:var(--text-secondary);cursor:pointer">
<input type="checkbox" id="showAutoToggle" ${showAutoGenerated ? 'checked' : ''}>
Show auto-generated
</label>
<button class="btn btn-primary" id="createPlaylistBtn">+ New Playlist</button>
</div>
</div>
<div id="playlistGrid" style="display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:16px">
<div style="color:var(--text-muted);padding:40px;text-align:center">Loading...</div>
@ -54,6 +62,10 @@ async function renderList(container) {
`;
document.getElementById('createPlaylistBtn').addEventListener('click', showCreateModal);
document.getElementById('showAutoToggle').addEventListener('change', (e) => {
showAutoGenerated = e.target.checked;
loadPlaylists();
});
loadPlaylists();
}
@ -77,14 +89,30 @@ async function loadPlaylists() {
return;
}
grid.innerHTML = playlists.map(p => `
const filtered = showAutoGenerated ? playlists : playlists.filter(p => !p.is_auto_generated);
if (!filtered.length) {
grid.innerHTML = `
<div style="grid-column:1/-1;text-align:center;padding:40px;color:var(--text-muted)">
${playlists.length ? 'All playlists are auto-generated. Toggle "Show auto-generated" to see them.' : ''}
</div>
`;
return;
}
grid.innerHTML = filtered.map(p => `
<a href="#/playlists/${esc(p.id)}" class="playlist-card" style="background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius-lg);padding:20px;text-decoration:none;color:inherit;display:block;transition:border-color 0.15s;cursor:pointer">
<div style="display:flex;justify-content:space-between;align-items:start;margin-bottom:12px">
<div style="font-size:16px;font-weight:600;color:var(--text-primary)" data-name="${esc(p.id)}">${esc(p.name)}</div>
<div style="display:flex;align-items:center;gap:8px">
<div style="font-size:16px;font-weight:600;color:var(--text-primary)">${esc(p.name)}</div>
${p.is_auto_generated ? '<span style="font-size:10px;padding:2px 6px;border-radius:4px;background:var(--bg-input);color:var(--text-muted)">auto</span>' : ''}
</div>
<div style="font-size:12px;color:var(--text-muted);white-space:nowrap;margin-left:12px">${p.item_count} item${p.item_count !== 1 ? 's' : ''}</div>
</div>
${p.description ? `<div style="font-size:13px;color:var(--text-secondary);margin-bottom:12px;line-height:1.4">${esc(p.description)}</div>` : ''}
<div style="font-size:12px;color:var(--text-muted)">Created ${formatDate(p.created_at)}</div>
<div style="display:flex;justify-content:space-between;font-size:12px;color:var(--text-muted)">
<span>Created ${formatDate(p.created_at)}</span>
${p.display_count ? `<span>${p.display_count} display${p.display_count !== 1 ? 's' : ''}</span>` : ''}
</div>
</a>
`).join('');
} catch (err) {
@ -160,6 +188,7 @@ function renderDetailContent(container, playlist) {
<div>
<h1 id="playlistTitle" style="cursor:pointer" title="Click to rename">${esc(playlist.name)}</h1>
<div class="subtitle" id="playlistDesc" style="cursor:pointer" title="Click to edit description">${playlist.description ? esc(playlist.description) : '<span style="opacity:0.5">Add a description...</span>'}</div>
${playlist.display_count ? `<div style="font-size:12px;color:var(--text-muted);margin-top:4px">Assigned to ${playlist.display_count} display${playlist.display_count !== 1 ? 's' : ''}</div>` : ''}
</div>
</div>
<div style="display:flex;gap:8px">