From 2735dd7af4a2bfebfbafc98cb45be05f176db399 Mon Sep 17 00:00:00 2001 From: Jean Paul Elisa NIYOKWIZERWA Date: Tue, 30 Jun 2026 20:00:02 +0200 Subject: [PATCH 1/3] feat(events): split into Upcoming and Past subsections - Add status/attendance/recapUrl to the events data model - Rebuild the events section into stacked 'Upcoming Events' and 'Past Events' subsections - Upcoming cards keep the Register CTA; past cards are muted, show a 'Past' badge, '{n} attended', and an optional 'View recap' link - Add an empty-state for when there are no upcoming events --- .../home-sections/events-section.tsx | 183 +++++++++++++----- src/lib/constants.ts | 59 +++++- 2 files changed, 190 insertions(+), 52 deletions(-) diff --git a/src/components/home-sections/events-section.tsx b/src/components/home-sections/events-section.tsx index 993dc16..fbb38a9 100644 --- a/src/components/home-sections/events-section.tsx +++ b/src/components/home-sections/events-section.tsx @@ -1,15 +1,106 @@ import { events, communityLinks } from "@/src/lib/constants"; import { Card } from "@/src/components/ui/card"; import { Button } from "@/src/components/ui/button"; -import { Calendar, MapPin, Users, Clock } from "lucide-react"; +import { Badge } from "@/src/components/ui/badge"; +import { Calendar, MapPin, Users, Clock, ArrowUpRight } from "lucide-react"; import Link from "next/link"; +type CommunityEvent = (typeof events)[number]; + +const upcomingEvents = events.filter((e) => e.status === "upcoming"); +const pastEvents = events.filter((e) => e.status === "past"); + +function EventMeta({ event }: { event: CommunityEvent }) { + const isPast = event.status === "past"; + return ( +
+
+ + {event.date} +
+
+ + {event.time} +
+
+ + {event.location} +
+
+ + + {event.attendees} {isPast ? "attended" : "going"} + +
+
+ ); +} + +function UpcomingCard({ event }: { event: CommunityEvent }) { + return ( + +
+
+

{event.title}

+

{event.description}

+ +
+ + + +
+
+ ); +} + +function PastCard({ event }: { event: CommunityEvent }) { + return ( + +
+
+
+

+ {event.title} +

+ + Past + +
+

{event.description}

+ +
+ {event.recapUrl ? ( + + + + ) : null} +
+
+ ); +} + export function EventsSection() { return (
{/* Section header */} -
+

Events & Meetups

@@ -19,52 +110,52 @@ export function EventsSection() {

- {/* Events grid */} -
- {events.map((event) => ( - -
- {/* Event info */} -
-

- {event.title} -

-

{event.description}

- - {/* Details */} -
-
- - {event.date} -
-
- - {event.time} -
-
- - {event.location} -
-
- - {event.attendees} attending -
-
-
- - {/* CTA */} - - - -
+ {/* Upcoming */} +
+
+

+ Upcoming Events +

+ {upcomingEvents.length > 0 && ( + + {upcomingEvents.length} + + )} +
+ {upcomingEvents.length > 0 ? ( +
+ {upcomingEvents.map((event) => ( + + ))} +
+ ) : ( + +

+ No upcoming events scheduled right now.{" "} + + Join the community + {" "} + to be the first to know. +

- ))} + )}
+ + {/* Past */} + {pastEvents.length > 0 && ( +
+

Past Events

+
+ {pastEvents.map((event) => ( + + ))} +
+
+ )}
); diff --git a/src/lib/constants.ts b/src/lib/constants.ts index 5d0df7c..94e8894 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -87,24 +87,71 @@ export const workshops = [ }, ] +// Events. `status` drives the Upcoming vs Past subsections. +// For upcoming events `attendees` = people going; for past = people who attended. +// `recapUrl` is optional — set it on past events to link a recording/photos/writeup. export const events = [ + // ── Upcoming ──────────────────────────────────────────────────────────── { id: 1, - title: "Monthly Meetup - Kigali", - date: "Every 2nd Saturday", + title: "Monthly Meetup — Kigali", + date: "Saturday, July 12, 2026", time: "2:00 PM", location: "Kigali Innovation Hub", - description: "Join fellow Django developers for networking, knowledge sharing, and coffee.", + description: + "Lightning talks, networking, and coffee with fellow Django developers.", + status: "upcoming", attendees: 45, + recapUrl: "", }, { id: 2, - title: "Django Bootcamp - Q1 2026", - date: "January 15 - March 15", + title: "Building APIs with Django REST", + date: "Saturday, August 9, 2026", + time: "10:00 AM", + location: "Online", + description: + "A hands-on workshop on designing and shipping production-ready REST APIs.", + status: "upcoming", + attendees: 30, + recapUrl: "", + }, + // ── Past ──────────────────────────────────────────────────────────────── + { + id: 3, + title: "Intro to Django Meetup", + date: "June 14, 2026", + time: "2:00 PM", + location: "Kigali Innovation Hub", + description: + "Newcomers built their first Django app and met the community.", + status: "past", + attendees: 60, + recapUrl: "", // TODO: link recording / photos / writeup + }, + { + id: 4, + title: "Django Bootcamp — Q1 2026", + date: "Jan 15 – Mar 15, 2026", time: "Flexible", location: "Online + In-person", - description: "Intensive bootcamp to launch your Django journey and build real projects.", + description: + "An intensive 8-week bootcamp where members built and shipped real Django projects.", + status: "past", attendees: 200, + recapUrl: "", // TODO: link recording / photos / writeup + }, + { + id: 5, + title: "DjangoGirls Kigali", + date: "March 8, 2026", + time: "9:00 AM", + location: "Norrsken House Kigali", + description: + "A free, beginner-friendly workshop introducing women to web development with Django.", + status: "past", + attendees: 80, + recapUrl: "", // TODO: link recording / photos / writeup }, ] From 5599b76c32c8dada8b7c88d437936527bf2af62a Mon Sep 17 00:00:00 2001 From: Jean Paul Elisa NIYOKWIZERWA Date: Tue, 30 Jun 2026 20:10:33 +0200 Subject: [PATCH 2/3] feat(events): use real events + per-event registration links - Set the real WhatsApp community invite link - Replace sample events with the Python/Django July Meetup 2026 (upcoming, GIZ DTC, Google Form registration) and the Python & Django Rwanda Bootcamp (past, Feb-Apr 2026) - Add per-event registerUrl (falls back to WhatsApp) and render time/location/attendees only when provided --- .../home-sections/events-section.tsx | 36 ++++++---- src/lib/constants.ts | 70 +++++-------------- 2 files changed, 40 insertions(+), 66 deletions(-) diff --git a/src/components/home-sections/events-section.tsx b/src/components/home-sections/events-section.tsx index fbb38a9..4ff95c5 100644 --- a/src/components/home-sections/events-section.tsx +++ b/src/components/home-sections/events-section.tsx @@ -18,20 +18,26 @@ function EventMeta({ event }: { event: CommunityEvent }) { {event.date} -
- - {event.time} -
-
- - {event.location} -
-
- - - {event.attendees} {isPast ? "attended" : "going"} - -
+ {event.time && ( +
+ + {event.time} +
+ )} + {event.location && ( +
+ + {event.location} +
+ )} + {event.attendees > 0 && ( +
+ + + {event.attendees} {isPast ? "attended" : "going"} + +
+ )} ); } @@ -46,7 +52,7 @@ function UpcomingCard({ event }: { event: CommunityEvent }) { diff --git a/src/lib/constants.ts b/src/lib/constants.ts index 94e8894..37b3ec5 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -19,7 +19,7 @@ export const navigationItems = [ export const communityLinks = { // Primary "Join Community" entry point — drives every Join/Register CTA // (header, hero, team, events, footer "Get Involved" + "Join Us"). - whatsapp: "https://chat.whatsapp.com/your-invite-code", // TODO: real WhatsApp invite link + whatsapp: "https://chat.whatsapp.com/GvIF9Mw1E2ZBf2S5wazfOo?mode=gi_t", // Social / code github: "https://github.com/djangorwanda", @@ -88,69 +88,37 @@ export const workshops = [ ] // Events. `status` drives the Upcoming vs Past subsections. -// For upcoming events `attendees` = people going; for past = people who attended. -// `recapUrl` is optional — set it on past events to link a recording/photos/writeup. +// Optional fields render only when set: `time`, `location`, `attendees` (>0), +// `registerUrl` (upcoming — falls back to the WhatsApp community), and +// `recapUrl` (past — links a recording / photos / writeup). export const events = [ // ── Upcoming ──────────────────────────────────────────────────────────── { id: 1, - title: "Monthly Meetup — Kigali", - date: "Saturday, July 12, 2026", + title: "Python/Django July Meetup 2026", + date: "Friday, 24 July 2026", time: "2:00 PM", - location: "Kigali Innovation Hub", + location: "GIZ Digital Transformation Center, Rwanda", description: - "Lightning talks, networking, and coffee with fellow Django developers.", + "A community meetup for Python and Django developers — talks, networking, and hands-on sessions.", status: "upcoming", - attendees: 45, - recapUrl: "", - }, - { - id: 2, - title: "Building APIs with Django REST", - date: "Saturday, August 9, 2026", - time: "10:00 AM", - location: "Online", - description: - "A hands-on workshop on designing and shipping production-ready REST APIs.", - status: "upcoming", - attendees: 30, + attendees: 0, + registerUrl: + "https://docs.google.com/forms/d/e/1FAIpQLSetBc2-fgyo1IRR3_8hQ1mMDc-LCIwD5fWv7FxcsfXUTrf2Ww/viewform", recapUrl: "", }, // ── Past ──────────────────────────────────────────────────────────────── { - id: 3, - title: "Intro to Django Meetup", - date: "June 14, 2026", - time: "2:00 PM", - location: "Kigali Innovation Hub", - description: - "Newcomers built their first Django app and met the community.", - status: "past", - attendees: 60, - recapUrl: "", // TODO: link recording / photos / writeup - }, - { - id: 4, - title: "Django Bootcamp — Q1 2026", - date: "Jan 15 – Mar 15, 2026", - time: "Flexible", - location: "Online + In-person", - description: - "An intensive 8-week bootcamp where members built and shipped real Django projects.", - status: "past", - attendees: 200, - recapUrl: "", // TODO: link recording / photos / writeup - }, - { - id: 5, - title: "DjangoGirls Kigali", - date: "March 8, 2026", - time: "9:00 AM", - location: "Norrsken House Kigali", + id: 2, + title: "Python & Django Rwanda Bootcamp", + date: "February – April 2026", + time: "", + location: "", description: - "A free, beginner-friendly workshop introducing women to web development with Django.", + "A 3-month intensive bootcamp covering Python and Django through hands-on, real-world projects.", status: "past", - attendees: 80, + attendees: 0, + registerUrl: "", recapUrl: "", // TODO: link recording / photos / writeup }, ] From d49551cf9427d2b9ddfaa36315b2c24e28bb41dd Mon Sep 17 00:00:00 2001 From: Jean Paul Elisa NIYOKWIZERWA Date: Tue, 30 Jun 2026 20:16:11 +0200 Subject: [PATCH 3/3] chore(team): remove 'Want to Join Our Team?' CTA --- src/components/home-sections/team-section.tsx | 23 +------------------ 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/src/components/home-sections/team-section.tsx b/src/components/home-sections/team-section.tsx index 1d3dd21..28d571c 100644 --- a/src/components/home-sections/team-section.tsx +++ b/src/components/home-sections/team-section.tsx @@ -1,4 +1,4 @@ -import { teamMembers, communityLinks } from "@/src/lib/constants"; +import { teamMembers } from "@/src/lib/constants"; import { Card } from "@/src/components/ui/card"; import Image from "next/image"; import { Github, Linkedin, Twitter } from "lucide-react"; @@ -76,27 +76,6 @@ export function TeamSection() { ))} - - {/* Join the team CTA */} -
-
-

- Want to Join Our Team? -

-

- We're always looking for passionate individuals to help grow - the Django community in Rwanda. -

- - Get Involved - -
-
);