Newer
Older
My-Portfolio / frontend / src / components / sections / Work.jsx
import { useState, useEffect, useContext } from "react";
import { motion } from "framer-motion";
import { TAG_HIERARCHY } from "../utils/helpers";
import "./Work.css";
import ProjectCard from "../ProjectCard";
import { tag_icon } from "../../assets";
import Heading from "../Heading";
import { LoadingContext } from "../utils/LoadingContext";

const Work = ({ isVisible, projects }) => {
  const [activeCategory, setActiveCategory] = useState("All");
  const [selectedTags, setSelectedTags] = useState([]);
  const [hoveredProjectId, setHoveredProjectId] = useState(null);
  const [filteredProjects, setFilteredProjects] = useState([]);

  const { isLoading } = useContext(LoadingContext); // Use the global loading state

  if (isLoading) return <div>Loading...</div>;

  useEffect(() => {
    const filterProjectsByTags = () => {
      const filtered = projects.filter((project) => {
        const matchesCategory =
          activeCategory === "All" ||
          project.category === activeCategory ||
          project.tech === activeCategory;

        const matchesTags =
          selectedTags.length === 0 ||
          selectedTags.every(
            (tag) => project.tags?.includes(tag) || project.tech?.includes(tag)
          );

        return matchesCategory && matchesTags;
      });
      setFilteredProjects(filtered);
    };

    filterProjectsByTags();
  }, [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"
      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" />

      <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 }}
        >
          {Object.entries(TAG_HIERARCHY).map(([category, data]) => (
            <motion.button
              key={category}
              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
                  ? "bg-orange-500 text-white font-bold"
                  : "bg-black text-gray-200 hover:bg-gray-600"
              }`}
            >
              <img
                src={data.logo}
                alt={`${category} Logo`}
                className="w-6 h-6 lg:w-8 lg:h-8"
              />
              {category}
            </motion.button>
          ))}
        </motion.div>

        {TAG_HIERARCHY[activeCategory]?.subtags?.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 }}
          >
            {TAG_HIERARCHY[activeCategory].subtags.map((tag) => (
              <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;