add kayamandi project

This commit is contained in:
2025-06-13 13:38:52 +02:00
parent 259d512ad9
commit c0b3d412ea
80 changed files with 873 additions and 3632 deletions

View File

@@ -15,6 +15,8 @@ import { CTA } from '@/components/cta'
import { ChevronRightIcon } from '@heroicons/react/24/outline'
import DonateButton from '@/components/donatebutton'
import Participate from '@/components/participate'
import FAQ from '@/components/faq'
export const metadata: Metadata = {
@@ -156,6 +158,7 @@ export default function GetInvolved() {
<Participate/>
<Involvement/>
<CTA />
<FAQ />
<Footer />
</main>
)

View File

@@ -0,0 +1,266 @@
'use client'
import { useState } from 'react'
import Image from 'next/image'
import { Metadata } from 'next'
import { BookmarkIcon, Share2Icon } from 'lucide-react'
import { Container } from '@/components/container'
import { GradientLight } from '@/components/gradient'
import { Navbar } from '@/components/navbar'
import { Footer } from '@/components/footer'
import { Button } from '@/components/button'
import { Heading, Lead } from '@/components/text'
import { CTA } from '@/components/cta'
import { FundingProgressBar } from '@/components/fundingprogressbar'
import ProjectRoadmap from '@/components/ProjectRoadmap'
import DonateButton from '@/components/donatebutton'
import { Pie } from 'react-chartjs-2'
import {
Chart as ChartJS,
ArcElement,
Tooltip,
Legend,
} from 'chart.js'
ChartJS.register(ArcElement, Tooltip, Legend)
// import { CTA } from '@/components/cta' // Uncomment or replace with your actual CTA
const metadata: Metadata = {
title: 'Kayamandi Health Hub Indaba',
description: 'Providing essential health access for 500 families in Kayamandi, South Africa.',
}
const images = [
'/projects/kayamandi/1.jpg',
'/projects/kayamandi/2.jpg',
'/projects/kayamandi/3.jpg',
'/projects/kayamandi/4.jpg',
'/projects/kayamandi/5.jpg',
'/projects/kayamandi/6.jpg',
]
const data = {
labels: [
'Healthcare Staff Salaries',
'Medical Equipment & Supplies',
'Training & Community Outreach',
'Operations & Maintenance',
'Monitoring & Evaluation',
],
datasets: [
{
label: 'Budget Allocation',
data: [35, 25, 15, 15, 10],
backgroundColor: [
'#6366F1', // indigo-500
'#A5B4FC', // indigo-300
'#E0E7FF', // indigo-100
'#4F46E5', // indigo-600
'#312E81', // indigo-900
],
borderWidth: 2,
},
],
}
const options = {
responsive: true,
plugins: {
legend: {
position: 'bottom' as const,
labels: {
color: '#374151', // gray-700
font: {
size: 14,
},
},
},
},
}
const roadmapSteps = [
{
title: 'Q1 2024: Facility Renovation & Staffing',
description: 'Completed renovation and hired initial staff for the health hub.',
},
{
title: 'Q2 2024: Pilot Program Launched',
description: 'Launched pilot care services with first 100 families onboarded.',
},
{
title: 'Q3 2024: Community Expansion to 500+ families',
description: 'Scaling outreach and services to 500+ families in Kayamandi.',
},
{
title: 'Q1 2025: Data Report & Potential Replication in Langa Township',
description: 'Publishing impact report and preparing for expansion to Langa.',
},
]
function KayamandiHero() {
const [selectedImage, setSelectedImage] = useState(images[0])
return (
<div className="mx-auto max-w-7xl px-6 py-12 lg:flex lg:items-start lg:gap-16">
{/* Image Gallery */}
<div className="lg:w-1/2 w-full">
<div className="relative w-full aspect-[3/2] rounded-xl overflow-hidden">
<Image
src={selectedImage}
alt="Kayamandi project image"
fill
className="object-cover"
sizes="(max-width: 1024px) 100vw, 50vw"
/>
</div>
<div className="mt-4 flex gap-2 overflow-x-auto">
{images.map((img) => (
<button
key={img}
onClick={() => setSelectedImage(img)}
className={`relative h-20 w-28 shrink-0 rounded-md overflow-hidden border ${selectedImage === img ? 'border-indigo-600' : 'border-gray-300'}`}
>
<Image src={img} alt="Thumbnail" fill className="object-cover" />
</button>
))}
</div>
</div>
{/* Text Content */}
<div className="mt-10 lg:mt-0 lg:w-1/2">
<p className="text-sm font-medium text-indigo-600 mb-2">Phase 1</p>
<Heading as="h1">Kayamandi Health Hub</Heading>
<p className="mt-4 text-lg text-gray-700">Providing Essential Health Access for 500 Families in Kayamandi, South Africa.</p>
<p className="text-sm mb-8 text-gray-500">Stellenbosch, South Africa</p>
<FundingProgressBar
current={22397}
goal={86778}
backers={207}
/>
<div className="mt-8 flex flex-wrap gap-4">
<Button variant="outline" className="flex items-center gap-2">
<BookmarkIcon className="h-4 w-4" /> Save for Later
</Button>
<Button variant="outline" className="flex items-center gap-2">
<Share2Icon className="h-4 w-4" /> Share
</Button>
</div>
</div>
</div>
)
}
function ProjectDetails() {
return (
<div className="bg-white py-12 px-6 lg:px-8">
<div className="mx-auto max-w-7xl flex flex-col lg:flex-row gap-12">
{/* Left Column: Main Content */}
<div className="w-full lg:w-1/2 space-y-14">
{/* Project Overview */}
<div>
<ProjectRoadmap steps={roadmapSteps} />
</div>
{/* Problem & Opportunity */}
<div>
<Lead>🚨 Problem & Opportunity</Lead>
<p className="mt-4 text-gray-700 text-lg leading-relaxed">
In underserved areas like Kayamandi, access to primary healthcare remains limited. Many families face long waits,
lack of transportation, and unaffordable costs. This gap disproportionately affects mothers and children, who are
most vulnerable to preventable health issues.
</p>
</div>
{/* Solution Summary */}
<div>
<Lead>💡 Solution Summary</Lead>
<p className="mt-4 text-gray-700 text-lg leading-relaxed">
Indaba's Kayamandi Health Hub offers accessible, community-centered care—including wellness checkups, child growth
monitoring, nutrition education, and maternal support. Through strategic partnerships and a local-first approach,
we transform access into long-term wellbeing.
</p>
</div>
{/* Highlights */}
<div>
<Lead>✨ Highlights / Impact Teasers</Lead>
<ul className="mt-4 space-y-3 text-gray-700 text-lg list-disc list-inside">
<li>🏥 Over <strong>500 families</strong> now have regular access to primary care</li>
<li>👩🏽‍⚕️ Led by a <strong>90% local healthcare team</strong> with cultural and language alignment</li>
<li>📈 <strong>Increased vaccination and wellness coverage</strong> by 3x within 6 months</li>
</ul>
</div>
{/* Impact Goals */}
<div>
<Lead>🎯 Impact Goals & KPIs</Lead>
<ul className="mt-4 space-y-3 text-gray-700 text-lg list-disc list-inside">
<li>100% of children under 6 receive regular growth & wellness monitoring</li>
<li>80% of mothers report improved health literacy after workshops</li>
<li>90% of acute care cases are managed locally without hospital escalation</li>
</ul>
</div>
{/* Funding Model */}
<div>
<Lead>💸 Funding Model</Lead>
<p className="mt-4 text-gray-700 text-lg leading-relaxed">
<strong>Capped Investment Model:</strong> Investors contribute capital to launch and stabilize the health hub operations.
Returns are modest and capped, with surplus reinvested into community training and equipment upgrades.
</p>
</div>
{/* Right Column: Budget */}
<div className='w-3/4'>
<Pie data={data} options={options} />
</div>
<div className="text-gray-700 text-lg leading-relaxed space-y-4">
<p>We believe in transparency. Every contribution is carefully allocated to maximize impact and sustainability.
</p>
<ul className="list-disc list-inside space-y-2">
<li><strong>35%</strong> Healthcare staff salaries & local hiring</li>
<li><strong>25%</strong> Essential medical equipment & supplies</li>
<li><strong>15%</strong> Community outreach & maternal training</li>
<li><strong>15%</strong> Operations & facility maintenance</li>
<li><strong>10%</strong> Monitoring, feedback & evaluations</li>
</ul>
</div>
</div>
{/* Right Column: Sticky Donate Button */}
<div className="w-full lg:w-1/2">
<div className="sticky top-24">
<DonateButton />
</div>
</div>
</div>
</div>
)
}
export default function Kayamandi() {
return (
<main className="overflow-hidden">
<GradientLight />
<Container>
<Navbar color="black" />
</Container>
<KayamandiHero />
<ProjectDetails />
<CTA />
</main>
)
}
// Uncomment or replace with your actual CTA component

View File

@@ -2,4 +2,71 @@
import { Button } from './button'
import { Heading, Subheading } from './text'
import { clsx } from 'clsx'
import { ChevronRightIcon } from '@heroicons/react/20/solid'
import { ChevronRightIcon } from '@heroicons/react/20/solid'
import { Disclosure, DisclosureButton, DisclosurePanel } from '@headlessui/react'
import { MinusSmallIcon, PlusSmallIcon } from '@heroicons/react/24/outline'
const faqs = [
{
question: "What is Indaba and what does it stand for?",
answer:
"Indaba is a social business dedicated to empowering young people through education, vocational training, and community-led initiatives. The word 'Indaba' means 'a gathering with purpose' in Zulu.",
},
{
question: "How does Indaba select its projects?",
answer:
"Projects are selected based on urgent community needs, the opportunity for long-term impact, and alignment with our three focus areas: Early Childhood, Youth Empowerment, and Vocational Regeneration.",
},
{
question: "Where does my donation go?",
answer:
"100% of your donation goes directly to funding the project you support. Our operational costs are covered by separate patrons and partners who believe in our mission.",
},
{
question: "Can I support a specific age group or region?",
answer:
"Yes! Our projects are categorized by phase (06, 615, 1525, and All Ages), and each project clearly states its region, focus, and funding model so you can support what resonates most.",
},
{
question: "What kind of impact does Indaba have?",
answer:
"We measure impact through clear KPIs—such as number of learners reached, parents trained, and jobs created. Our community-led approach ensures long-term change that scales.",
},
{
question: "Can I volunteer or get involved beyond donations?",
answer:
"Absolutely. You can become a volunteer, ambassador, project backer, or even nominate a country or cause. Visit our Get Involved page to see how you can join the movement.",
},
]
export default function FAQ() {
return (
<div className="bg-white">
<div className="mx-auto max-w-7xl px-6 pb-32 pt-12 lg:px-8">
<div className="mx-auto max-w-4xl">
<h2 className="text-4xl font-semibold tracking-tight text-gray-900 sm:text-5xl">
Frequently Asked Questions
</h2>
<dl className="mt-16 divide-y divide-gray-900/10">
{faqs.map((faq) => (
<Disclosure key={faq.question} as="div" className="py-6 first:pt-0 last:pb-0">
<dt>
<DisclosureButton className="group flex w-full items-start justify-between text-left text-gray-900">
<span className="text-base/7 font-semibold">{faq.question}</span>
<span className="ml-6 flex h-7 items-center">
<PlusSmallIcon aria-hidden="true" className="size-6 group-data-open:hidden" />
<MinusSmallIcon aria-hidden="true" className="size-6 group-not-data-open:hidden" />
</span>
</DisclosureButton>
</dt>
<DisclosurePanel as="dd" className="mt-2 pr-12">
<p className="text-base/7 text-gray-600">{faq.answer}</p>
</DisclosurePanel>
</Disclosure>
))}
</dl>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,48 @@
'use client'
import React from 'react'
interface FundingProgressBarProps {
current: number
goal: number
backers: number
currency?: string
}
export function FundingProgressBar({
current,
goal,
backers,
currency = '€',
}: FundingProgressBarProps) {
const percent = Math.min((current / goal) * 100, 100)
return (
<div className="space-y-2 text-indigo-950">
<div className="flex justify-between items-center text-sm font-medium">
<div className="text-2xl font-semibold">
{currency}
{current.toLocaleString()}{' '}
<span className="text-sm font-normal">EUR</span>
</div>
<div className="text-sm">
<span className="font-bold">{backers}</span> backers
</div>
</div>
{/* Progress Bar */}
<div className="h-3 w-full rounded-full bg-gray-200">
<div
className="h-full bg-indigo-600 rounded-full transition-all"
style={{ width: `${percent}%` }}
/>
</div>
<div className="text-sm font-medium">
{percent.toFixed(0)}% of {currency}
{goal.toLocaleString()}{' '}
<span className="underline underline-offset-2">Flexible Goal</span>
</div>
</div>
)
}

View File

@@ -32,7 +32,7 @@ export default function Participate() {
{projects.map((project) => (
<div key={project.id} className="relative rounded-2xl overflow-hidden bg-gray-900 text-white shadow-lg aspect-[4/3]">
<img src={project.imageUrl} alt={project.title} className="absolute inset-0 w-full h-full object-cover opacity-50" />
<div className="absolute inset-0 bg-gradient-to-t from-black/80 via-black/20 to-transparent" />
<div className="absolute inset-0 bg-gradient-to-t from-black/50 via-black/20 to-transparent" />
<div className="relative p-6 flex flex-col justify-end h-full">
<h3 className="text-2xl lg:text-4xl font-light mt-2">{project.title}</h3>
<div className="text-sm mt-2 text-indigo-300 font-semibold">{project.impactGoal}</div>

View File

@@ -0,0 +1,32 @@
'use client'
import { CheckCircleIcon } from '@heroicons/react/20/solid'
interface Step {
title: string
description: string
completed?: boolean
}
interface ProjectRoadmapProps {
steps: Step[]
}
export default function ProjectRoadmap({ steps }: ProjectRoadmapProps) {
return (
<div className="bg-white rounded-xl border p-6 shadow-md">
<h2 className="text-2xl font-semibold text-indigo-700 mb-6">📍 Timeline & Roadmap</h2>
<ol className="relative border-l border-gray-300">
{steps.map((step, idx) => (
<li key={idx} className="mb-10 ml-4">
<div className="absolute w-8 h-8 bg-indigo-600 rounded-full -left-4 flex items-center justify-center ring-4 ring-white">
<CheckCircleIcon className="w-5 h-5 text-white" />
</div>
<h3 className="text-lg font-medium text-gray-900">{step.title}</h3>
<p className="text-gray-600">{step.description}</p>
</li>
))}
</ol>
</div>
)
}