166 lines
6.2 KiB
TypeScript
166 lines
6.2 KiB
TypeScript
|
|
import { useState } from "react";
|
||
|
|
import { useParams, Link } from "wouter";
|
||
|
|
import { useLanguage } from "../contexts/LanguageContext";
|
||
|
|
import { Reveal } from "../components/Reveal";
|
||
|
|
import { Card, CardContent } from "@/components/ui/card";
|
||
|
|
import { Users, Info, Check, Building2 } from "lucide-react";
|
||
|
|
|
||
|
|
type TabKey = "visionMission" | "goalsPillars" | "advantagesDomains";
|
||
|
|
|
||
|
|
function ListBlock({ title, items }: { title: string; items: string[] }) {
|
||
|
|
return (
|
||
|
|
<div>
|
||
|
|
<h3 className="text-lg font-bold text-primary mb-4">{title}</h3>
|
||
|
|
<ul className="space-y-3">
|
||
|
|
{items.map((item, i) => (
|
||
|
|
<li key={i} className="flex items-start gap-3">
|
||
|
|
<Check className="w-5 h-5 text-primary shrink-0 mt-0.5" />
|
||
|
|
<span className="text-foreground/90 leading-relaxed">{item}</span>
|
||
|
|
</li>
|
||
|
|
))}
|
||
|
|
</ul>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
function StatementBlock({ title, text }: { title: string; text: string }) {
|
||
|
|
return (
|
||
|
|
<div>
|
||
|
|
<h3 className="text-lg font-bold text-primary mb-3">{title}</h3>
|
||
|
|
<p className="text-foreground/90 leading-loose">{text}</p>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
export default function About() {
|
||
|
|
const { t } = useLanguage();
|
||
|
|
const params = useParams<{ section?: string }>();
|
||
|
|
const isCommittees = params.section === "committees";
|
||
|
|
const [tab, setTab] = useState<TabKey>("visionMission");
|
||
|
|
|
||
|
|
const tabs: { key: TabKey; label: string }[] = [
|
||
|
|
{ key: "visionMission", label: t.about.tabVisionMission },
|
||
|
|
{ key: "goalsPillars", label: t.about.tabGoalsPillars },
|
||
|
|
{ key: "advantagesDomains", label: t.about.tabAdvantagesDomains },
|
||
|
|
];
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div className="container mx-auto px-4 py-10">
|
||
|
|
{/* Section toggle: Who we are / Committees */}
|
||
|
|
<div className="flex justify-end mb-8">
|
||
|
|
<div className="inline-flex rounded-full border border-border bg-muted/40 p-1">
|
||
|
|
<Link
|
||
|
|
href="/about"
|
||
|
|
className={`inline-flex items-center gap-2 rounded-full px-5 py-2 text-sm font-medium transition-colors ${
|
||
|
|
!isCommittees
|
||
|
|
? "bg-primary/10 text-primary"
|
||
|
|
: "text-muted-foreground hover:text-primary"
|
||
|
|
}`}
|
||
|
|
data-testid="about-tab-whoWeAre"
|
||
|
|
>
|
||
|
|
<Info className="w-4 h-4" />
|
||
|
|
{t.about.whoWeAre}
|
||
|
|
</Link>
|
||
|
|
<Link
|
||
|
|
href="/about/committees"
|
||
|
|
className={`inline-flex items-center gap-2 rounded-full px-5 py-2 text-sm font-medium transition-colors ${
|
||
|
|
isCommittees
|
||
|
|
? "bg-primary/10 text-primary"
|
||
|
|
: "text-muted-foreground hover:text-primary"
|
||
|
|
}`}
|
||
|
|
data-testid="about-tab-committees"
|
||
|
|
>
|
||
|
|
<Users className="w-4 h-4" />
|
||
|
|
{t.about.committees}
|
||
|
|
</Link>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{isCommittees ? (
|
||
|
|
<Reveal>
|
||
|
|
<h1 className="text-2xl font-bold text-foreground mb-3">{t.about.committeesTitle}</h1>
|
||
|
|
<p className="text-muted-foreground mb-8 max-w-3xl leading-relaxed">
|
||
|
|
{t.about.committeesIntro}
|
||
|
|
</p>
|
||
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||
|
|
{t.about.committeeItems.map((c, i) => (
|
||
|
|
<Reveal key={i} delay={(i % 2) * 0.08} className="h-full">
|
||
|
|
<Card className="h-full">
|
||
|
|
<CardContent className="p-6 flex items-start gap-4">
|
||
|
|
<div className="w-11 h-11 rounded-xl bg-primary/10 text-primary flex items-center justify-center shrink-0">
|
||
|
|
<Building2 className="w-5 h-5" />
|
||
|
|
</div>
|
||
|
|
<div>
|
||
|
|
<h3 className="text-base font-bold text-foreground mb-1">{c.name}</h3>
|
||
|
|
<p className="text-sm text-muted-foreground leading-relaxed">{c.desc}</p>
|
||
|
|
</div>
|
||
|
|
</CardContent>
|
||
|
|
</Card>
|
||
|
|
</Reveal>
|
||
|
|
))}
|
||
|
|
</div>
|
||
|
|
</Reveal>
|
||
|
|
) : (
|
||
|
|
<>
|
||
|
|
{/* Intro green panel */}
|
||
|
|
<Reveal>
|
||
|
|
<section className="rounded-2xl bg-primary text-primary-foreground p-8 md:p-12 mb-10">
|
||
|
|
<h1 className="text-2xl md:text-3xl font-bold mb-5">{t.about.introTitle}</h1>
|
||
|
|
<p className="leading-loose text-primary-foreground/90 max-w-4xl">
|
||
|
|
{t.about.intro}
|
||
|
|
</p>
|
||
|
|
</section>
|
||
|
|
</Reveal>
|
||
|
|
|
||
|
|
{/* Tabs */}
|
||
|
|
<Reveal>
|
||
|
|
<div className="border-b border-border mb-8">
|
||
|
|
<div className="flex flex-wrap gap-2">
|
||
|
|
{tabs.map((tb) => (
|
||
|
|
<button
|
||
|
|
key={tb.key}
|
||
|
|
type="button"
|
||
|
|
onClick={() => setTab(tb.key)}
|
||
|
|
data-testid={`about-section-${tb.key}`}
|
||
|
|
className={`px-4 py-3 text-sm font-medium border-b-2 -mb-px transition-colors ${
|
||
|
|
tab === tb.key
|
||
|
|
? "border-primary text-primary"
|
||
|
|
: "border-transparent text-muted-foreground hover:text-primary"
|
||
|
|
}`}
|
||
|
|
>
|
||
|
|
{tb.label}
|
||
|
|
</button>
|
||
|
|
))}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</Reveal>
|
||
|
|
|
||
|
|
{/* Tab content */}
|
||
|
|
<Reveal>
|
||
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 md:gap-12">
|
||
|
|
{tab === "visionMission" && (
|
||
|
|
<>
|
||
|
|
<StatementBlock title={t.about.visionTitle} text={t.about.visionText} />
|
||
|
|
<StatementBlock title={t.about.missionTitle} text={t.about.missionText} />
|
||
|
|
</>
|
||
|
|
)}
|
||
|
|
{tab === "goalsPillars" && (
|
||
|
|
<>
|
||
|
|
<ListBlock title={t.about.goalsTitle} items={t.about.goals} />
|
||
|
|
<ListBlock title={t.about.pillarsTitle} items={t.about.pillars} />
|
||
|
|
</>
|
||
|
|
)}
|
||
|
|
{tab === "advantagesDomains" && (
|
||
|
|
<>
|
||
|
|
<ListBlock title={t.about.advantagesTitle} items={t.about.advantages} />
|
||
|
|
<ListBlock title={t.about.domainsTitle} items={t.about.domains} />
|
||
|
|
</>
|
||
|
|
)}
|
||
|
|
</div>
|
||
|
|
</Reveal>
|
||
|
|
</>
|
||
|
|
)}
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|