mirror of
https://git.kh3group.com/georgebiri/kh3_website.git
synced 2026-07-02 07:03:46 +00:00
130 lines
4 KiB
JavaScript
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();
|
|
}
|
|
});
|
|
|