From 9110b540d4367c41ef3e7c5610f9537ab91ba1ab Mon Sep 17 00:00:00 2001 From: IsaacMsheliaSamuel Date: Wed, 29 Jul 2026 17:25:42 +0100 Subject: [PATCH] feat(waves): add wave archive pages and data (#74) --- src/App.tsx | 4 + src/components/Header.tsx | 13 ++ src/data/waves/index.ts | 35 +++++ src/data/waves/wave-1.json | 50 +++++++ src/data/waves/wave-2.json | 56 +++++++ src/data/waves/wave-3.json | 56 +++++++ src/data/waves/wave-4.json | 57 ++++++++ src/data/waves/wave-5.json | 57 ++++++++ src/data/waves/wave-6.json | 63 ++++++++ src/data/waves/wave-7.json | 21 +++ src/i18n/en.json | 40 ++++- src/i18n/es.json | 40 ++++- src/pages/Wave.tsx | 292 +++++++++++++++++++++++++++++++++++++ src/pages/Waves.tsx | 217 +++++++++++++++++++++++++++ 14 files changed, 999 insertions(+), 2 deletions(-) create mode 100644 src/data/waves/index.ts create mode 100644 src/data/waves/wave-1.json create mode 100644 src/data/waves/wave-2.json create mode 100644 src/data/waves/wave-3.json create mode 100644 src/data/waves/wave-4.json create mode 100644 src/data/waves/wave-5.json create mode 100644 src/data/waves/wave-6.json create mode 100644 src/data/waves/wave-7.json create mode 100644 src/pages/Wave.tsx create mode 100644 src/pages/Waves.tsx diff --git a/src/App.tsx b/src/App.tsx index 1beeb16..a277462 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -28,6 +28,8 @@ const Stellar = lazy(() => import('./pages/Stellar')); const Roadmap = lazy(() => import('./pages/Roadmap')); const CaseStudies = lazy(() => import('./pages/CaseStudies')); const Careers = lazy(() => import('./pages/Careers')); +const Waves = lazy(() => import('./pages/Waves')); +const Wave = lazy(() => import('./pages/Wave')); const NotFound = lazy(() => import('./pages/NotFound')); function Home() { @@ -74,6 +76,8 @@ export default function App() { } /> } /> } /> + } /> + } /> {/* Wrap Stellar with Layout */} {t('header.nav.roadmap')} + + {t('header.nav.waves')} +
@@ -276,6 +282,13 @@ export default function Header() { > {t('header.nav.roadmap')} + + {t('header.nav.waves')} + = { + completed: { + label: 'Completed', + marker: 'bg-tertiary', + badge: 'border-tertiary text-tertiary', + }, + open: { + label: 'Open', + marker: 'bg-blue', + badge: 'border-blue text-blue', + }, + upcoming: { + label: 'Upcoming', + marker: 'bg-outline', + badge: 'border-outline-variant text-outline', + }, +}; + +function WaveDetail({ wave }: { wave: WaveData }) { + const { t } = useTranslation(); + const meta = statusMeta[wave.status]; + + const formatDate = (iso: string) => + new Intl.DateTimeFormat('en-US', { month: 'long', year: 'numeric' }).format(new Date(iso)); + + const dateRange = + wave.startDate && wave.endDate + ? `${formatDate(wave.startDate)} – ${formatDate(wave.endDate)}` + : wave.status === 'open' + ? t('waves.issuesOpen') + : t('waves.dateTbd'); + + const optedInContributors = wave.contributors.filter((c) => c.optedIn); + const anonCount = wave.contributors.filter((c) => !c.optedIn).length; + + // Schema.org structured data + const structuredData = { + '@context': 'https://schema.org', + '@type': 'Event', + name: `Wraith Protocol Wave ${wave.number}: ${wave.title}`, + description: wave.summary, + ...(wave.startDate && { startDate: wave.startDate }), + ...(wave.endDate && { endDate: wave.endDate }), + organizer: { + '@type': 'Organization', + name: 'Wraith Protocol', + url: 'https://usewraith.xyz', + }, + }; + + return ( + +