kh3_website/js/projects.js

130 lines
4 KiB
JavaScript

// Projects Page JavaScript
document.addEventListener("DOMContentLoaded", function () {
const pills = document.querySelectorAll("[data-filter]");
const grid = document.querySelector("#projectsGrid");
let projectsData = [];
// Load projects data
async function loadProjects() {
try {
const response = await fetch("/data/projects.json");
projectsData = await response.json();
renderProjects("All");
} catch (error) {
console.error("Error loading projects:", error);
grid.innerHTML =
'<p class="error-message">Error loading projects. Please try again later.</p>';
}
}
// Render projects based on category
function renderProjects(category = "All") {
const filteredProjects =
category === "All"
? projectsData
: projectsData.filter((project) => project.category === category);
grid.classList.add("fade-out");
setTimeout(() => {
grid.innerHTML = filteredProjects
.map(
(project) => `
<div class="project-card" onclick="window.location.href='project-${project.slug}.html'">
<div class="project-card-image" style="background-image: url('${project.coverImage}')">
<div class="project-card-overlay"></div>
</div>
<div class="project-card-content">
<div class="project-card-category">${project.category}</div>
<h3 class="project-card-title">${project.title}</h3>
<p class="project-card-location">${project.location}</p>
<a href="project-${project.slug}.html" class="project-card-link">View Project</a>
</div>
</div>
`
)
.join("");
grid.classList.remove("fade-out");
grid.classList.add("fade-in");
setTimeout(() => {
grid.classList.remove("fade-in");
}, 180);
}, 120);
}
// Handle filter pill clicks
pills.forEach((pill) => {
pill.addEventListener("click", (e) => {
e.preventDefault();
const category = pill.dataset.filter;
// Update pill states
pills.forEach((p) => {
p.setAttribute("aria-pressed", p === pill ? "true" : "false");
});
// Update URL
const url = new URL(location);
if (category === "All") {
url.searchParams.delete("category");
} else {
url.searchParams.set("category", category);
}
history.pushState({}, "", url);
// Render filtered projects
renderProjects(category);
});
});
// Handle browser back/forward
window.addEventListener("popstate", () => {
const category = new URL(location).searchParams.get("category") || "All";
const activePill = document.querySelector(`[data-filter="${category}"]`);
if (activePill) {
pills.forEach((p) => {
p.setAttribute("aria-pressed", p === activePill ? "true" : "false");
});
renderProjects(category);
}
});
// Initialize with URL category if present
const initialCategory =
new URL(location).searchParams.get("category") || "All";
const initialPill = document.querySelector(
`[data-filter="${initialCategory}"]`
);
if (initialPill) {
pills.forEach((p) => {
p.setAttribute("aria-pressed", p === initialPill ? "true" : "false");
});
}
// Load projects on page load
loadProjects();
});
// Keyboard navigation for filter pills
document.addEventListener("keydown", function (e) {
const activePill = document.querySelector('.pill[aria-pressed="true"]');
const pills = Array.from(document.querySelectorAll(".pill"));
const currentIndex = pills.indexOf(activePill);
if (e.key === "ArrowRight" || e.key === "ArrowDown") {
e.preventDefault();
const nextIndex = (currentIndex + 1) % pills.length;
pills[nextIndex].click();
pills[nextIndex].focus();
} else if (e.key === "ArrowLeft" || e.key === "ArrowUp") {
e.preventDefault();
const prevIndex = currentIndex === 0 ? pills.length - 1 : currentIndex - 1;
pills[prevIndex].click();
pills[prevIndex].focus();
}
});