diff --git a/src/app/about/page.js b/src/app/about/page.js index f07ad58..0cded19 100644 --- a/src/app/about/page.js +++ b/src/app/about/page.js @@ -1,221 +1,220 @@ -"use client"; - -import { useRef, useState, useEffect } from "react"; +"use client" +import {useRef, useState, useEffect} from "react"; export default function About() { - // Timeline data - const timelineData = [ - { - date: "2018", - title: "First Contact with Coding", - content: - "I discovered my passion for technology by experimenting with Scratch and creating some simple Games.", - }, - { - date: "2020", - title: "Exploring Web & Scripting", - content: - "Started creating small websites and got into JavaScript, CSS, and working with various scripting languages.", - }, - { - date: "2022", - title: "Diving into Game Development", - content: - "Tried Unity and C#, building small 2D and 3D prototypes to expand my skill set.", - }, - { - date: "2024", - title: "Full Stack & Beyond", - content: - "Ventured into backend (SQL, Python) and continued refining my frontend abilities, always exploring new challenges.", - }, - ]; + const timelineData = [ + { + date: "2018", + title: "First Contact with Coding", + content: "I discovered my passion for technology by experimenting with Scratch and creating some simple Games." + }, + { + date: "2022", + title: "Exploring Web Development", + content: "Started creating my first website and got into HTML and CSS." + }, + { + date: "2023", + title: "Diving into Informatics", + content: "Started with Python and basic exploration of 'real' programming." + }, + { + date: "2024", + title: "Full Stack & Beyond", + content: "Ventured into backend (SQL, Python) and frontend using Javascript" + } + ]; - // Disable lint for calling hooks in a loop - // eslint-disable-next-line react-hooks/rules-of-hooks - const sectionRefs = timelineData.map(() => useRef(null)); + const sectionRefs = timelineData.map(() => useRef(null)); + const aboutMeRef = useRef(null); + const [currentSection, setCurrentSection] = useState(0); + const [timelineFinished, setTimelineFinished] = useState(false); + const [isManualScroll, setIsManualScroll] = useState(false); // Track user scrolling + const scrollContainerRef = useRef(null); - const [currentSection, setCurrentSection] = useState(0); + useEffect(() => { + setCurrentSection(0); // Reset timeline + setTimelineFinished(false); - // Keep track if the user has reached the last section in the timeline - const [timelineFinished, setTimelineFinished] = useState(false); + // Ensure 'About Me' is visible on reload + setTimeout(() => { + aboutMeRef.current?.scrollIntoView({ behavior: "smooth", block: "start" }); + }, 100); + }, []); - // Keyboard navigation (left / right arrow keys) - useEffect(() => { - const handleKeyDown = (e) => { - if (e.key === "ArrowRight") { - setCurrentSection((prev) => Math.min(prev + 1, timelineData.length - 1)); - } else if (e.key === "ArrowLeft") { - setCurrentSection((prev) => Math.max(prev - 1, 0)); - } + // Handle button navigation + const handleButtonClick = (direction) => { + setIsManualScroll(false); // Ensure programmatic scrolling happens + setCurrentSection((prev) => { + const newSection = Math.max(0, Math.min(prev + direction, timelineData.length - 1)); + if (newSection === timelineData.length - 1) { + setTimelineFinished(true); + } + return newSection; + }); }; - window.addEventListener("keydown", handleKeyDown); - return () => { - window.removeEventListener("keydown", handleKeyDown); - }; - }, [timelineData.length]); + // Scroll to current section (only if not manually scrolling) + useEffect(() => { + if (!isManualScroll) { + sectionRefs[currentSection]?.current?.scrollIntoView({behavior: "smooth", inline: "start"}); + } + }, [currentSection, isManualScroll]); + useEffect(() => { + const handleScroll = () => { + setIsManualScroll(true); + }; - // Scroll the timeline horizontally to the currently selected section - useEffect(() => { - sectionRefs[currentSection].current?.scrollIntoView({ - behavior: "smooth", - inline: "start", - }); + const scrollContainer = scrollContainerRef.current; + if (scrollContainer) { + scrollContainer.addEventListener("scroll", handleScroll); + } - // If we are on the last section, mark timeline as finished - if (currentSection === timelineData.length - 1) { - setTimelineFinished(true); - } - }, [currentSection, sectionRefs]); + return () => { + if (scrollContainer) { + scrollContainer.removeEventListener("scroll", handleScroll); + } + }; + }, []); - // Navigate left or right with on-screen buttons - const goLeft = () => { - setCurrentSection((prev) => Math.max(prev - 1, 0)); - }; + // Intersection Observer to detect when last section is fully visible + useEffect(() => { + const observer = new IntersectionObserver( + (entries) => { + entries.forEach((entry) => { + if (entry.isIntersecting && entry.target === sectionRefs[timelineData.length - 1].current) { + setTimelineFinished(true); + } + }); + }, + {threshold: 0.8} // Increased threshold to ensure full visibility before triggering + ); - const goRight = () => { - setCurrentSection((prev) => Math.min(prev + 1, timelineData.length - 1)); - }; + sectionRefs.forEach((ref) => { + if (ref.current) observer.observe(ref.current); + }); - return ( -
+ return () => observer.disconnect(); + }, [sectionRefs]); - {/* ───────────────────────────── - 1) Intro / Top Section - ────────────────────────────── */} -
-

About Me

-

- I’m a passionate developer always excited about new challenges. - Scroll down to check out my coding journey through the years! -

-
- - {/* ───────────────────────────── - 2) Timeline Section - ────────────────────────────── */} -
- {/* Only show the left button if we're not on the first section */} - {currentSection > 0 && ( - - )} - - {/* Only show the right button if we're not on the last section */} - {currentSection < timelineData.length - 1 && ( - - )} - - {/* Horizontal scroll area */} -
- {timelineData.map((item, index) => ( + return ( +
+ {/* About Me Section */}
-

{item.title}

-

{item.date}

-

- {item.content} -

+

About Me

+

+ I’m a passionate developer always excited about new challenges. + Scroll down to check out my coding journey through the years! +

- ))} -
-
- {/* ───────────────────────────── - 3) Skills Section - Only visible if timelineFinished - ────────────────────────────── */} - {timelineFinished && ( -
-

My Skills

-

- By completing projects in web development, scripting, and game - design, I’ve cultivated a diverse set of skills — spanning - JavaScript, Python, C#, and more! -

-
- )} -
- ); + {/* Timeline Section */} +
+ {currentSection > 0 && ( + + )} + {currentSection < timelineData.length - 1 && ( + + )} +
+ {timelineData.map((item, index) => ( +
+

{item.title}

+

{item.date}

+

{item.content}

+
+ ))} +
+
+ + {timelineFinished && ( +
+

My Skills

+

+ By completing projects in web development, scripting, and game + design, I’ve cultivated a diverse set of skills — spanning + JavaScript, Python, C#, and more! +

+
+ )} + + ); } \ No newline at end of file