Skip to content

Commit

Permalink
Added Events Page
Browse files Browse the repository at this point in the history
  • Loading branch information
sadwika-sabbella-zs committed Dec 17, 2024
1 parent 0352639 commit 5579bea
Show file tree
Hide file tree
Showing 9 changed files with 395 additions and 90 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"react": "18.2.0",
"react-dom": "18.2.0",
"react-highlight-words": "^0.20.0",
"react-timeline-animation": "^1.2.3",
"refractor": "^4.8.1",
"simple-functional-loader": "^1.2.1",
"tailwindcss": "^3.3.3"
Expand Down
38 changes: 38 additions & 0 deletions src/app/events/events.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
[
{
"date": "10-02-2020",
"title": "GopherCon Africa",
"description": "GoFr received an amazing response at GopherCon Africa! We showcased our seamless database integration, HTTP/gRPC support, observability, and WebSockets.",
"imageSrc": "https://media.discordapp.net/attachments/1230609009162059836/1301136150156677141/1729836948894.jpeg?ex=67620038&is=6760aeb8&hm=4cbee5de4bec5f526b941db402a3d1607c990054c3cf1853edb4934c70f776ba&=&format=webp&width=2160&height=944"
},
{
"date": "2021",
"title": "Open Source India 2024",
"description": "At Open Source India in Bengaluru, we kicked off with an amazing response at our booth on 23rd and an interactive Developer’s Meet on Oct 24th. It was a pleasure connecting with everyone at our booth, where demos highlighted GoFr’s innovative approach to writing microservices, making backend development simpler and more efficient.",
"imageSrc": "https://media.discordapp.net/attachments/1230609009162059836/1301136149749698650/1729836948365.jpeg?ex=67620038&is=6760aeb8&hm=f43bbf9dacbc631f36dfa7ae4402f61caaddcde1c8e4357236418d11c86d8006&=&format=webp&width=1418&height=1056"
},
{
"date": "2022",
"title": "GoFr is on a roll with its workshops!",
"description": "Past two months, we’ve hosted workshops at top colleges such as IIT BHU, IIIT Sri City, Thapar University, JIIT Noida, NIT Jalandhar, and NIT Nagpur. At Gravitas in VIT Vellore, we proudly supported the Hack the Hackathon event, where students explored GoFr and contributed innovative ideas to enhance the framework.",
"imageSrc": "https://media.discordapp.net/attachments/1230609050899710052/1301491118780973137/WhatsApp_Image_2024-10-30_at_15.47.27.jpeg?ex=6761f94f&is=6760a7cf&hm=4bc52e39b921aeb00e444522fa49744dcbfa9d6fb7e35b1d3b2c167b6b6111d9&=&format=webp&width=1408&height=1056"
},
{
"date": "2020",
"title": "GopherCon Africa",
"description": "GoFr received an amazing response at GopherCon Africa! We showcased our seamless database integration, HTTP/gRPC support, observability, and WebSockets.",
"imageSrc": "https://media.discordapp.net/attachments/1230609009162059836/1301136150156677141/1729836948894.jpeg?ex=67620038&is=6760aeb8&hm=4cbee5de4bec5f526b941db402a3d1607c990054c3cf1853edb4934c70f776ba&=&format=webp&width=2160&height=944"
},
{
"date": "2021",
"title": "Open Source India 2024",
"description": "At Open Source India in Bengaluru, we kicked off with an amazing response at our booth on 23rd and an interactive Developer’s Meet on Oct 24th. It was a pleasure connecting with everyone at our booth, where demos highlighted GoFr’s innovative approach to writing microservices, making backend development simpler and more efficient.",
"imageSrc": "https://media.discordapp.net/attachments/1230609009162059836/1301136149749698650/1729836948365.jpeg?ex=67620038&is=6760aeb8&hm=f43bbf9dacbc631f36dfa7ae4402f61caaddcde1c8e4357236418d11c86d8006&=&format=webp&width=1418&height=1056"
},
{
"date": "2022",
"title": "GoFr is on a roll with its workshops!",
"description": "Past two months, we’ve hosted workshops at top colleges such as IIT BHU, IIIT Sri City, Thapar University, JIIT Noida, NIT Jalandhar, and NIT Nagpur. At Gravitas in VIT Vellore, we proudly supported the Hack the Hackathon event, where students explored GoFr and contributed innovative ideas to enhance the framework.",
"imageSrc": "https://media.discordapp.net/attachments/1230609050899710052/1301491118780973137/WhatsApp_Image_2024-10-30_at_15.47.27.jpeg?ex=6761f94f&is=6760a7cf&hm=4bc52e39b921aeb00e444522fa49744dcbfa9d6fb7e35b1d3b2c167b6b6111d9&=&format=webp&width=1408&height=1056"
}
]
12 changes: 12 additions & 0 deletions src/app/events/page.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
'use client'
import React, {useEffect, useRef, useState} from 'react';
import Events from "@/components/EventsTimeline";

