v0.7.0 Add filtering feature in projects to filter project cards based on categories
This commit is contained in:
parent
ff04802a61
commit
5a4c05fcba
7 changed files with 130 additions and 7 deletions
|
|
@ -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} />}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue