-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
106 lines (90 loc) · 3.1 KB
/
Copy pathscript.js
File metadata and controls
106 lines (90 loc) · 3.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
let tools = [];
let activeTag = "all";
let searchQuery = "";
async function loadTools() {
const res = await fetch("tools.json");
tools = await res.json();
buildTagFilters();
renderTools();
}
function buildTagFilters() {
const tagSet = new Set();
tools.forEach((t) => t.tags.forEach((tag) => tagSet.add(tag)));
const container = document.getElementById("tag-filters");
tagSet.forEach((tag) => {
const btn = document.createElement("button");
btn.className = "btn btn-tag me-2 mb-2";
btn.dataset.tag = tag;
btn.textContent = `#${tag}`;
btn.addEventListener("click", () => setTag(tag, btn));
container.appendChild(btn);
});
document.querySelector('[data-tag="all"]').addEventListener("click", (e) => {
setTag("all", e.currentTarget);
});
}
function setTag(tag, btn) {
activeTag = tag;
document
.querySelectorAll(".btn-tag")
.forEach((b) => b.classList.remove("active"));
btn.classList.add("active");
renderTools();
}
function renderTools() {
const grid = document.getElementById("tools-grid");
const emptyState = document.getElementById("empty-state");
const countEl = document.getElementById("tool-count");
const filtered = tools.filter((tool) => {
const matchesTag = activeTag === "all" || tool.tags.includes(activeTag);
const matchesSearch =
searchQuery === "" ||
tool.name.toLowerCase().includes(searchQuery) ||
tool.description.toLowerCase().includes(searchQuery) ||
tool.tags.some((t) => t.includes(searchQuery));
return matchesTag && matchesSearch;
});
grid.innerHTML = "";
if (filtered.length === 0) {
emptyState.classList.remove("d-none");
countEl.textContent = "0 tools";
return;
}
emptyState.classList.add("d-none");
countEl.textContent = `${filtered.length} tool${filtered.length !== 1 ? "s" : ""}`;
filtered.forEach((tool) => {
const tagsHTML = tool.tags
.map(
(tag) =>
`<span class="tag-badge me-1" onclick="filterByTag('${tag}')">#${tag}</span>`,
)
.join("");
const col = document.createElement("div");
col.className = "col-12 col-sm-6 col-lg-4";
col.innerHTML = `
<div class="tool-card card p-3 d-flex flex-column">
<div class="card-body d-flex flex-column p-0">
<h6 class="card-title mb-1">${tool.name}</h6>
<p class="card-text flex-grow-1 mb-3">${tool.description}</p>
<div class="mb-3">${tagsHTML}</div>
<a href="${tool.website}" target="_blank" rel="noopener" class="btn btn-visit align-self-start">
<i class="bi bi-box-arrow-up-right me-1"></i> Visit
</a>
</div>
</div>
`;
grid.appendChild(col);
});
}
function filterByTag(tag) {
activeTag = tag;
document.querySelectorAll(".btn-tag").forEach((b) => {
b.classList.toggle("active", b.dataset.tag === tag);
});
renderTools();
}
document.getElementById("search-input").addEventListener("input", (e) => {
searchQuery = e.target.value.toLowerCase().trim();
renderTools();
});
loadTools();