const EventsTimeline = () => {
return(
<Events/>
)

};

export default EventsTimeline;
103 changes: 103 additions & 0 deletions src/components/AnimatedTimelineItem.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import React, { useRef, useEffect, useState } from 'react';

const AnimatedTimelineItem = ({ date, title, description, imageSrc, isLeft }) => {
const itemRef = useRef(null);
const [isVisible, setIsVisible] = useState(false);
const [isExiting, setIsExiting] = useState(false);

useEffect(() => {
const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) {
setIsVisible(true);
setIsExiting(false);
} else {
setIsVisible(false);
setIsExiting(true);
}
},
{
threshold: 0.1,
}
);

if (itemRef.current) {
observer.observe(itemRef.current);
}

return () => {
if (itemRef.current) {
observer.unobserve(itemRef.current);
}
};
}, []);

const animationStyle = isVisible
? {
transform: 'translateX(0)',
opacity: 1,
transition: 'all 1s ease-out',
}
: isExiting
? isLeft
? {
transform: 'translateX(100px)',
opacity: 0,
transition: 'all 1s ease-out',
}
: {
transform: 'translateX(-100px)',
opacity: 0,
transition: 'all 1s ease-out',
}
: isLeft
? {
transform: 'translateX(-100px)',
opacity: 0,
}
: {
transform: 'translateX(100px)',
opacity: 0,
};

return (
<div
ref={itemRef}
className="flex flex-col md:flex-row items-center w-full xs:mb-20 md:mb-60 relative transition-all duration-1000 ease-out"
>
<div
className={`w-full md:w-5/12 ${
isLeft ? 'md:text-right md:pr-8' : 'md:order-last md:text-left md:pl-8'
}`}
>
<div className="mb-4">
<h3 className="text-xl text-white font-bold mb-2">{title}</h3>
<p className="text-white">{description}</p>
</div>
</div>
<div className="w-full px-4 md:w-2/12 flex md:justify-center items-center mb-4 md:mb-0">
<div className="w-auto h-6 bg-primary rounded-full z-20 flex items-center justify-center">
<span className="text-xs px-4 bg-[#23293b] p-2 rounded-3xl text-white font-semibold items-center whitespace-nowrap">
{date}
</span>
</div>
</div>


<div
className={`w-full md:w-5/12 ${
isLeft ? 'md:pl-8' : 'md:order-first md:pr-8'
}`}
style={animationStyle}
>
<img
src={imageSrc}
alt={title}
className="w-full h-72 object-cover rounded-lg shadow-md"
/>
</div>
</div>
);
};

export default AnimatedTimelineItem;
23 changes: 23 additions & 0 deletions src/components/EventsTimeline.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React, { useEffect } from 'react';
import VerticalTimeline from './VerticalTimeline';
import events from '../app/events/events.json'

const EventsTimeline = () => {
useEffect(() => {
if (window.innerWidth >= 768) {
window.scrollBy(0, 70);
}
}, []);
return (
<div className="bg-slate-900 min-h-screen py-4 md:py-28">
<div className="sm:mx-auto px-4 py-8">
<h1 className="flex justify-center items-center text-4xl font-bold text-center mb-12 text-white sm:hidden">
Events
</h1>
<VerticalTimeline events={events} />
</div>
</div>
);
};

export default EventsTimeline;
3 changes: 2 additions & 1 deletion src/components/Footer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const footerLinks = [
// { title: 'Releases', link: '/releases' },
{ title: 'Documentation', link: '/docs' },
{ title: 'Blogs', link: 'https://medium.com/gofr', target_blank: true },
{ title: 'Events', link: '/events' }
]

