v0.7.0 Add filtering feature in projects to filter project cards based on categories

This commit is contained in:
Murtadha 2024-07-15 15:09:00 -04:00
parent ff04802a61
commit 5a4c05fcba
7 changed files with 130 additions and 7 deletions

View file

@ -1,10 +1,12 @@
import React, { useState, useCallback } from "react";
import React, { useState, useCallback, useMemo } from "react";
import ProjectCard from "./projectCard/ProjectCard";
import ProjectModal from "./projectModal/ProjectModal";
import styles from "./Projects.module.css";
function Projects({ title, data }) {
const [selectedProject, setSelectedProject] = useState(null);
const [activeFilter, setActiveFilter] = useState("All");
const [animatingOut, setAnimatingOut] = useState(false);
const openModal = (project) => {
setSelectedProject(project);
@ -14,12 +16,39 @@ function Projects({ title, data }) {
setSelectedProject(null);
}, []);
const categories = useMemo(() => {
const cats = new Set(data.map((project) => project.category));
return ["All", ...Array.from(cats)];
}, [data]);
const filteredProjects = useMemo(() => {
if (activeFilter === "All") return data;
return data.filter((project) => project.category === activeFilter);
}, [data, activeFilter]);
const handleFilterClick = (category) => {
if (category !== activeFilter) {
setAnimatingOut(true);
setTimeout(() => {
setActiveFilter(category);
setAnimatingOut(false);
}, 300); // This should match the CSS animation duration
}
};
return (
<section className={styles.projects}>
<h2 className={styles.sectionTitle}>{title}</h2>
<div className={styles.filterContainer}>
{categories.map((category) => (
<button key={category} className={`${styles.filterButton} ${activeFilter === category ? styles.active : ""}`} onClick={() => handleFilterClick(category)}>
{category}
</button>
))}
</div>
<div className={styles.projectGrid}>
{data.map((project) => (
<ProjectCard key={project.id} project={project} onClick={openModal} />
{filteredProjects.map((project) => (
<ProjectCard key={project.id} project={project} onClick={openModal} className={animatingOut ? styles.fadeOut : styles.fadeIn} />
))}
</div>
{selectedProject && <ProjectModal project={selectedProject} onClose={closeModal} />}