()
| 131 | } |
| 132 | |
| 133 | export async function initToolsPage(): Promise<void> { |
| 134 | if (initialized) return; |
| 135 | initialized = true; |
| 136 | |
| 137 | const categoryFilter = document.getElementById( |
| 138 | "filter-category" |
| 139 | ) as HTMLSelectElement; |
| 140 | const clearFiltersBtn = document.getElementById("clear-filters"); |
| 141 | const sortSelect = document.getElementById("sort-select") as HTMLSelectElement; |
| 142 | |
| 143 | const data = await fetchData<ToolsData>("tools.json"); |
| 144 | if (!data || !data.items) { |
| 145 | const container = document.getElementById("tools-list"); |
| 146 | if (container) |
| 147 | container.innerHTML = |
| 148 | '<div class="empty-state"><h3>Failed to load tools</h3></div>'; |
| 149 | return; |
| 150 | } |
| 151 | |
| 152 | // Map items to include title for FuzzySearch |
| 153 | allItems = data.items.map((item) => ({ |
| 154 | ...item, |
| 155 | title: item.name, // FuzzySearch uses title |
| 156 | })); |
| 157 | |
| 158 | // Populate category filter |
| 159 | if (categoryFilter && data.filters.categories) { |
| 160 | categoryFilter.innerHTML = |
| 161 | '<option value="">All Categories</option>' + |
| 162 | data.filters.categories |
| 163 | .map( |
| 164 | (c) => `<option value="${c}">${c}</option>` |
| 165 | ) |
| 166 | .join(""); |
| 167 | |
| 168 | const initialCategory = getQueryParam("category"); |
| 169 | if (initialCategory && data.filters.categories.includes(initialCategory)) { |
| 170 | currentFilters.categories = [initialCategory]; |
| 171 | categoryFilter.value = initialCategory; |
| 172 | } |
| 173 | |
| 174 | categoryFilter.addEventListener("change", () => { |
| 175 | currentFilters.categories = categoryFilter.value |
| 176 | ? [categoryFilter.value] |
| 177 | : []; |
| 178 | applyFiltersAndRender(); |
| 179 | syncUrlState(); |
| 180 | }); |
| 181 | } |
| 182 | |
| 183 | const initialSort = getQueryParam("sort"); |
| 184 | if (initialSort === "title") { |
| 185 | currentSort = initialSort; |
| 186 | if (sortSelect) sortSelect.value = initialSort; |
| 187 | } |
| 188 | sortSelect?.addEventListener("change", () => { |
| 189 | currentSort = sortSelect.value as ToolSortOption; |
| 190 | applyFiltersAndRender(); |
nothing calls this directly
no test coverage detected