182 lines
6.0 KiB
JavaScript
182 lines
6.0 KiB
JavaScript
"use client";
|
|
|
|
import React, { useEffect, useState } from "react";
|
|
import {
|
|
VerticalTimeline,
|
|
VerticalTimelineElement,
|
|
} from "react-vertical-timeline-component";
|
|
import { AnimatePresence, motion } from "framer-motion";
|
|
|
|
import "react-vertical-timeline-component/style.min.css";
|
|
|
|
import { SectionWrapper } from "src/hoc";
|
|
import { textVariant } from "src/utils/motion";
|
|
import { styles } from "src/style";
|
|
import { experiences } from "src/constans";
|
|
import { activityFake } from "datacalender";
|
|
import ActivityCardFake from "@comp/TaskPage/ActivityCardFake/page";
|
|
|
|
const ExperienceCard = ({ experience }) => {
|
|
const [isMobile, setIsMobile] = useState(false);
|
|
|
|
useEffect(() => {
|
|
// Check window size after the component mounts
|
|
const handleResize = () => {
|
|
setIsMobile(window.innerWidth < 640);
|
|
};
|
|
|
|
// Run the function initially and also when the window is resized
|
|
handleResize();
|
|
window.addEventListener("resize", handleResize);
|
|
|
|
// Clean up event listener on unmount
|
|
return () => window.removeEventListener("resize", handleResize);
|
|
}, []);
|
|
return (
|
|
<VerticalTimelineElement
|
|
contentStyle={{
|
|
background: "#35685952",
|
|
color: "#fff",
|
|
borderRadius: "15px",
|
|
}}
|
|
contentArrowStyle={{ borderRight: "7px solid #35685952" }}
|
|
date={experience.date}
|
|
iconStyle={{
|
|
background: experience.iconBg, // Customize background
|
|
color: "#fff", // Customize icon color
|
|
boxShadow: "0 0 0 4px #35685952", // Add shadow or border
|
|
display: "flex",
|
|
justifyContent: "center",
|
|
alignItems: "center",
|
|
background: "white",
|
|
width: "30px",
|
|
height: "30px",
|
|
marginLeft: isMobile ? "5px" : "-15px", // Apply margin based on screen width
|
|
marginTop: "15px",
|
|
opacity: "0.8",
|
|
}}
|
|
>
|
|
<div>
|
|
<h3 className="text-white text-[24px] font-bold">{experience.title}</h3>
|
|
<p
|
|
className="text-secondary text-[16px] font-semibold"
|
|
style={{ margin: 0 }}
|
|
>
|
|
{experience.company_name}
|
|
</p>
|
|
</div>
|
|
|
|
<ul className="mt-5 list-disc ml-5 space-y-2">
|
|
{experience.points.map((point, index) => (
|
|
<li
|
|
key={`experience-point-${index}`}
|
|
className="text-white-100 text-[14px] pl-1 tracking-wider"
|
|
>
|
|
{point}
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</VerticalTimelineElement>
|
|
);
|
|
};
|
|
|
|
const Experience = () => {
|
|
const [number, setNumber] = useState(4521);
|
|
const [prevNumber, setPrevNumber] = useState(4521);
|
|
|
|
useEffect(() => {
|
|
const interval = setInterval(() => {
|
|
setPrevNumber(number);
|
|
setNumber((prev) => prev + 1);
|
|
}, 15000);
|
|
|
|
return () => clearInterval(interval);
|
|
}, [number]);
|
|
|
|
const numberStr = number.toString();
|
|
const prevNumberStr = prevNumber.toString();
|
|
|
|
const fadeVariants = {
|
|
initial: { opacity: 0, y: 30, color: "#000000" }, // Dark background when fading in
|
|
animate: { opacity: 1, y: 0, color: "#ffffff" }, // White background when fully visible
|
|
exit: { opacity: 0, y: -30, color: "#000000" }, // Dark background when fading out
|
|
};
|
|
return (
|
|
<>
|
|
<motion.div variants={textVariant()}>
|
|
<h2 className="text-white font-black text-[30px] xs:text-[40px] sm:text-[50px] md:text-[60px] xs:leading-[50px] text-center ">
|
|
<span className="text-primary-300 text-[30px] xs:text-[100px] sm:text-[150px] relative top-[5px] sm:top-[10px] font-bold">
|
|
B
|
|
</span>
|
|
ase logics{" "}
|
|
</h2>
|
|
</motion.div>
|
|
|
|
<div className="mt-20 flex flex-col">
|
|
<VerticalTimeline>
|
|
{experiences.map((experience, index) => (
|
|
<ExperienceCard
|
|
key={`experience-${index}`}
|
|
experience={experience}
|
|
/>
|
|
))}
|
|
</VerticalTimeline>
|
|
</div>
|
|
|
|
<div className=" mt-20">
|
|
<h2
|
|
className={`text-white font-bold md:text-[30px] sm:text-[20px] xs:text-[18px] text-[30px] text-center`}
|
|
>
|
|
Number of tasks completed in Briz
|
|
</h2>
|
|
<div className="xs:block lg:flex justify-center mt-10">
|
|
<div className="lg:w-[400px]">
|
|
<ActivityCardFake data={activityFake} />
|
|
</div>
|
|
<div className="ml-4 mt-7">
|
|
<div className="flex xs:justify-center xs:mt-10 lg:mt-0">
|
|
{numberStr.split("").map((digit, index) => (
|
|
<div key={index} className="relative text-4xl h-12 w-11 ">
|
|
<AnimatePresence initial={false}>
|
|
{prevNumberStr[index] !== digit && (
|
|
<motion.span
|
|
key={`${prevNumberStr[index]}-prev`}
|
|
className="absolute inset-x-0 text-center text-white !text-[80px] font-bold "
|
|
initial="animate"
|
|
animate="exit"
|
|
exit="initial"
|
|
variants={fadeVariants}
|
|
transition={{ duration: 0.5 }}
|
|
>
|
|
{prevNumberStr[index]}
|
|
</motion.span>
|
|
)}
|
|
</AnimatePresence>
|
|
<AnimatePresence initial={false}>
|
|
<motion.span
|
|
key={`${digit}-current`}
|
|
className="absolute inset-x-0 text-center text-white !text-[80px] font-bold"
|
|
initial="initial"
|
|
animate="animate"
|
|
exit="exit"
|
|
variants={fadeVariants}
|
|
transition={{ duration: 0.5 }}
|
|
>
|
|
{digit}
|
|
</motion.span>
|
|
</AnimatePresence>
|
|
</div>
|
|
))}
|
|
</div>
|
|
<p className="mb-0 text-white font-light text-center">
|
|
Activities performed with Briz
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default SectionWrapper(Experience, "our-solution");
|