//React import { useState, useEffect, useContext } from "react"; //Framer Motion import { motion } from "framer-motion"; //Components import ProjectCard from "../ProjectCard"; //Utils import Heading from "../Heading"; import { LoadingContext } from "../utils/LoadingContext"; import NavigationDots from "../utils/NavigationDots"; //Assets import { tag_icon, all_tags } from "../../assets"; //CSS import "./Work.css"; const Work = ({ isVisible, work }) => { const [activeCategory, setActiveCategory] = useState({ category_id: "All", category_name: "All", category_logo: all_tags, tags: [], }); const [selectedTags, setSelectedTags] = useState([]); const [hoveredProjectId, setHoveredProjectId] = useState(null); const [filteredProjects, setFilteredProjects] = useState([]); const { isLoading } = useContext(LoadingContext); if (!work.categories) { return <div>Loading...</div>; } if (isLoading) return <div>Loading...</div>; const allCategory = { category_id: "All", category_name: "All", category_logo: all_tags, tags: [], }; const categoriesWithAll = [allCategory, ...work.categories]; useEffect(() => { const filterProjectsByTags = () => { const filtered = work.projects.filter((project) => { const matchesCategory = activeCategory.category_name === "All" || project.category === activeCategory.category_name; const matchesTags = selectedTags.length === 0 || selectedTags.every( (tag) => project.tags?.includes(tag) || project.tech?.includes(tag) ); return matchesCategory && matchesTags; }); setFilteredProjects(filtered); }; filterProjectsByTags(); }, [work.projects, activeCategory, selectedTags]); const handleCategoryClick = (category) => { setActiveCategory(category); setSelectedTags([]); }; const handleTagClick = (tag) => { setSelectedTags((prev) => prev.includes(tag) ? prev.filter((t) => t !== tag) : [...prev, tag] ); }; return ( <motion.div className="relative min-h-screen z-2 pt-2 sm:pt-10 sm:px-4" id="work" initial={{ opacity: 0, y: 100 }} // Start off-screen animate={isVisible ? { opacity: 1, y: 0 } : { opacity: 0, y: 100 }} // Slide-in when visible transition={{ duration: 0.2, ease: "easeOut" }} > <Heading title="My Portfolio" highlightWords={[{ word: "Portfolio", color: "text-orange-500" }]} /> <NavigationDots currentSectionId="work" /> <div className="flex flex-col items-center"> <motion.div className="flex flex-wrap gap-8 mb-6 justify-center" initial="hidden" animate="visible" variants={{ hidden: { opacity: 0, y: 50 }, visible: { opacity: 1, y: 0 }, }} transition={{ staggerChildren: 0.1 }} > {categoriesWithAll.map((category) => ( <motion.button key={category.category_id} onClick={() => handleCategoryClick(category)} whileHover={{ scale: 1.1 }} whileTap={{ scale: 0.9 }} className={`flex items-center gap-2 px-6 lg:px-10 py-4 text-xl rounded-lg transition-all duration-200 ${ activeCategory.category_id === category.category_id ? "bg-orange-500 text-white font-bold" : "bg-black text-gray-200 hover:bg-gray-600" }`} > {category.category_logo && ( // Only render the logo if it exists <img src={category.category_logo} alt={`${category.category_name} Logo`} className="w-6 h-6 lg:w-8 lg:h-8" /> )} {category.category_name} </motion.button> ))} </motion.div> {activeCategory.category_name !== "All" && work.categories.find( (cat) => cat.category_id === activeCategory.category_id )?.tags?.length > 0 && ( <motion.div className="flex flex-wrap gap-4 mb-10 justify-center" initial="hidden" animate="visible" variants={{ hidden: { opacity: 0, y: 50 }, visible: { opacity: 1, y: 0 }, }} transition={{ staggerChildren: 0.1 }} > {work.categories .find((cat) => cat.category_id === activeCategory.category_id) ?.tags?.map( ( tag // Map over its tags ) => ( <motion.button key={tag} onClick={() => handleTagClick(tag)} whileHover={{ scale: 1.1 }} whileTap={{ scale: 0.9 }} className={`flex items-center px-4 py-1 rounded-lg transition-all duration-200 ${ selectedTags.includes(tag) ? "bg-orange-500 text-white" : "bg-black text-gray-200 hover:bg-gray-600" }`} > <img src={tag_icon} alt="Tag Logo" className="mr-2 w-4 h-4" /> {tag} </motion.button> ) )} </motion.div> )} <motion.div className="flex flex-wrap justify-center gap-8 px-8 mt-5" initial="hidden" animate="visible" variants={{ hidden: { opacity: 0 }, visible: { opacity: 1, transition: { staggerChildren: 0.2 } }, }} > {filteredProjects.map((project) => ( <ProjectCard key={project.id} project={project} hoveredProjectId={hoveredProjectId} setHoveredProjectId={setHoveredProjectId} /> ))} </motion.div> </div> </motion.div> ); }; export default Work;