Files
bitvid/components/search-filter-modal.html
T
google-labs-jules[bot] f53bfbeccf Replace search filter popover with responsive modal
Replaces the existing search filter popover with a new responsive modal component to improve UI/UX on both desktop and mobile devices.

- Adds `components/search-filter-modal.html` implementing a responsive grid layout.
- Adds `js/ui/components/SearchFilterModal.js` to manage filter state and modal interactions.
- Updates `js/index.js` to bootstrap the new modal and bind trigger events.
- Removes obsolete `js/ui/components/SearchFiltersPopover.js`.
- Keeps advanced filters hidden by default behind a toggle.

Signed-off-by: Jules <[email protected]>
2026-01-23 19:41:10 +00:00

175 lines
7.8 KiB
HTML

<div
id="searchFilterModal"
class="bv-modal hidden p-0 sm:p-0 lg:p-8 lg:items-start lg:justify-center overflow-hidden"
role="dialog"
aria-modal="true"
aria-labelledby="searchFilterModalTitle"
data-ds="new"
>
<div class="bv-modal-backdrop" data-dismiss></div>
<div
class="modal-sheet w-full h-full max-w-none rounded-none border-0 lg:max-h-modal-shell lg:max-w-4xl lg:rounded-modal-xl lg:border lg:h-auto flex min-h-0 flex-col overflow-hidden"
tabindex="-1"
>
<!-- Header -->
<div class="modal-header">
<h2 id="searchFilterModalTitle" class="text-xl font-bold text-text">
Search Filters
</h2>
<button id="closeSearchFilterModal" class="modal-close">
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-6"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M6 18L18 6M6 6l12 12"
/>
</svg>
</button>
</div>
<!-- Body -->
<div class="modal-body flex-1 overflow-y-auto">
<form id="searchFilterForm" class="space-y-6">
<!-- Basic Filters Grid -->
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<!-- Column 1: Date Range -->
<div class="space-y-3">
<h3 class="text-xs font-semibold uppercase tracking-wide text-muted">Date Range</h3>
<div class="flex flex-wrap gap-2" id="searchFilterDateChips">
<button type="button" class="search-filter-chip focus-ring" data-days="1">24h</button>
<button type="button" class="search-filter-chip focus-ring" data-days="7">7d</button>
<button type="button" class="search-filter-chip focus-ring" data-days="30">30d</button>
<button type="button" class="search-filter-chip focus-ring" data-days="90">90d</button>
<button type="button" class="search-filter-chip focus-ring" data-days="all">All time</button>
</div>
<div class="grid grid-cols-2 gap-2">
<div class="space-y-1">
<label for="searchFilterDateStart" class="text-xs text-muted">Start</label>
<input type="date" id="searchFilterDateStart" class="input w-full text-xs" />
</div>
<div class="space-y-1">
<label for="searchFilterDateEnd" class="text-xs text-muted">End</label>
<input type="date" id="searchFilterDateEnd" class="input w-full text-xs" />
</div>
</div>
</div>
<!-- Column 2: Sort & Author -->
<div class="space-y-4">
<div class="space-y-2">
<label for="searchFilterSort" class="text-xs font-semibold uppercase tracking-wide text-muted">Sort By</label>
<select id="searchFilterSort" class="select w-full">
<option value="recent">Most recent</option>
<option value="views">Most viewed</option>
<option value="trending">Trending</option>
<option value="longest">Longest</option>
</select>
</div>
<div class="space-y-2">
<label for="searchFilterAuthor" class="text-xs font-semibold uppercase tracking-wide text-muted">Author (npub)</label>
<input type="text" id="searchFilterAuthor" class="input w-full" placeholder="npub1..." />
</div>
</div>
<!-- Column 3: Quick Toggles (was advanced) -->
<div class="space-y-4">
<div class="space-y-2">
<h3 class="text-xs font-semibold uppercase tracking-wide text-muted">Content</h3>
<div class="flex flex-col gap-3">
<div class="flex items-center justify-between">
<span class="text-sm text-text">NSFW Content</span>
<button type="button" role="switch" aria-checked="false" id="searchFilterNsfwToggle" class="switch">
</button>
</div>
<!-- Reserved for "Followed only" later -->
</div>
</div>
</div>
</div>
<!-- Advanced Toggle -->
<div>
<button
type="button"
id="searchFilterAdvancedToggle"
class="btn-ghost w-full justify-between text-sm font-medium"
aria-expanded="false"
aria-controls="searchFilterAdvancedPanel"
>
<span>Advanced filters</span>
<span class="text-muted transition-transform duration-200" aria-hidden="true">▼</span>
</button>
</div>
<!-- Advanced Panel (Hidden by default) -->
<div id="searchFilterAdvancedPanel" class="hidden space-y-6 pt-2 border-t border-border-subtle">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<!-- Advanced: Tags -->
<div class="md:col-span-2 space-y-3">
<label for="searchFilterTags" class="text-xs font-semibold uppercase tracking-wide text-muted">Tags</label>
<input type="text" id="searchFilterTags" class="input w-full" placeholder="Add tag or keyword (comma separated)" />
<div class="flex flex-wrap gap-2" id="searchFilterTagChips">
<button type="button" class="search-filter-chip focus-ring" data-tag="nostr">#nostr</button>
<button type="button" class="search-filter-chip focus-ring" data-tag="music">#music</button>
<button type="button" class="search-filter-chip focus-ring" data-tag="live">#live</button>
<button type="button" class="search-filter-chip focus-ring" data-tag="gaming">#gaming</button>
<button type="button" class="search-filter-chip focus-ring" data-tag="tech">#tech</button>
</div>
</div>
<!-- Advanced: Duration -->
<div class="space-y-3">
<h3 class="text-xs font-semibold uppercase tracking-wide text-muted">Duration</h3>
<div class="grid gap-2">
<label class="flex items-center gap-3 text-sm text-text cursor-pointer">
<input type="checkbox" class="checkbox" id="searchFilterDurationShort" />
<span>Short (under 5 min)</span>
</label>
<label class="flex items-center gap-3 text-sm text-text cursor-pointer">
<input type="checkbox" class="checkbox" id="searchFilterDurationMedium" />
<span>Medium (5-20 min)</span>
</label>
<label class="flex items-center gap-3 text-sm text-text cursor-pointer">
<input type="checkbox" class="checkbox" id="searchFilterDurationLong" />
<span>Long (20+ min)</span>
</label>
</div>
</div>
<!-- Advanced: Has -->
<div class="space-y-3">
<h3 class="text-xs font-semibold uppercase tracking-wide text-muted">Must Have</h3>
<div class="flex flex-wrap gap-2" id="searchFilterHasChips">
<button type="button" class="search-filter-chip focus-ring" data-has="magnet">Magnet Link</button>
<button type="button" class="search-filter-chip focus-ring" data-has="url">Web URL</button>
</div>
</div>
</div>
</div>
</form>
</div>
<!-- Footer -->
<div class="modal-footer flex-row items-center justify-between border-t border-border-subtle bg-surface-alt/50">
<button type="button" id="searchFilterResetBtn" class="btn-ghost text-sm">
Reset
</button>
<button type="button" id="searchFilterApplyBtn" class="btn text-sm">
Apply Filters
</button>
</div>
</div>
</div>