feat(ui): collection filter toolbar — toggle chips + tidy inline selects

Replace raw checkboxes + stacked-label dropdowns with pill toggle chips
(.chip, accent when checked via :has) and a single aligned toolbar row;
result count as a badge. Adds reusable .toolbar/.chip/.field components.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
hehihoho3@gmail.com 2026-06-12 22:45:05 +09:00
parent 7497cb08ce
commit fc58a32a20
2 changed files with 51 additions and 32 deletions

View File

@ -323,6 +323,33 @@ body.sidebar-collapsed #mainContent { margin-left: var(--sidebar-collapsed-width
.bar-fill { height: 100%; border-radius: var(--radius-full); transition: width 0.6s cubic-bezier(0.22, 1, 0.36, 1); }
@media (prefers-reduced-motion: reduce) { .bar-fill { transition: none; } }
/* Toolbar + filter chips */
.toolbar { display: flex; align-items: center; flex-wrap: wrap; gap: 0.5rem; }
.toolbar .sep { width: 1px; align-self: stretch; background: var(--border); margin: 2px 0.35rem; }
.toolbar .spacer { margin-left: auto; }
.toolbar select {
padding: 0.45rem 0.6rem;
font-size: 0.82rem;
border-radius: var(--r-sm);
}
.field { display: inline-flex; align-items: center; gap: 0.4rem; font-size: 0.78rem; color: var(--text-3); }
.chip {
display: inline-flex; align-items: center; gap: 6px;
padding: 0.45rem 0.8rem;
border-radius: var(--radius-full);
border: 1px solid var(--border-strong);
background: var(--surface);
color: var(--text-2);
font-size: 0.82rem; font-weight: 500;
cursor: pointer; user-select: none;
transition: all 0.15s ease;
}
.chip:hover { background: var(--surface-2); color: var(--text); }
.chip input { display: none; }
.chip:has(input:checked) { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); }
.chip svg { width: 14px; height: 14px; }
/* Badge */
.badge {
display: inline-flex; align-items: center; gap: 4px;

View File

@ -41,22 +41,17 @@
</div>
</div>
<!-- 필터 -->
<!-- 필터 -->
<div class="card mb-4">
<div style="display:flex; flex-wrap:wrap; gap:16px; align-items:flex-end;">
<label class="flex items-center gap-2 cursor-pointer" style="height:42px;">
<input type="checkbox" id="fOutperformers" onchange="loadVideos()"> <span class="text-sm font-bold">🚀 떡상 후보만</span>
</label>
<label class="flex items-center gap-2 cursor-pointer" style="height:42px;">
<input type="checkbox" id="fShorts" onchange="loadVideos()"> <span class="text-sm">Shorts만</span>
</label>
<label class="flex items-center gap-2 cursor-pointer" style="height:42px;">
<input type="checkbox" id="fBookmarked" onchange="loadVideos()"> <span class="text-sm">⭐ 북마크만</span>
</label>
<div class="toolbar">
<label class="chip"><input type="checkbox" id="fOutperformers" onchange="loadVideos()"> 🚀 떡상 후보</label>
<label class="chip"><input type="checkbox" id="fShorts" onchange="loadVideos()"> Shorts</label>
<label class="chip"><input type="checkbox" id="fBookmarked" onchange="loadVideos()"> ⭐ 북마크</label>
<div style="display:flex; flex-direction:column; gap:4px; min-width:130px;">
<label class="text-sm text-muted">상태</label>
<select id="fStatus" onchange="loadVideos()" class="filter-sel">
<span class="sep"></span>
<label class="field">상태
<select id="fStatus" onchange="loadVideos()">
<option value="">전체</option>
<option value="NEW">NEW (수집됨)</option>
<option value="REVIEWING">REVIEWING (검토중)</option>
@ -64,34 +59,31 @@
<option value="DONE">DONE (완료)</option>
<option value="EXCLUDED">EXCLUDED (제외)</option>
</select>
</div>
<div style="display:flex; flex-direction:column; gap:4px; min-width:150px;">
<label class="text-sm text-muted">카테고리</label>
<select id="fCategory" onchange="loadVideos()" class="filter-sel">
<option value="">전체</option>
</select>
</div>
<div style="display:flex; flex-direction:column; gap:4px; min-width:120px;">
<label class="text-sm text-muted">출처</label>
<select id="fSource" onchange="loadVideos()" class="filter-sel">
</label>
<label class="field">카테고리
<select id="fCategory" onchange="loadVideos()"><option value="">전체</option></select>
</label>
<label class="field">출처
<select id="fSource" onchange="loadVideos()">
<option value="">전체</option>
<option value="CHANNEL">채널 수집</option>
<option value="SEARCH">검색 수집</option>
</select>
</div>
<div style="display:flex; flex-direction:column; gap:4px; min-width:150px;">
<label class="text-sm text-muted">정렬</label>
<select id="fSort" onchange="loadVideos()" class="filter-sel">
</label>
<label class="field">정렬
<select id="fSort" onchange="loadVideos()">
<option value="viewsPerSubRatio">배율(조회/구독) ↓</option>
<option value="viewsPerHour">시간당 조회수 ↓</option>
<option value="viewCount">조회수 ↓</option>
<option value="publishedAt">최신순 ↓</option>
</select>
</div>
<button class="btn btn-secondary px-4 py-2 flex items-center gap-1" onclick="loadVideos()">
<i data-lucide="refresh-cw" style="width:16px;"></i> 새로고침
</label>
<span class="spacer"></span>
<span id="resultCount" class="badge badge-muted"></span>
<button class="btn btn-secondary" onclick="loadVideos()" title="새로고침">
<i data-lucide="refresh-cw" style="width:15px;"></i>
</button>
<span id="resultCount" class="text-sm text-muted" style="margin-left:auto; height:42px; display:flex; align-items:center;"></span>
</div>
</div>