710 lines
20 KiB
HTML
710 lines
20 KiB
HTML
{{ define "main" }}
|
||
<h1>{{ .Title }}</h1>
|
||
{{ if .Description }}
|
||
<p class="lead">{{ .Description }}</p>
|
||
{{ end }}
|
||
|
||
{{ .Content }}
|
||
|
||
{{ if .Pages }}
|
||
<div class="filter-controls">
|
||
<div class="filter-row">
|
||
<input type="text" id="searchInput" placeholder="Search full text..." class="search-input">
|
||
<div class="tag-filter-container">
|
||
<div id="tagDropdown" class="tag-dropdown">
|
||
<div class="tag-dropdown-trigger">
|
||
<span class="dropdown-label">Select tags</span>
|
||
<div class="selected-tags" id="selectedTags"></div>
|
||
<svg class="dropdown-arrow" width="12" height="8" viewBox="0 0 12 8" fill="none">
|
||
<path d="M1 1.5L6 6.5L11 1.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||
</svg>
|
||
</div>
|
||
<div class="tag-dropdown-menu" id="tagDropdownMenu">
|
||
<div class="tag-options" id="tagOptions">
|
||
<!-- Tags will be populated here -->
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="sort-container">
|
||
<div id="sortDropdown" class="sort-dropdown">
|
||
<div class="sort-dropdown-trigger">
|
||
<span class="sort-label">Sort by Title</span>
|
||
<svg class="dropdown-arrow" width="12" height="8" viewBox="0 0 12 8" fill="none">
|
||
<path d="M1 1.5L6 6.5L11 1.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||
</svg>
|
||
</div>
|
||
<div class="sort-dropdown-menu" id="sortDropdownMenu">
|
||
<div class="sort-option" data-value="title">Sort by Title</div>
|
||
<div class="sort-option" data-value="date">Sort by Date</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="grid" id="cardGrid">
|
||
{{ range .Pages }}
|
||
<div class="card"
|
||
data-title="{{ .Title }}"
|
||
data-description="{{ if .Description }}{{ .Description }}{{ else if .Summary }}{{ .Summary | plainify | replaceRE "^### \\*\\*Summary\\*\\*\\s*" "" | truncate 200 }}{{ else }}{{ .Content | plainify | replaceRE "^### \\*\\*Summary\\*\\*\\s*" "" | truncate 200 }}{{ end }}"
|
||
data-content="{{ .Content | plainify | replaceRE "^### \\*\\*Summary\\*\\*\\s*" "" }}"
|
||
data-tags="{{ if .Params.tags }}{{ delimit .Params.tags "," }}{{ end }}"
|
||
data-date="{{ .Date.Format "2006-01-02" }}">
|
||
{{ if .Params.banner }}
|
||
<a href="{{ .RelPermalink }}" class="card-banner-link">
|
||
<div class="card-banner">
|
||
<img src="{{ .Params.banner }}" alt="{{ .Title }} banner" class="case-banner" />
|
||
{{ if .Params.image }}
|
||
<img src="{{ .Params.image }}" alt="{{ .Title }} logo" class="case-logo-overlay" />
|
||
{{ end }}
|
||
</div>
|
||
</a>
|
||
{{ else if .Params.image }}
|
||
<a href="{{ .RelPermalink }}" class="card-logo-link">
|
||
<img src="{{ .Params.image }}" alt="{{ .Title }} logo" class="case-logo" />
|
||
</a>
|
||
{{ end }}
|
||
<h3><a href="{{ .RelPermalink }}" class="card-title-link">{{ .Title }}</a></h3>
|
||
{{ if .Description }}
|
||
<p>{{ .Description }}</p>
|
||
{{ else if .Summary }}
|
||
<p>{{ .Summary | plainify | replaceRE "^### \\*\\*Summary\\*\\*\\s*" "" | truncate 200 }}</p>
|
||
{{ else }}
|
||
<p>{{ .Content | plainify | replaceRE "^### \\*\\*Summary\\*\\*\\s*" "" | truncate 200 }}</p>
|
||
{{ end }}
|
||
{{ if .Params.tags }}
|
||
<div class="tags">
|
||
{{ range .Params.tags }}
|
||
<a href="?tag={{ . | urlize }}" class="tag">{{ . }}</a>
|
||
{{ end }}
|
||
</div>
|
||
{{ end }}
|
||
</div>
|
||
{{ end }}
|
||
</div>
|
||
{{ end }}
|
||
|
||
<style>
|
||
.lead {
|
||
font-size: 1.125rem;
|
||
color: #666;
|
||
margin-bottom: 2rem;
|
||
}
|
||
|
||
.filter-controls {
|
||
margin-bottom: 48px;
|
||
padding: 24px;
|
||
background: var(--card-background);
|
||
border-radius: 16px;
|
||
border: 1px solid var(--border);
|
||
box-shadow: 0 4px 12px var(--shadow);
|
||
}
|
||
|
||
.filter-row {
|
||
display: flex;
|
||
gap: 16px;
|
||
flex-wrap: wrap;
|
||
align-items: center;
|
||
}
|
||
|
||
.search-input {
|
||
font-family: 'Space Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||
font-weight: 400;
|
||
font-size: 14px;
|
||
padding: 10px 16px;
|
||
border: 1px solid var(--border);
|
||
border-radius: 24px;
|
||
background: rgba(255, 255, 255, 0.9);
|
||
backdrop-filter: blur(8px);
|
||
transition: all 0.2s ease;
|
||
color: var(--text-primary);
|
||
flex: 1;
|
||
min-width: 280px;
|
||
}
|
||
|
||
.search-input:focus {
|
||
outline: none;
|
||
border-color: var(--e2c-yellow);
|
||
background: var(--e2c-yellow);
|
||
transform: translateY(-1px);
|
||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||
}
|
||
|
||
.search-input::placeholder {
|
||
color: var(--text-primary);
|
||
font-weight: 400;
|
||
}
|
||
|
||
/* Custom Multi-Select Dropdown */
|
||
.tag-filter-container {
|
||
position: relative;
|
||
min-width: 200px;
|
||
}
|
||
|
||
.tag-dropdown {
|
||
position: relative;
|
||
font-family: 'Space Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||
}
|
||
|
||
.tag-dropdown-trigger {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 10px 16px;
|
||
border: 1px solid var(--border);
|
||
border-radius: 24px;
|
||
background: rgba(255, 255, 255, 0.9);
|
||
backdrop-filter: blur(8px);
|
||
cursor: pointer;
|
||
transition: all 0.2s ease;
|
||
color: var(--text-primary);
|
||
font-size: 14px;
|
||
font-weight: 400;
|
||
min-height: 20px;
|
||
}
|
||
|
||
.tag-dropdown-trigger:hover, .tag-dropdown.open .tag-dropdown-trigger {
|
||
border-color: var(--e2c-yellow);
|
||
background: var(--e2c-yellow);
|
||
transform: translateY(-1px);
|
||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||
}
|
||
|
||
.dropdown-label {
|
||
flex: 1;
|
||
color: var(--text-primary);
|
||
font-weight: 400;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.tag-dropdown.has-selection .dropdown-label {
|
||
display: none;
|
||
}
|
||
|
||
.selected-tags {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 4px;
|
||
flex: 1;
|
||
min-height: 20px;
|
||
}
|
||
|
||
.selected-tag {
|
||
background: var(--text-primary);
|
||
color: white;
|
||
padding: 2px 8px;
|
||
border-radius: 12px;
|
||
font-size: 12px;
|
||
font-weight: 500;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 4px;
|
||
}
|
||
|
||
.selected-tag .remove {
|
||
cursor: pointer;
|
||
font-weight: bold;
|
||
font-size: 14px;
|
||
line-height: 1;
|
||
opacity: 0.8;
|
||
}
|
||
|
||
.selected-tag .remove:hover {
|
||
opacity: 1;
|
||
}
|
||
|
||
.dropdown-arrow {
|
||
margin-left: 8px;
|
||
transition: transform 0.2s ease;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.tag-dropdown.open .dropdown-arrow {
|
||
transform: rotate(180deg);
|
||
}
|
||
|
||
.tag-dropdown-menu {
|
||
position: absolute;
|
||
top: 100%;
|
||
left: 0;
|
||
right: 0;
|
||
background: var(--card-background);
|
||
border: 1px solid var(--border);
|
||
border-radius: 12px;
|
||
box-shadow: 0 8px 24px var(--shadow);
|
||
z-index: 1000;
|
||
max-height: 200px;
|
||
overflow-y: auto;
|
||
opacity: 0;
|
||
visibility: hidden;
|
||
transform: translateY(-4px);
|
||
transition: all 0.2s ease;
|
||
margin-top: 4px;
|
||
}
|
||
|
||
.tag-dropdown.open .tag-dropdown-menu {
|
||
opacity: 1;
|
||
visibility: visible;
|
||
transform: translateY(0);
|
||
}
|
||
|
||
.tag-option {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 8px 12px;
|
||
cursor: pointer;
|
||
font-size: 14px;
|
||
color: var(--text-primary);
|
||
transition: background-color 0.15s ease;
|
||
}
|
||
|
||
.tag-option:hover {
|
||
background: rgba(244, 208, 63, 0.1);
|
||
}
|
||
|
||
.tag-option input[type="checkbox"] {
|
||
margin-right: 8px;
|
||
accent-color: var(--e2c-yellow);
|
||
}
|
||
|
||
.tag-option.selected {
|
||
background: rgba(244, 208, 63, 0.15);
|
||
font-weight: 500;
|
||
}
|
||
|
||
/* Custom Sort Dropdown */
|
||
.sort-container {
|
||
position: relative;
|
||
min-width: 160px;
|
||
}
|
||
|
||
.sort-dropdown {
|
||
position: relative;
|
||
font-family: 'Space Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||
}
|
||
|
||
.sort-dropdown-trigger {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 10px 16px;
|
||
border: 1px solid var(--border);
|
||
border-radius: 24px;
|
||
background: rgba(255, 255, 255, 0.9);
|
||
backdrop-filter: blur(8px);
|
||
cursor: pointer;
|
||
transition: all 0.2s ease;
|
||
color: var(--text-primary);
|
||
font-size: 14px;
|
||
font-weight: 400;
|
||
min-height: 20px;
|
||
}
|
||
|
||
.sort-dropdown-trigger:hover, .sort-dropdown.open .sort-dropdown-trigger {
|
||
border-color: var(--e2c-yellow);
|
||
background: var(--e2c-yellow);
|
||
transform: translateY(-1px);
|
||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||
}
|
||
|
||
.sort-label {
|
||
flex: 1;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.sort-dropdown.open .dropdown-arrow {
|
||
transform: rotate(180deg);
|
||
}
|
||
|
||
.sort-dropdown-menu {
|
||
position: absolute;
|
||
top: 100%;
|
||
left: 0;
|
||
right: 0;
|
||
background: var(--card-background);
|
||
border: 1px solid var(--border);
|
||
border-radius: 12px;
|
||
box-shadow: 0 8px 24px var(--shadow);
|
||
z-index: 1000;
|
||
opacity: 0;
|
||
visibility: hidden;
|
||
transform: translateY(-4px);
|
||
transition: all 0.2s ease;
|
||
margin-top: 4px;
|
||
}
|
||
|
||
.sort-dropdown.open .sort-dropdown-menu {
|
||
opacity: 1;
|
||
visibility: visible;
|
||
transform: translateY(0);
|
||
}
|
||
|
||
.sort-option {
|
||
padding: 8px 12px;
|
||
cursor: pointer;
|
||
font-size: 14px;
|
||
color: var(--text-primary);
|
||
transition: background-color 0.15s ease;
|
||
}
|
||
|
||
.sort-option:hover {
|
||
background: rgba(244, 208, 63, 0.1);
|
||
}
|
||
|
||
.sort-option.selected {
|
||
background: rgba(244, 208, 63, 0.15);
|
||
font-weight: 500;
|
||
}
|
||
|
||
.tags {
|
||
margin-top: 0.5rem;
|
||
}
|
||
|
||
.tag {
|
||
display: inline-block;
|
||
background: #e9ecef;
|
||
color: #495057;
|
||
padding: 0.25rem 0.5rem;
|
||
margin: 0.25rem 0.25rem 0 0;
|
||
border-radius: 0.25rem;
|
||
font-size: 0.875rem;
|
||
text-decoration: none;
|
||
transition: all 0.2s ease;
|
||
}
|
||
|
||
.tag:hover {
|
||
background: var(--e2c-yellow);
|
||
color: var(--text-primary);
|
||
transform: translateY(-1px);
|
||
}
|
||
|
||
.card-title-link {
|
||
display: inline-block;
|
||
padding: 8px 16px;
|
||
background: var(--e2c-yellow);
|
||
color: var(--text-primary) !important;
|
||
text-decoration: none !important;
|
||
border-radius: 12px;
|
||
margin: 8px 0;
|
||
font-weight: 600;
|
||
font-size: 1.25rem;
|
||
transition: all 0.2s ease;
|
||
border: 2px solid var(--e2c-yellow);
|
||
}
|
||
|
||
.card-title-link:hover {
|
||
background: var(--e2c-dark-yellow);
|
||
border-color: var(--e2c-dark-yellow);
|
||
color: var(--text-primary) !important;
|
||
transform: translateY(-1px);
|
||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||
}
|
||
|
||
.card {
|
||
transition: opacity 0.3s ease, transform 0.3s ease;
|
||
}
|
||
|
||
.card.hidden {
|
||
display: none;
|
||
}
|
||
|
||
.card-banner {
|
||
position: relative;
|
||
margin-bottom: 1rem;
|
||
border-radius: 12px;
|
||
overflow: hidden;
|
||
aspect-ratio: 16/9;
|
||
}
|
||
|
||
.case-banner {
|
||
width: 100%;
|
||
height: 100%;
|
||
object-fit: cover;
|
||
display: block;
|
||
}
|
||
|
||
|
||
.card-banner-link, .card-logo-link {
|
||
display: block;
|
||
text-decoration: none;
|
||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||
}
|
||
|
||
.card-banner-link:hover, .card-logo-link:hover {
|
||
transform: translateY(-2px);
|
||
}
|
||
|
||
.card-banner-link:hover .card-banner {
|
||
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
|
||
}
|
||
|
||
.card-logo-link:hover .case-logo {
|
||
transform: scale(1.05);
|
||
}
|
||
|
||
@media (max-width: 768px) {
|
||
.filter-controls {
|
||
margin-bottom: 32px;
|
||
padding: 16px;
|
||
}
|
||
|
||
.filter-row {
|
||
flex-direction: column;
|
||
align-items: stretch;
|
||
gap: 12px;
|
||
}
|
||
|
||
.search-input {
|
||
width: 100%;
|
||
min-width: unset;
|
||
padding: 8px 14px;
|
||
font-size: 12px;
|
||
}
|
||
|
||
.tag-filter-container, .sort-container {
|
||
min-width: unset;
|
||
width: 100%;
|
||
}
|
||
|
||
.sort-dropdown-trigger {
|
||
padding: 8px 14px;
|
||
font-size: 12px;
|
||
}
|
||
|
||
.tag-dropdown-trigger {
|
||
padding: 8px 14px;
|
||
font-size: 12px;
|
||
}
|
||
|
||
.selected-tag {
|
||
font-size: 11px;
|
||
padding: 1px 6px;
|
||
}
|
||
|
||
.tag-dropdown-menu {
|
||
left: -4px;
|
||
right: -4px;
|
||
}
|
||
}
|
||
</style>
|
||
|
||
<script>
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
const searchInput = document.getElementById('searchInput');
|
||
const tagDropdown = document.getElementById('tagDropdown');
|
||
const tagDropdownTrigger = tagDropdown.querySelector('.tag-dropdown-trigger');
|
||
const tagDropdownMenu = document.getElementById('tagDropdownMenu');
|
||
const tagOptions = document.getElementById('tagOptions');
|
||
const selectedTagsContainer = document.getElementById('selectedTags');
|
||
const sortDropdown = document.getElementById('sortDropdown');
|
||
const sortDropdownTrigger = sortDropdown.querySelector('.sort-dropdown-trigger');
|
||
const sortDropdownMenu = document.getElementById('sortDropdownMenu');
|
||
const sortLabel = sortDropdown.querySelector('.sort-label');
|
||
const cardGrid = document.getElementById('cardGrid');
|
||
const cards = Array.from(cardGrid.querySelectorAll('.card'));
|
||
|
||
let selectedTags = new Set();
|
||
let currentSort = 'title';
|
||
|
||
// Check for URL parameter to pre-filter by tag
|
||
const urlParams = new URLSearchParams(window.location.search);
|
||
const preSelectedTag = urlParams.get('tag');
|
||
if (preSelectedTag) {
|
||
selectedTags.add(preSelectedTag);
|
||
}
|
||
|
||
// Collect all unique tags
|
||
const allTags = new Set();
|
||
cards.forEach(card => {
|
||
const tags = card.dataset.tags;
|
||
if (tags) {
|
||
tags.split(',').forEach(tag => allTags.add(tag.trim()));
|
||
}
|
||
});
|
||
|
||
// Populate tag dropdown
|
||
function populateTagOptions() {
|
||
tagOptions.innerHTML = '';
|
||
Array.from(allTags).sort().forEach(tag => {
|
||
const option = document.createElement('div');
|
||
option.className = 'tag-option';
|
||
option.innerHTML = `
|
||
<input type="checkbox" ${selectedTags.has(tag) ? 'checked' : ''}>
|
||
<span>${tag}</span>
|
||
`;
|
||
|
||
const checkbox = option.querySelector('input');
|
||
checkbox.addEventListener('change', function() {
|
||
if (checkbox.checked) {
|
||
selectedTags.add(tag);
|
||
} else {
|
||
selectedTags.delete(tag);
|
||
}
|
||
updateSelectedTagsDisplay();
|
||
filterAndSort();
|
||
updateURL();
|
||
});
|
||
|
||
tagOptions.appendChild(option);
|
||
});
|
||
}
|
||
|
||
// Update selected tags display
|
||
function updateSelectedTagsDisplay() {
|
||
selectedTagsContainer.innerHTML = '';
|
||
|
||
if (selectedTags.size > 0) {
|
||
tagDropdown.classList.add('has-selection');
|
||
|
||
selectedTags.forEach(tag => {
|
||
const tagElement = document.createElement('div');
|
||
tagElement.className = 'selected-tag';
|
||
tagElement.innerHTML = `
|
||
<span>${tag}</span>
|
||
<span class="remove">×</span>
|
||
`;
|
||
|
||
tagElement.querySelector('.remove').addEventListener('click', function(e) {
|
||
e.stopPropagation();
|
||
selectedTags.delete(tag);
|
||
updateSelectedTagsDisplay();
|
||
updateTagOptionStates();
|
||
filterAndSort();
|
||
updateURL();
|
||
});
|
||
|
||
selectedTagsContainer.appendChild(tagElement);
|
||
});
|
||
} else {
|
||
tagDropdown.classList.remove('has-selection');
|
||
}
|
||
}
|
||
|
||
// Update checkbox states in dropdown
|
||
function updateTagOptionStates() {
|
||
const checkboxes = tagOptions.querySelectorAll('input[type="checkbox"]');
|
||
checkboxes.forEach((checkbox, index) => {
|
||
const tag = Array.from(allTags).sort()[index];
|
||
checkbox.checked = selectedTags.has(tag);
|
||
checkbox.parentElement.classList.toggle('selected', selectedTags.has(tag));
|
||
});
|
||
}
|
||
|
||
// Toggle dropdown
|
||
tagDropdownTrigger.addEventListener('click', function(e) {
|
||
e.stopPropagation();
|
||
tagDropdown.classList.toggle('open');
|
||
});
|
||
|
||
// Close dropdown when clicking outside
|
||
document.addEventListener('click', function(e) {
|
||
if (!tagDropdown.contains(e.target)) {
|
||
tagDropdown.classList.remove('open');
|
||
}
|
||
if (!sortDropdown.contains(e.target)) {
|
||
sortDropdown.classList.remove('open');
|
||
}
|
||
});
|
||
|
||
// Sort dropdown functionality
|
||
sortDropdownTrigger.addEventListener('click', function(e) {
|
||
e.stopPropagation();
|
||
sortDropdown.classList.toggle('open');
|
||
tagDropdown.classList.remove('open'); // Close other dropdown
|
||
});
|
||
|
||
// Sort option selection
|
||
sortDropdownMenu.addEventListener('click', function(e) {
|
||
if (e.target.classList.contains('sort-option')) {
|
||
const value = e.target.dataset.value;
|
||
const text = e.target.textContent;
|
||
|
||
// Update current sort
|
||
currentSort = value;
|
||
sortLabel.textContent = text;
|
||
|
||
// Update selected state
|
||
sortDropdownMenu.querySelectorAll('.sort-option').forEach(option => {
|
||
option.classList.remove('selected');
|
||
});
|
||
e.target.classList.add('selected');
|
||
|
||
// Close dropdown and filter
|
||
sortDropdown.classList.remove('open');
|
||
filterAndSort();
|
||
}
|
||
});
|
||
|
||
// Update URL with selected tags
|
||
function updateURL() {
|
||
const url = new URL(window.location);
|
||
if (selectedTags.size > 0) {
|
||
url.searchParams.set('tag', Array.from(selectedTags)[0]); // For simplicity, just use first tag in URL
|
||
} else {
|
||
url.searchParams.delete('tag');
|
||
}
|
||
window.history.replaceState({}, '', url);
|
||
}
|
||
|
||
function filterAndSort() {
|
||
const searchTerm = searchInput.value.toLowerCase();
|
||
const sortCriteria = currentSort;
|
||
|
||
// Filter cards
|
||
const filteredCards = cards.filter(card => {
|
||
const title = card.dataset.title.toLowerCase();
|
||
const description = card.dataset.description.toLowerCase();
|
||
const content = card.dataset.content.toLowerCase();
|
||
const tags = card.dataset.tags;
|
||
|
||
// Full text search - search in title, description, and content
|
||
const matchesSearch = !searchTerm ||
|
||
title.includes(searchTerm) ||
|
||
description.includes(searchTerm) ||
|
||
content.includes(searchTerm);
|
||
|
||
// Tag filter - must match ALL selected tags
|
||
const matchesTags = selectedTags.size === 0 ||
|
||
(tags && Array.from(selectedTags).every(selectedTag =>
|
||
tags.split(',').map(t => t.trim()).includes(selectedTag)
|
||
));
|
||
|
||
return matchesSearch && matchesTags;
|
||
});
|
||
|
||
// Sort filtered cards
|
||
filteredCards.sort((a, b) => {
|
||
if (sortCriteria === 'title') {
|
||
return a.dataset.title.localeCompare(b.dataset.title);
|
||
} else if (sortCriteria === 'date') {
|
||
const dateA = new Date(a.dataset.date || '1970-01-01');
|
||
const dateB = new Date(b.dataset.date || '1970-01-01');
|
||
return dateB - dateA; // Most recent first
|
||
}
|
||
return 0;
|
||
});
|
||
|
||
// Hide all cards first
|
||
cards.forEach(card => card.classList.add('hidden'));
|
||
|
||
// Show and reorder filtered cards
|
||
filteredCards.forEach((card, index) => {
|
||
card.classList.remove('hidden');
|
||
card.style.order = index;
|
||
});
|
||
}
|
||
|
||
// Event listeners
|
||
searchInput.addEventListener('input', filterAndSort);
|
||
|
||
// Initialize
|
||
populateTagOptions();
|
||
updateSelectedTagsDisplay();
|
||
updateTagOptionStates();
|
||
|
||
// Initialize sort dropdown
|
||
sortDropdownMenu.querySelector('[data-value="title"]').classList.add('selected');
|
||
|
||
filterAndSort();
|
||
});
|
||
</script>
|
||
{{ end }} |