59 lines
1.9 KiB
JavaScript
59 lines
1.9 KiB
JavaScript
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);
|
|
};
|
|
|
|
const closeModal = useCallback(() => {
|
|
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}>
|
|
{filteredProjects.map((project) => (
|
|
<ProjectCard key={project.id} project={project} onClick={openModal} className={animatingOut ? styles.fadeOut : styles.fadeIn} />
|
|
))}
|
|
</div>
|
|
{selectedProject && <ProjectModal project={selectedProject} onClose={closeModal} />}
|
|
</section>
|
|
);
|
|
}
|
|
|
|
export default Projects;
|