Newer
Older
My-Portfolio / frontend / src / components / sections / Skills.jsx
import React, { useState, useContext } from "react";
import { motion } from "framer-motion";
import Container from "../sections/projects/Container";
import HoverableSkillList from "../sections/projects/HoverableSkill";
import Heading from "../Heading";
import { pdf } from "../../assets/index";
import { LoadingContext } from "../utils/LoadingContext";
import NavigationDots from "../utils/NavigationDots";

const Skills = ({ isVisible, skillsData }) => {
  const [hoveredItem, setHoveredItem] = useState({
    section: null,
    index: null,
  }); // Track section and index
  const { isLoading } = useContext(LoadingContext);

  // Fallback if skillsData or its nested properties are undefined
  if (isLoading) return <div>Loading...</div>;
  if (!skillsData || !skillsData.skills) return <div>No skills data found</div>;

  // Group tools by type
  const groupedTools = skillsData.skills.tools?.reduce((acc, tool) => {
    if (!acc[tool.type]) acc[tool.type] = [];
    acc[tool.type].push(tool);
    return acc;
  }, {});

  return (
    <motion.div
      className="relative z-2 pt-2 sm:pt-10"
      id="skills"
      initial={{ opacity: 0, y: 100 }}
      animate={isVisible ? { opacity: 1, y: 0 } : { opacity: 0, y: 100 }}
      transition={{ duration: 0.2, ease: "easeOut" }}
    >
      <Heading
        title="My Skills"
        highlightWords={[{ word: "Skills", color: "text-orange-500" }]}
      />
      <NavigationDots currentSectionId="skills" />
      <div className="text-white flex flex-col">
        <div className="flex flex-wrap gap-6 justify-center mb-10">
          {/* Tech Section */}
          {skillsData.skills.techs && (
            <Container
              noBackground
              className="relative max-w-[400px]"
              shadow={false}
            >
              <HoverableSkillList
                title="Tech"
                items={skillsData.skills.techs}
                color="orange"
                hoveredItem={hoveredItem}
                setHoveredItem={setHoveredItem}
                section="tech" // Unique section identifier
                getKey={(item, index) => `tech-${index}`}
                isVisible={isVisible}
              />
            </Container>
          )}
          {/* Tools Section */}
          {groupedTools &&
            Object.entries(groupedTools).map(([toolType, tools]) => (
              <Container
                key={toolType}
                noBackground
                className="relative max-w-[400px]"
                shadow={false}
              >
                <HoverableSkillList
                  title={`${toolType} Tools`}
                  items={tools}
                  color="orange"
                  hoveredItem={hoveredItem}
                  setHoveredItem={setHoveredItem}
                  section={`tools-${toolType}`} // Unique section identifier
                  getKey={(item, index) => `${toolType}-${index}`}
                  isVisible={isVisible}
                />
              </Container>
            ))}

          {/* Programming Languages Section */}
          {skillsData.skills.languages && (
            <Container
              noBackground
              className="min-w-[280px] max-w-auto lg:max-w-[400px]"
              shadow={false}
            >
              <HoverableSkillList
                title="Languages"
                items={skillsData.skills.languages}
                color="orange"
                hoveredItem={hoveredItem}
                setHoveredItem={setHoveredItem}
                section="languages" // Unique section identifier
                getKey={(item, index) => `language-${item.id || index}`}
                isVisible={isVisible}
              />
            </Container>
          )}

          {/* Databases Section */}
          {skillsData.skills.databases && (
            <Container
              noBackground
              className="min-w-[280px] max-w-auto lg:max-w-[400px]"
              shadow={false}
            >
              <HoverableSkillList
                title="Databases"
                items={skillsData.skills.databases}
                color="orange"
                hoveredItem={hoveredItem}
                setHoveredItem={setHoveredItem}
                section="databases"
                getKey={(item, index) => `database-${item.id || index}`}
                isVisible={isVisible}
              />
            </Container>
          )}
        </div>

        {/* Experience Section */}
        <Heading
          title="My Experience"
          className="relative text-4xl lg:text-5xl font-bold mb-16 pt-72"
          highlightWords={[{ word: "Experience", color: "text-orange-500" }]}
        />
        <div className="flex flex-wrap gap-6 mb-10">
          {/* Academic Experience */}
          {skillsData.experience?.academic?.length > 0 && (
            <>
              <div className="flex lg:justify-start sm:justify-center items-center mb-2 mx-6 lg:mx-52">
                {/* Education Section Header */}
                <img
                  src={
                    skillsData.logos?.find((logo) => logo.academic)?.academic
                  }
                  alt="Education logo"
                  className="w-10 h-10 lg:w-14 lg:h-14 object-contain mr-4"
                />
                <h3 className="text-2xl sm:text-3xl font-semibold">
                  Education
                </h3>
              </div>

              {skillsData.experience.academic.map((exp, index) => (
                <Container
                  key={`academic-${index}`}
                  className="relative bg-black/60 flex flex-col mb-8 mx-6 lg:mx-52 w-full p-6 rounded-lg shadow-lg"
                >
                  {/* Top Row: Logo + Info */}
                  <div className="flex items-center gap-4">
                    {/* Logo */}
                    {exp.logo && (
                      <img
                        src={exp.logo}
                        alt="Academic logo"
                        className="w-16 sm:w-20 md:w-24 lg:w-32 rounded-full"
                      />
                    )}

                    {/* Info (Title, Organization, Dates) */}
                    <div className="flex flex-col">
                      {/* Title */}
                      <h4 className="text-base sm:text-2xl text-orange-400 font-bold">
                        {exp.name}
                      </h4>

                      {/* Organization */}
                      <p className="text-sm sm:text-lg text-gray-400">
                        {exp.org}
                      </p>

                      {/* Dates */}
                      <p className="text-xs sm:text-sm text-gray-300 mt-1">
                        {exp.start_date
                          ? new Date(exp.start_date).toLocaleDateString()
                          : "Unknown"}{" "}
                        -{" "}
                        {exp.end_date
                          ? new Date(exp.end_date).toLocaleDateString()
                          : "Present"}
                      </p>
                    </div>
                  </div>

                  {/* Description (Below Top Row) */}
                  <p
                    className="text-sm sm:text-base mt-4"
                    dangerouslySetInnerHTML={{ __html: exp.description }}
                  ></p>

                  {/* Skills (Below Description) */}
                  {exp.skills && (
                    <div className="flex flex-wrap gap-2 mt-4">
                      {/* Techs */}
                      {exp.skills.techs?.map((tech, index) => (
                        <span
                          key={`tech-${index}`}
                          className="bg-[#4a4a4a] text-[#d4d4d4] text-sm px-3 py-1 rounded-md hover:bg-[#6a6a6a]"
                        >
                          {tech}
                        </span>
                      ))}

                      {/* Tools */}
                      {exp.skills.tools?.map((tool, index) => (
                        <span
                          key={`tool-${index}`}
                          className="bg-[#4a4a4a] text-[#d4d4d4] text-sm px-3 py-1 rounded-md hover:bg-[#6a6a6a]"
                        >
                          {tool}
                        </span>
                      ))}

                      {/* Languages */}
                      {exp.skills.languages?.map((language, index) => (
                        <span
                          key={`language-${index}`}
                          className="bg-[#4a4a4a] text-[#d4d4d4] text-sm px-3 py-1 rounded-md hover:bg-[#6a6a6a]"
                        >
                          {language}
                        </span>
                      ))}
                    </div>
                  )}
                </Container>
              ))}
            </>
          )}

          {/* Professional Experience */}
          {skillsData.experience?.professional?.length > 0 && (
            <>
              <div className="flex items-center mb-10">
                {" "}
                {/* Flex container for logo and title */}
                <img
                  src={
                    skillsData.logos?.find((logo) => logo.professional)
                      ?.professional
                  }
                  alt="logo"
                  color="white"
                  className="w-12 h-12 sm:w-16 sm:h-16 object-contain mr-4"
                />
                <h3 className="text-3xl font-semibold">Professional</h3>
              </div>
              {skillsData.experience.professional.map((exp, index) => (
                <Container
                  key={`professional-${index}`}
                  className="relative p-6 bg-gray-900 justify-center rounded-lg shadow-lg flex flex-col sm:flex-row sm:gap-6"
                >
                  {/* Thumbnail (Left) */}
                  {exp.logo && (
                    <img
                      src={exp.logo}
                      alt="Professional logo"
                      className="w-24 h-24 sm:w-32 sm:h-32 object-contain rounded-lg"
                    />
                  )}

                  {/* Content (Right) */}
                  <div className="flex flex-col justify-center flex-1 text-left sm:pl-6">
                    {/* Title */}
                    <h4 className="text-xl sm:text-2xl text-orange-400 font-bold">
                      {exp.title}
                    </h4>

                    {/* Organization */}
                    <p className="text-sm sm:text-lg text-gray-400">
                      {exp.org}
                    </p>

                    {/* Dates */}
                    <p className="text-xs sm:text-sm text-gray-300 mt-1">
                      {exp.start_date
                        ? new Date(exp.start_date).toLocaleDateString()
                        : "Unknown"}{" "}
                      -{" "}
                      {exp.end_date
                        ? new Date(exp.end_date).toLocaleDateString()
                        : "Present"}
                    </p>

                    {/* Description */}
                    <p className="text-sm sm:text-base mt-2">
                      {exp.description}
                    </p>
                  </div>
                </Container>
              ))}
            </>
          )}
        </div>
        <h2 className="text-2xl sm:text-3xl font-semibold text-center mb-5">
          Resume Download
        </h2>
        <div className="relative self-center justify-center bg-black/60 items-center p-4 rounded-lg mb-5 transition-shadow duration-150 hover:shadow-[0_0_30px_rgba(255,255,255,0.6)]">
          <a
            href="https://drive.google.com/file/d/1CCl9T4pHoPJ3KNcGz0XUIfGGf7o5X_vj/view?usp=drive_link"
            target="_blank"
            rel="noopener noreferrer"
            className="flex items-center justify-center space-x-2"
          >
            <img src={pdf} alt="PDF Logo" className="w-10 sm:w-12" />
            <span className="text-white font-bold text-xl sm:text-2xl px-4 py-1">
              Resume
            </span>
          </a>
        </div>
      </div>
    </motion.div>
  );
};

export default Skills;