portfolio-website icon indicating copy to clipboard operation
portfolio-website copied to clipboard

My experience is not showing

Open ratulsantra opened this issue 2 years ago • 12 comments

My experience is not showing but tried everything but still same issue. Screenshot (37)

Please anyone help me!

ratulsantra avatar Dec 04 '23 07:12 ratulsantra

Same issue! Can somebody help @ByteGrad

Crazyhaller avatar Dec 04 '23 13:12 Crazyhaller

Resolved it! Add an attribute visible={true} in the VerticalTimelineElement

Crazyhaller avatar Dec 04 '23 13:12 Crazyhaller

adding visible={true} doesn't use the animation shown in @ByteGrad 's tutorial. @ByteGrad can you have a look?

flip-in avatar Dec 18 '23 02:12 flip-in

Update: somethow I was on next v14, after downgrading to next v 13.4.8 it works as shown in the tutorial @Crazyhaller

flip-in avatar Dec 18 '23 03:12 flip-in

below is another solution proposed on the react-vertical-timeline-component repo https://github.com/stephane-monnot/react-vertical-timeline/issues/171

kliffhanger avatar Dec 28 '23 05:12 kliffhanger

Update: somethow I was on next v14, after downgrading to next v 13.4.8 it works as shown in the tutorial @Crazyhaller

It worked just fine for me, must have been some other issue for you then I guess

Crazyhaller avatar Dec 30 '23 18:12 Crazyhaller

Hi! To fix this issue add this to your lib/hooks.ts file

import { useActiveSectionContext } from "@/context/active-section-context";
import { useEffect } from "react";
import { useInView } from "react-intersection-observer";
import type { SectionName } from "./types";

export function useSectionInView(sectionName: SectionName, threshold = 0.75) {
  const { ref, inView } = useInView({
    threshold,
  });
  const { setActiveSection, timeOfLastClick } = useActiveSectionContext();

  useEffect(() => {
    if (inView && Date.now() - timeOfLastClick > 1000) {
      setActiveSection(sectionName);
    }
  }, [inView, setActiveSection, timeOfLastClick, sectionName]);

  return {
    ref, inView //ADDING "inView"
  };
}

and make the following change to your components/experience.tsx file