function FooterUi() {
Expand All @@ -44,7 +45,7 @@ function FooterUi() {
<div className="mx-auto max-w-screen-2xl overflow-hidden px-6 py-4 lg:px-8">
<nav
aria-label="Footer"
className="-mb-6 columns-2 sm:flex sm:justify-center sm:space-x-12"
className="-mb-6 flex gap-5 justify-center sm:space-x-12"
>
{footerLinks.map((item) => (
<div key={item.title} className="pb-6">
Expand Down
6 changes: 4 additions & 2 deletions src/components/Layout.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ function Header() {
let [isScrolled, setIsScrolled] = useState(false)
let pathname = usePathname()
const isCertificate = pathname.includes('certificate')
const isEvents = pathname.includes('events');
const [githubStars, setGithubStars] = useState(null)

useEffect(() => {
Expand Down Expand Up @@ -76,12 +77,13 @@ function Header() {
</span>
</Link>
</div>
{!isCertificate && (
{!isCertificate && !isEvents && (
<div className="-my-5 mr-6 sm:mr-8 md:mr-0">
<Search />
</div>
)}
<div className="relative flex basis-0 items-center justify-end gap-2 sm:gap-2 md:flex-grow">
{isEvents && <div className='relative flex flex-grow basis-0 items-center justify-center sm:block hidden'><h1 className="justify-center items-center text-xl sm:text-3xl md:text-4xl font-bold text-center text-white">Events</h1></div>}
<div className="relative flex flex-grow basis-0 items-center justify-end gap-2 sm:gap-3 md:flex-grow">
<Link
href="https://github.com/gofr-dev/gofr"
className="group"
Expand Down
97 changes: 97 additions & 0 deletions src/components/VerticalTimeline.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import React, { useEffect, useRef, useState } from "react";
import AnimatedTimelineItem from "./AnimatedTimelineItem";
import Image from "next/image";
import blurCyanImage from "@/images/blur-cyan.png";
import TimelineObserver from "react-timeline-animation";

const Timeline = ({ setObserver, customHeight }) => {
const timelineRef = useRef(null);

useEffect(() => {
setObserver(timelineRef.current);
}, [setObserver]);

return (
<div
id="timeline"
ref={timelineRef}
style={{ height: customHeight }}

className="absolute left-3 xs:left-0 md:left-1/2 py-8 top-0 w-1 transform md:-translate-x-1/2 md:block hidden transition-all duration-100 ease-in-out"
/>
);
};

const VerticalTimeline = ({ events }) => {
const containerRef = useRef(null);
const [timelineHeight, setTimelineHeight] = useState("100%");

useEffect(() => {
const updateTimelineHeight = () => {
if (containerRef.current) {
const lastEvent = containerRef.current.querySelector(
`.timeline-item:last-child`
);
if (lastEvent) {
const timelineTop = containerRef.current.getBoundingClientRect().top;
const lastEventBottom = lastEvent.getBoundingClientRect().bottom;
const lastEventHeight = lastEvent.offsetHeight;
setTimelineHeight(`${lastEventBottom - timelineTop - lastEventHeight / 2}px`);
}
}
};
updateTimelineHeight();
}, [events]);

return (
<div ref={containerRef} className="md:container mx-auto px-4 py-4 md:py-8 relative">
<TimelineObserver
initialColor="transparent"
fillColor="cyan"
hasReverse={true}
handleObserve={(setObserver) => (
<Timeline setObserver={setObserver} customHeight={timelineHeight} />
)}
/>

<Image
className="fixed bottom-full right-full top-5 -mb-56 -mr-72 opacity-50"
src={blurCyanImage}
alt=""
width={530}
height={530}
unoptimized
priority
/>

<div className="relative z-10">
{events.map((event, index) => (
<div
key={index}
className="timeline-item"
>
<AnimatedTimelineItem
date={event.date}
title={event.title}
description={event.description}
imageSrc={event.imageSrc}
isLeft={index % 2 === 0}
/>
</div>
))}
</div>

<Image
className="fixed right-0 bottom-0 -mb-56 -mr-72 opacity-50"
src={blurCyanImage}
alt=""
width={530}
height={530}
unoptimized
priority
/>
</div>
);
};

export default VerticalTimeline;
Loading

0 comments on commit 5579bea

Please sign in to comment.