diff --git a/app/events/[slug]/page.tsx b/app/events/[slug]/page.tsx
new file mode 100644
index 0000000..a8e6089
--- /dev/null
+++ b/app/events/[slug]/page.tsx
@@ -0,0 +1,363 @@
+import Link from 'next/link';
+import { notFound } from 'next/navigation';
+import { Section, Badge, Button } from '../../../components/UI';
+import { EVENTS } from '../../../data';
+import {
+ ArrowLeft, Calendar, Clock, MapPin, Ticket, ShieldAlert,
+ Swords, Trophy, Users, ExternalLink, AlertTriangle
+} from 'lucide-react';
+
+interface EventPageProps {
+ params: Promise<{ slug: string }>;
+}
+
+export default async function EventDetailPage({ params }: EventPageProps) {
+ const { slug } = await params;
+ const event = EVENTS.find((e) => e.slug === slug);
+
+ if (!event) {
+ notFound();
+ }
+
+ const isTournament = Boolean(event.rules && event.rules.length > 0);
+
+ return (
+
+ {/* Hero Banner */}
+
+
+
+
+
+
+
+
All Events
+
+
+
+ {event.status === 'upcoming' ? 'Upcoming Event' : 'Past Event'}
+ {isTournament && (
+
+ Live 1v1 Knockout
+
+ )}
+ {event.tags.map((tag) => (
+
+ {tag}
+
+ ))}
+
+
+
+ {event.title}
+
+
+
+ {event.description}
+
+
+ {/* Quick Metadata Bar */}
+
+
+
+
+
+
+
Date
+
+ {new Date(event.date).toLocaleDateString('en-UG', {
+ weekday: 'short',
+ year: 'numeric',
+ month: 'short',
+ day: 'numeric',
+ timeZone: 'Africa/Kampala'
+ })}
+
+
+
+
+
+
+
+
+
+
Time
+
{event.time} EAT
+
+
+
+
+
+
+
+
+
Venue
+
{event.venue}
+
{event.address}
+
+
+
+
+ {/* Action Buttons */}
+ {event.ticketsUrl && (
+
+ )}
+
+
+
+
+
+
+ {/* Rules & Integrity Policy (Special for Tournament) */}
+ {event.rules && event.rules.length > 0 && (
+
+
+
+
+ Tournament Rules & Battle Code
+
+
+
+ Strict adherence is required for all competitors. Violations lead to immediate disqualification.
+
+
+
+ {event.rules.map((rule, idx) => (
+
+
+
+
+ Rule #{idx + 1}
+
+ {rule.highlight && (
+
+ {rule.highlight}
+
+ )}
+
+
+ {rule.title}
+
+
+ {rule.description}
+
+
+
+ {idx === 1 && (
+
+
Zero tolerance: AI tools disabled on all devices.
+
+ )}
+
+ ))}
+
+
+ )}
+
+ {/* Knockout Bracket Visualizer */}
+ {event.bracket && event.bracket.length > 0 && (
+
+
+
+
+ Championship Pathway
+
+
+ Knockout Tournament Tree
+
+
+
+ 8 Coders • Single Elimination
+
+
+
+ {/* Bracket Grid */}
+
+ {/* Quarterfinals */}
+
+
+ Quarterfinals (10m Sprint)
+
+ {event.bracket.slice(0, 4).map((m) => (
+
+
{m.round}
+
+ {m.player1}
+ TBD
+
+
+ {m.player2}
+ TBD
+
+
+ ))}
+
+
+ {/* Semifinals */}
+
+
+ Semifinals (15m Deep Dive)
+
+ {event.bracket.slice(4, 6).map((m) => (
+
+
{m.round}
+
+ {m.player1}
+ TBD
+
+
+ {m.player2}
+ TBD
+
+
+ ))}
+
+
+ {/* Grand Final */}
+
+
+ Grand Final (20m Duel)
+
+ {event.bracket.slice(6, 7).map((m) => (
+
+
+ Championship Match
+
+
+ {m.player1}
+ FINALIST 1
+
+
+ {m.player2}
+ FINALIST 2
+
+
+ Winner receives the JSK Code Wars Edition 2 Trophy
+
+
+ ))}
+
+
+
+ )}
+
+ {/* Agenda Timeline */}
+ {event.agenda && event.agenda.length > 0 && (
+
+
+
+
+ Battle Schedule (2:00 PM – 5:00 PM)
+
+
+
+
+ {event.agenda.map((item, idx) => (
+
+
+
+ {item.time}
+
+
+ {item.title}
+
+
+ {item.speaker && (
+
+ {item.speaker}
+
+ )}
+
+ ))}
+
+
+ )}
+
+ {/* Venue & Host Section */}
+
+
+
+
+ Host & Venue Partner
+
+
+ Africa's Talking Uganda Office
+
+
+ Join us in-person at Africa's Talking Office. Experience the intense action with live high-definition code screens, live audio commentary, and direct networking with Uganda's top software engineers and architects.
+
+
+
+
+ {event.address}
+
+
+
+ In-person spectator seating limited to registered attendees.
+
+
+
+
+ {event.ticketsUrl && (
+
+
+ Admission
+
+
+ Free RSVP
+
+
+ Tickets managed through TicketDaddy. Secure your seat before room capacity is reached.
+
+
+ Reserve on TicketDaddy
+
+
+ )}
+
+
+
+
+
+ );
+}
+
+export function generateStaticParams() {
+ return EVENTS.map((event) => ({
+ slug: event.slug,
+ }));
+}
diff --git a/app/events/page.tsx b/app/events/page.tsx
index b2f1841..17895f2 100644
--- a/app/events/page.tsx
+++ b/app/events/page.tsx
@@ -1,6 +1,7 @@
+import Link from 'next/link';
import { Section, Heading, Badge, Button } from '../../components/UI';
import { EVENTS } from '../../data';
-import { Calendar, MapPin, Ticket, Clock } from 'lucide-react';
+import { Calendar, MapPin, Ticket, Clock, Swords, ArrowRight } from 'lucide-react';
export default function Events() {
const upcomingEvents = EVENTS.filter(e => e.status === 'upcoming');
@@ -19,7 +20,7 @@ export default function Events() {
Events
- Join us for meetups, workshops, and conferences. Build skills, make connections, and grow your network.
+ Join us for meetups, workshops, and tournaments. Build skills, make connections, and test your code under pressure.
@@ -35,15 +36,22 @@ export default function Events() {
{event.coverImage && (
-
+
+
+
)}
-
+
+ {event.format && (
+
+ Live 1v1 Tournament
+
+ )}
{event.tags.map(tag => (
{tag}
@@ -51,13 +59,21 @@ export default function Events() {
))}
- {event.title}
+
+ {event.title}
+
{event.description}
-
+
- {new Date(event.date).toLocaleDateString()}
+ {new Date(event.date).toLocaleDateString('en-UG', {
+ weekday: 'short',
+ year: 'numeric',
+ month: 'short',
+ day: 'numeric',
+ timeZone: 'Africa/Kampala'
+ })}
@@ -68,11 +84,16 @@ export default function Events() {
{event.venue}
- {event.ticketsUrl && (
-
- Get Tickets
+
+ {event.ticketsUrl && (
+
+ Reserve Seat
+
+ )}
+
+ Rules & Match Intel
- )}
+
@@ -102,7 +123,9 @@ export default function Events() {
))}
- {event.title}
+
+ {event.title}
+
{new Date(event.date).toLocaleDateString()} • {event.venue}
diff --git a/app/page.tsx b/app/page.tsx
index 9f21779..996629c 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -5,37 +5,26 @@ import Link from 'next/link';
import {
ArrowRight, Calendar, Zap, Github, CheckCircle, Ticket, MapPin,
Terminal, Activity, Users, Monitor, Play,
- Star, GitFork
+ Star, GitFork, X
} from 'lucide-react';
import { Button, Section, Card, Heading, Badge } from '../components/UI';
import { EVENTS, BLOG_POSTS, SPONSORS, PROJECTS } from '../data';
import SponsorsComponent from '@/components/sponsers';
const HeroVideo = () => {
- const videoRef = useRef(null);
const [isPlaying, setIsPlaying] = useState(false);
- const togglePlayback = () => {
- const video = videoRef.current;
- if (!video) return;
- if (video.paused) {
- video.play().catch(() => {}); // handle autoplay block gracefully
- } else {
- video.pause();
- }
- };
-
return (
{/* Header bar – slightly more compact on mobile */}
Spotlight
-
Community Reel
+
JSK Dev Quiz Night Recap
-
Runtime
-
02:34
+
Source
+
YouTube
@@ -43,44 +32,61 @@ const HeroVideo = () => {
- {/* Video wrapper with gradient overlay */}
-
-
setIsPlaying(true)}
- onPause={() => setIsPlaying(false)}
- onClick={togglePlayback}
- />
-
+ {isPlaying ? (
+
+
+ setIsPlaying(false)}
+ className="absolute top-3 right-3 z-40 bg-black/80 hover:bg-js-yellow hover:text-black text-white p-1.5 border border-gray-800 text-xs transition-colors"
+ aria-label="Close video player"
+ >
+
+
+
+ ) : (
+
+
+
- {!isPlaying && (
setIsPlaying(true)}
>
- Watch The Network
+ Watch Recap Video
- )}
-
-
-
-
Kampala JS
-
Community Reel
+
+
+
+ JSK Dev Quiz Night
+
+
+ 2026 Community Recap
+
+
+
FEATURED
+
-
FEATURED
-
+ )}
@@ -209,8 +215,15 @@ const FeaturedEvent = () => {
{/* Text Content Left */}
-
-
Upcoming Summit
+
+
+ {nextEvent.format ? "Upcoming Tournament" : "Upcoming Event"}
+
+ {nextEvent.rules && (
+
+ Live 1v1 • Zero AI
+
+ )}
Don't miss out
@@ -230,8 +243,12 @@ const FeaturedEvent = () => {
{new Date(nextEvent.date).toLocaleDateString("en-UG", {
+ weekday: "short",
+ year: "numeric",
+ month: "short",
+ day: "numeric",
timeZone: "Africa/Kampala",
- })}
+ })}{" "}
— {nextEvent.time}
@@ -247,6 +264,9 @@ const FeaturedEvent = () => {
{nextEvent.venue}
+
+ {nextEvent.address}
+
@@ -264,7 +284,7 @@ const FeaturedEvent = () => {
href={`/events/${nextEvent.slug}`}
className="w-full sm:w-auto"
>
- Event Details
+ Tournament Intel & Rules
diff --git a/data.ts b/data.ts
index a47b3f0..e70cab7 100644
--- a/data.ts
+++ b/data.ts
@@ -1,6 +1,76 @@
import { BlogPost, Event, GalleryItem, Leader, Sponsor, Project } from './types';
export const EVENTS: Event[] = [
+ {
+ slug: 'jsk-code-wars-edition-2',
+ title: "JSK Code Wars Edition 2",
+ date: '2026-11-07T14:00:00+03:00',
+ time: '02:00 PM - 05:00 PM',
+ venue: "Africa's Talking Office",
+ address: 'Victoria Park, Block B, Kampala',
+ city: 'Kampala',
+ status: 'upcoming',
+ format: 'Live 1v1 Knockout Cup (Single Elimination)',
+ description: "East Africa's premier live 1v1 competitive programming tournament inspired by the HackSussex Coders' Cup. 8 elite coders clash head-to-head on the big screen in front of a live audience. Solve algorithmic challenges under extreme time pressure in any programming language of your choice. Strictly zero AI tools permitted.",
+ tags: ['Competition', 'Live Tournament', 'Algorithms', 'No-AI', 'Polyglot'],
+ ticketsUrl: 'https://www.ticketdaddy.io/',
+ videoUrl: 'https://youtu.be/EJPkNt7HbZM',
+ coverImage: 'https://images.unsplash.com/photo-1511512578047-dfb367046420?auto=format&fit=crop&q=80&w=2070',
+ rules: [
+ {
+ title: 'Polyglot Playground (Any Language)',
+ highlight: 'Freedom of Choice',
+ description: 'Competitors can write solutions in ANY programming language (TypeScript, JavaScript, Python, Go, Rust, C++, Java, etc.). You bring your language mastery; we provide the standard test harnesses.'
+ },
+ {
+ title: 'Zero AI Usage Policy',
+ highlight: 'Strictly Enforced',
+ description: 'No GitHub Copilot, Cursor, ChatGPT, Claude, tab autocompletions, or generative assistants of any kind are permitted. All solutions must be reasoned and authored from pure human cognition.'
+ },
+ {
+ title: '1v1 Head-to-Head Knockout',
+ highlight: 'HackSussex Format',
+ description: 'Live bracket single-elimination battles. Code editor feeds projected side-by-side with live test suite progress, live shoutcasters, and spectator hype.'
+ },
+ {
+ title: 'Instant Automated Test Harness',
+ highlight: 'Live Evaluation',
+ description: 'Deterministic test cases run live on screen. The first competitor to pass 100% of test cases (or highest passing rate when the timer expires) advances to the next round.'
+ }
+ ],
+ bracket: [
+ { id: 'm1', round: 'Quarterfinal 1', player1: 'Seed 1', player2: 'Seed 8' },
+ { id: 'm2', round: 'Quarterfinal 2', player1: 'Seed 4', player2: 'Seed 5' },
+ { id: 'm3', round: 'Quarterfinal 3', player1: 'Seed 2', player2: 'Seed 7' },
+ { id: 'm4', round: 'Quarterfinal 4', player1: 'Seed 3', player2: 'Seed 6' },
+ { id: 'm5', round: 'Semifinal 1', player1: 'Winner QF 1', player2: 'Winner QF 2' },
+ { id: 'm6', round: 'Semifinal 2', player1: 'Winner QF 3', player2: 'Winner QF 4' },
+ { id: 'm7', round: 'Grand Final', player1: 'Winner SF 1', player2: 'Winner SF 2' }
+ ],
+ speakers: [
+ {
+ name: 'Tournament Cast & Commentary Team',
+ role: "JS Kampala & Africa's Talking",
+ topic: 'Live Match Casting, Play-by-Play & Edge-Case Analysis',
+ avatar: 'https://images.unsplash.com/photo-1534528741775-53994a69daeb?auto=format&fit=crop&q=80&w=200'
+ },
+ {
+ name: 'Arbitration & Benchmarking Jury',
+ role: 'Technical Lead Judges',
+ topic: 'Polyglot Test Runner & Strict Zero-AI Auditing',
+ avatar: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?auto=format&fit=crop&q=80&w=200'
+ }
+ ],
+ agenda: [
+ { time: '02:00 PM', title: 'Arrival, Environment Setup & Bracket Reveal' },
+ { time: '02:25 PM', title: 'Opening Remarks & Code-of-Combat Rules Briefing' },
+ { time: '02:35 PM', title: 'Quarterfinals: 1v1 Speed Rounds (4 Matches • 10m sprints)' },
+ { time: '03:25 PM', title: "Halftime Break & Africa's Talking Tech Spotlight" },
+ { time: '03:40 PM', title: 'Semifinals: Deep Algorithmic Duels (2 Matches • 15m deep dives)' },
+ { time: '04:20 PM', title: 'Grand Final: The Championship Duel (20m Showdown)' },
+ { time: '04:45 PM', title: 'Awards Ceremony, Trophy Presentation & Networking Mixer' }
+ ]
+ },
{
slug: 'js-kampala-summit-2025',
title: 'JS Kampala Summit 2025: The Future of Web',
@@ -9,7 +79,7 @@ export const EVENTS: Event[] = [
venue: 'Kampala Serena Hotel',
address: 'Kintu Road, Kampala',
city: 'Kampala',
- status: 'upcoming',
+ status: 'past',
description: 'The premier engineering conference in East Africa. Join 500+ developers for a full day of deep dives into React Server Components, AI Engineering, and Cloud Architecture.',
tags: ['Conference', 'Architecture', 'AI'],
ticketsUrl: 'https://eventbrite.com',
@@ -43,7 +113,7 @@ export const EVENTS: Event[] = [
venue: 'Innovation Village',
address: 'Ntinda Complex',
city: 'Kampala',
- status: 'upcoming',
+ status: 'past',
description: 'A deep dive into designing scalable distributed systems. Perfect for Senior Engineers looking to level up.',
tags: ['System Design', 'Backend', 'Workshop'],
coverImage: 'https://images.unsplash.com/photo-1517245386807-bb43f82c33c4?auto=format&fit=crop&q=80&w=2000',
@@ -139,6 +209,14 @@ export const SPONSORS: Sponsor[] = [
logo: 'https://upload.wikimedia.org/wikipedia/commons/4/4b/Andela_logo.png',
url: 'https://www.andela.com/',
description: 'Connecting talent.'
+ },
+ {
+ id: '5',
+ name: "Africa's Talking",
+ tier: 'Gold',
+ logo: 'https://africastalking.com/img/favicon.png',
+ url: 'https://africastalking.com/',
+ description: 'Powering communication & cloud infrastructure across Africa.'
}
];
diff --git a/types.ts b/types.ts
index 6c7e665..abef957 100644
--- a/types.ts
+++ b/types.ts
@@ -13,6 +13,21 @@ export interface AgendaItem {
speaker?: string;
}
+export interface TournamentMatch {
+ id: string;
+ round: string;
+ player1: string;
+ player2: string;
+ winner?: string;
+ score?: string;
+}
+
+export interface TournamentRule {
+ title: string;
+ description: string;
+ highlight?: string;
+}
+
export interface Event {
slug: string;
title: string;
@@ -28,6 +43,11 @@ export interface Event {
tags: string[];
status: 'upcoming' | 'past';
description: string;
+ format?: string;
+ rules?: TournamentRule[];
+ bracket?: TournamentMatch[];
+ videoUrl?: string;
+ venueMapUrl?: string;
}
export interface BlogPost {