export default function Experience() {
  const { ref, inView } = useSectionInView("Experience");
  const { theme } = useTheme();
  const [isVisible, setIsVisible] = React.useState(false);

  React.useEffect(() => {
    if (inView) {
      setIsVisible(true);
    }
  }, [inView]);
  
  return (
    <section id="experience" ref={ref} className="scroll-mt-28 mb-28 sm:mb-40">
      <SectionHeading>My experience</SectionHeading>
      <VerticalTimeline lineColor="">
        {experiencesData.map((item, index) => (
          <React.Fragment key={index}>
            <VerticalTimelineElement
              visible={isVisible}   //THIS WAS ADDED
              contentStyle={{
                background:
                  theme === "light" ? "#f3f4f6" : "rgba(255, 255, 255, 0.05)",
                boxShadow: "none",
                border: "1px solid rgba(0, 0, 0, 0.05)",
                textAlign: "left",
                padding: "1.3rem 2rem",
              }}
              
              ... //the rest of the code

Adithya-Rajendran avatar Jan 08 '24 04:01 Adithya-Rajendran

Hi! To fix this issue add this to your lib/hooks.ts file

import { useActiveSectionContext } from "@/context/active-section-context";
import { useEffect } from "react";
import { useInView } from "react-intersection-observer";
import type { SectionName } from "./types";

export function useSectionInView(sectionName: SectionName, threshold = 0.75) {
  const { ref, inView } = useInView({
    threshold,
  });
  const { setActiveSection, timeOfLastClick } = useActiveSectionContext();

  useEffect(() => {
    if (inView && Date.now() - timeOfLastClick > 1000) {
      setActiveSection(sectionName);
    }
  }, [inView, setActiveSection, timeOfLastClick, sectionName]);

  return {
    ref, inView //ADDING "inView"
  };
}

and make the following change to your components/experience.tsx file

export default function Experience() {
  const { ref, inView } = useSectionInView("Experience");
  const { theme } = useTheme();
  const [isVisible, setIsVisible] = React.useState(false);

  React.useEffect(() => {
    if (inView) {
      setIsVisible(true);
    }
  }, [inView]);
  
  return (
    <section id="experience" ref={ref} className="scroll-mt-28 mb-28 sm:mb-40">
      <SectionHeading>My experience</SectionHeading>
      <VerticalTimeline lineColor="">
        {experiencesData.map((item, index) => (
          <React.Fragment key={index}>
            <VerticalTimelineElement
              visible={isVisible}   //THIS WAS ADDED
              contentStyle={{
                background:
                  theme === "light" ? "#f3f4f6" : "rgba(255, 255, 255, 0.05)",
                boxShadow: "none",
                border: "1px solid rgba(0, 0, 0, 0.05)",
                textAlign: "left",
                padding: "1.3rem 2rem",
              }}
              
              ... //the rest of the code

I had mine working with just visible={true} but this broke the SectionInView hook for the Experience element.

Following your instructions results in the timeline not displaying for me.

drbrunning avatar Jan 22 '24 21:01 drbrunning

  const [isVisible, setIsVisible] = React.useState(false);

  React.useEffect(() => {
    if (inView) {
      setIsVisible(true);
    }
  }, [inView]);

Did you add section this as well? Can you share some of your code?

  const [isVisible, setIsVisible] = React.useState(false);

  React.useEffect(() => {
    if (inView) {
      setIsVisible(true);
    }
  }, [inView]);

Adithya-Rajendran avatar Feb 09 '24 05:02 Adithya-Rajendran

isVisible

Hi @Adithya-Rajendran / @drbrunning - There is no need to have a seperate useState and useEffect in experience.tsx to track visibility. With this approach you will also skip unncessary use of useEffect / useState ⚠

Better solution: 👉 Within experience.tsx you can use inView directly in visilbe prop visible={inView}

Experience.tsx

<VerticalTimelineElement
      visible={inView}
      ...

However, with this animation will run everytime when Experience section comes to view. To control it, you can use triggerOnce: true within useInView options like below:

export default function Experience() {
    const { ref, inView } = useSectionInView('Experience', { threshold: 0.2, triggerOnce: true })  <------ PASSING OPTIONS OBJECT rather than just threshold to give more control to components
 ...

Hooks.ts

import { useContext, useEffect } from 'react'
import { ActiveSectionContext } from '@/context/active-section-context'
import { useInView } from 'react-intersection-observer'
import type { SectionName } from '@/context/active-section-context'

type SectionInViewOptions = {
    threshold?: number
    triggerOnce?: boolean
}

export function useSectionInView(sectionName: SectionName, options: SectionInViewOptions) {
    const { setActiveSection, timeOfLastClick } = useContext(ActiveSectionContext)

    const { ref, inView } = useInView(options)

    useEffect(() => {
        if (inView && Date.now() - timeOfLastClick > 500) {
            setActiveSection(sectionName)
        }
    }, [inView, setActiveSection, sectionName, timeOfLastClick])

    return {
        ref,
        inView,
    }
}

aakash19090 avatar Mar 21 '24 15:03 aakash19090

nah your code will have inView to be set true only work when u scroll to the section of experience first time. When i scroll to the same section from a different section the second time what happens is the header slider to the experience will not work because the inView will not change this time and the setActiveSection hook will not be executed as the case in the if here

useEffect(() => { if (inView && Date.now() - timeOfLastClick > 500) { setActiveSection(sectionName) } }, [inView, setActiveSection, sectionName, timeOfLastClick])

will not return true the second time i scroll to the section

Prajwalg19 avatar Mar 25 '24 08:03 Prajwalg19

All we need to do is return inView in hooks.ts, then set visible={inView} in experience.tsx

import { useActiveSectionActions, useTimeOfLastClick } from "@/stores/activeSectionStore";
import { useEffect } from "react";
import { useInView } from "react-intersection-observer";
import type { SectionName } from "./types";

export function useSectionInView(sectionName: SectionName, threshold = 0.75) {
  const { ref, inView } = useInView({
    threshold,
  });
  const timeOfLastClick = useTimeOfLastClick();
  const {setActiveSection} = useActiveSectionActions();

  useEffect(() => {
    if (inView && Date.now() - timeOfLastClick > 1000) {
      setActiveSection(sectionName);
    }
  }, [inView, setActiveSection, timeOfLastClick, sectionName]);

  return {
    ref,
    inView,
  };
}
"use client";

import React from "react";
import SectionHeading from "./section-heading";
import {
  VerticalTimeline,
  VerticalTimelineElement,
} from "react-vertical-timeline-component";
import "react-vertical-timeline-component/style.min.css";
import { experiencesData } from "@/lib/data";
import { useSectionInView } from "@/lib/hooks";
import { useTheme } from "@/context/theme-context";

export default function Experience() {
  const { ref, inView } = useSectionInView("Experience");
  const { theme } = useTheme();

  return (
    <section id="experience" ref={ref} className="scroll-mt-28 mb-28 sm:mb-40">
      <SectionHeading>My experience</SectionHeading>
      <VerticalTimeline lineColor="">
        {experiencesData.map((item, index) => (
          <React.Fragment key={index}>
            <VerticalTimelineElement
            visible={inView}
              contentStyle={{
                background:
                  theme === "light" ? "#f3f4f6" : "rgba(255, 255, 255, 0.05)",
                boxShadow: "none",
                border: "1px solid rgba(0, 0, 0, 0.05)",
                textAlign: "left",
                padding: "1.3rem 2rem",
              }}
              contentArrowStyle={{
                borderRight:
                  theme === "light"
                    ? "0.4rem solid #9ca3af"
                    : "0.4rem solid rgba(255, 255, 255, 0.5)",
              }}
              date={item.date}
              icon={item.icon}
              iconStyle={{
                background:
                  theme === "light" ? "white" : "rgba(255, 255, 255, 0.15)",
                fontSize: "1.5rem",
              }}
            >
              <h3 className="font-semibold capitalize">{item.title}</h3>
              <p className="font-normal !mt-0">{item.location}</p>
              <p className="!mt-1 !font-normal text-gray-700 dark:text-white/75">
                {item.description}
              </p>
            </VerticalTimelineElement>
          </React.Fragment>
        ))}
      </VerticalTimeline>
    </section>
  );
}

Rope-a-dope avatar Jun 16 '24 21:06 Rope-a-dope