Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added a Upcoming Events Feature #78

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 24 additions & 3 deletions JSON/events.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"start_date": "2020-10-01T00:00:00Z",
"end_date": "2020-10-31T23:59:59Z",
"title": "Hacktoberfest 2020",
"description": "Hacktoberfest is a month-long celebration of open source software run by DigitalOcean in partnership with GitHub and Twilio. We will put projects on different fields like Mobile App Development, Web Development, Python, etc. We will initialise some GitHub Repo and will make them open source.",
"description": "Hacktoberfest is a month-long celebration of open source software run by DigitalOcean in partnership with GitHub and Twilio.",
"filename": "hacktoberfest_2020.md"
}
],
Expand All @@ -31,17 +31,38 @@
"start_date": "2021-10-01T00:00:00Z",
"end_date": "2021-10-31T23:59:59Z",
"title": "Hacktoberfest 2021",
"description": "Hacktoberfest is a month-long celebration of open source software run by DigitalOcean in partnership with GitHub, Intel, Appwrite & Deepsource. Hacktoberfest encourages participation in the open source community, which grows bigger every year. Complete the 2021 challenge and earn a limited edition T-shirt. We have different projects on our github, check it out!",
"description": "Hacktoberfest encourages participation in the open source community.",
"filename": "hacktoberfest_2021.md"
},
{
"start_date": "2021-11-01T00:00:00Z",
"end_date": "2021-11-01T23:59:59Z",
"title": "Tech Symposium 2021",
"description": "A day of talks and workshops from industry leaders.",
"filename": "tech_symposium_2021.md"
}
],
"2024": [
{
"start_date": "2024-10-01T00:00:00Z",
"end_date": "2024-10-31T23:59:59Z",
"title": "Hacktoberfest 2024",
"description": "Hacktoberfest 2024 is a month-long celebration of open source software, hosted by DigitalOcean and GitHub. Contribute four quality pull requests during October to earn either a limited edition eco-friendly t-shirt or have a tree planted in your name. Join developers worldwide in supporting open source projects - from beginners to experts, everyone is welcome!",
"description": "Hacktoberfest 2024 is a month-long celebration of open source software.",
"filename": "hacktoberfest_2024.md"
},
{
"start_date": "2024-11-01T00:00:00Z",
"end_date": "2024-11-01T23:59:59Z",
"title": "New Tech Conference 2024",
"description": "Join us for a day of insightful talks and networking with industry leaders in tech.",
"filename": "new_tech_conference_2024.md"
},
{
"start_date": "2024-12-01T00:00:00Z",
"end_date": "2024-12-01T23:59:59Z",
"title": "Year-End Hackathon",
"description": "A collaborative event for developers to showcase their skills.",
"filename": "year_end_hackathon_2024.md"
}
]
}
123 changes: 87 additions & 36 deletions src/Pages/Events.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,75 +2,126 @@ import React, { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
import EventCard from '@/components/EventCard';
import Loader from '@/components/Loader';
import SEO from '@/components/SEO';
import SEO from '@/components/SEO';
import EventToggle from '../components/EventToggle';
import RegistrationForm from '../components/RegistrationForm';

const Events = () => {
const { year } = useParams();
const [events, setEvents] = useState([]);
const [loading, setLoading] = useState(true);
const [activeTab, setActiveTab] = useState('upcoming');
const [isRegistering, setIsRegistering] = useState(false);
const [selectedEvent, setSelectedEvent] = useState(null);

const handleToggle = (tab) => {
setActiveTab(tab);
};

const handleRegisterClick = (event) => {
setSelectedEvent(event);
setIsRegistering(true);
};

const closeRegistration = () => {
setIsRegistering(false);
setSelectedEvent(null);
};

useEffect(() => {
const fetchEvents = async () => {
try {
const response = await fetch("https://raw.githubusercontent.com/clubgamma/club-gamma-frontend/refs/heads/main/JSON/events.json");
const data = await response.json();
const filteredEvents = data[year] || [];

const eventsWithMarkdown = await Promise.all(filteredEvents.map(async (event) => {
const filename = event.filename || `${event.title.replace(/\s+/g, '_').toLowerCase()}.md`;
const markdownResponse = await fetch(`https://raw.githubusercontent.com/clubgamma/club-gamma-frontend/refs/heads/main/JSON/markdowns/${filename}`);
const markdownContent = await markdownResponse.text();

return {
...event,
markdownContent,
};
}));

setEvents(eventsWithMarkdown);

// Filter events based on the selected year
const filteredEvents = data[year] ? data[year].map(event => ({
...event,
date: event.start_date || event.date, // Ensure we have a date field
})) : [];

console.log("Fetched Events for year " + year + ":", JSON.stringify(filteredEvents, null, 2));
setEvents(filteredEvents);
} catch (error) {
console.error("Error fetching events:", error);
} finally {
setLoading(false);
}
};

fetchEvents();
}, [year]);

// Separate upcoming and past events based on current date
const currentDate = new Date();
console.log("Current Date:", currentDate.toISOString());

const upcomingEvents = events.filter(event => {
const startDate = new Date(event.start_date || event.date);
console.log(`Checking Event: ${event.title}, Start Date: ${startDate.toISOString()}`);
return startDate >= currentDate;
});

const pastEvents = events.filter(event => {
const endDate = new Date(event.end_date || event.date);
return endDate < currentDate;
});

return (
<>
<SEO
title={`Events ${year && `${year}`}`}
pathname={`/events/${year}`}
description="Explore Club Gamma's tech events, workshops, and community initiatives for hands-on learning and networking in the tech world."
keywords="Club Gamma events, tech workshops, developer networking, tech community, coding, programming, technology, learning, developer community, tech events, skill development"
/>
console.log("Upcoming Events:", upcomingEvents);
console.log("Past Events:", pastEvents);
return (
<>
<SEO
title={`Events ${year && `${year}`}`}
pathname={`/events/${year}`}
description="Explore Club Gamma's tech events, workshops, and community initiatives for hands-on learning and networking in the tech world."
keywords="Club Gamma events, tech workshops, developer networking, tech community, coding, programming, technology, learning, developer community, tech events, skill development"
/>
<div className="min-h-screen font-dm-sans bg-[#1e1e1e] text-white p-8 pt-28">
<h1 className="text-4xl md:text-5xl font-bold mb-8 md:mb-12 text-center">
<span className="text-[#ff6b6b]">
Club gamma
</span>
<span className="text-white"> Events {year && `${year}`}</span>
<span className="text-[#ff6b6b]">Club Gamma</span>
<span className="text-white"> Events {year}</span>
</h1>

{year === '2024' && <EventToggle onToggle={setActiveTab} activeTab={activeTab} />}

{loading ? (
<div className="flex flex-col items-center justify-center">
<Loader size='80' />
</div>
) : events.length > 0 ? (
) : (
<div className="max-w-7xl mx-auto">
{events.map((event) => (
<EventCard key={event.title} event={event} />
{(year === '2024' ? (activeTab === 'upcoming' ? upcomingEvents : pastEvents) : events).map((event, index) => (
<div key={index} className="mb-8">
<EventCard event={event} />
{year === '2024' && activeTab === 'upcoming' && (
<button
onClick={() => handleRegisterClick(event)}
className="mt-4 bg-[#ff6b6b] hover:bg-[#ff9b9b] text-white py-2 px-4 rounded transition-colors duration-300"
>
Register
</button>
)}
</div>
))}
{year === '2024' && activeTab === 'upcoming' && upcomingEvents.length === 0 && (
<p className="text-center text-lg">No upcoming events found.</p>
)}
{year === '2024' && activeTab === 'past' && pastEvents.length === 0 && (
<p className="text-center text-lg">No past events found.</p>
)}
</div>
) : (
<p className="text-center text-gray-300">No events found for the year {year}.</p>
)}
</div>
</>

{isRegistering && (
<RegistrationForm
event={selectedEvent}
onClose={() => setIsRegistering(false)}
/>
)}
</div>
</>
);
};

export default Events;
export default Events;
23 changes: 23 additions & 0 deletions src/components/EventToggle.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// EventToggle.js
import React from 'react';

const EventToggle = ({ onToggle, activeTab }) => {
return (
<div className="flex justify-center mb-8">
<button
className={`px-4 py-2 rounded-l-lg ${activeTab === 'upcoming' ? 'bg-[#ff6b6b] text-white' : 'bg-gray-700 text-gray-300'}`}
onClick={() => onToggle('upcoming')}
>
Upcoming Events
</button>
<button
className={`px-4 py-2 rounded-r-lg ${activeTab === 'past' ? 'bg-[#ff6b6b] text-white' : 'bg-gray-700 text-gray-300'}`}
onClick={() => onToggle('past')}
>
Past Events
</button>
</div>
);
};

export default EventToggle;
34 changes: 34 additions & 0 deletions src/components/RegistrationForm.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// src/components/RegistrationForm.js
import React, { useState } from 'react';

const RegistrationForm = ({ onClose }) => {
const [name, setName] = useState('');
const [email, setEmail] = useState('');

const handleSubmit = (e) => {
e.preventDefault();
// Handle registration logic here
console.log('Registered:', { name, email });
onClose(); // Close the form after submission
};

return (
<div className="registration-form">
<h2>Register for Event</h2>
<form onSubmit={handleSubmit}>
<label>
Name:
<input type="text" value={name} onChange={(e) => setName(e.target.value)} required />
</label>
<label>
Email:
<input type="email" value={email} onChange={(e) => setEmail(e.target.value)} required />
</label>
<button type="submit">Register</button>
<button type="button" onClick={onClose}>Close</button>
</form>
</div>
);
};

export default RegistrationForm;
66 changes: 66 additions & 0 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,70 @@ html {
::-webkit-scrollbar-thumb {
width: 0; /* Remove scrollbar space */
background: transparent; /* Optional: just make scrollbar invisible */
}

/* src/styles.css */
.event-toggle {
display: flex;
justify-content: space-between;
margin-bottom: 20px;
}

.event-toggle button {
background-color: #4CAF50;
color: #fff;
border: none;
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
}

.event-toggle button.active {
background-color: #3e8e41;
}

.registration-form {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: #fff;
padding: 20px;
border: 1px solid #ddd;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
}

.registration-form h2 {
margin-top: 0;
}

.registration-form label {
display: block;
margin-bottom: 10px;
}

.registration-form input[type="text"],
.registration-form input[type="email"] {
width: 100%;
padding: 10px;
margin-bottom: 20px;
border: 1px solid #ccc;
}

.registration-form button[type="submit"] {
background-color: #4CAF50;
color: #fff;
border: none;
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
}

.registration-form button[type="button"] {
background-color: #fff;
color: #333;
border: 1px solid #ddd;
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
}