All checks were successful
CodeAnt AI Review - Stage 1 / codeant-review (pull_request) Successful in 1m4s
134 lines
3.5 KiB
TypeScript
134 lines
3.5 KiB
TypeScript
import { BrandedTag } from "./about/BrandedTag";
|
|
import { PrimaryCTAButton } from "./PrimaryCTAButton";
|
|
import { useAnimatedCounter } from "../redux/hooks/useAnimatedCounter";
|
|
|
|
interface Stat {
|
|
id: string;
|
|
number: number;
|
|
suffix: string;
|
|
label: string;
|
|
display_order: number;
|
|
}
|
|
|
|
interface StatsSectionProps {
|
|
stats: Stat[];
|
|
isLoading?: boolean;
|
|
}
|
|
|
|
interface StatItemProps {
|
|
end: number;
|
|
suffix: string;
|
|
label: string;
|
|
duration?: number;
|
|
}
|
|
|
|
function StatItem({ end, suffix, label, duration = 2000 }: StatItemProps) {
|
|
const { count, ref } = useAnimatedCounter({ end, suffix, duration });
|
|
|
|
return (
|
|
<div className="mb-0">
|
|
<div
|
|
className="w-full h-[1px] mb-4"
|
|
style={{ backgroundColor: "var(--color-brand-gray-muted)" }}
|
|
/>
|
|
|
|
<span
|
|
ref={ref}
|
|
className="stats-number mb-3 leading-none"
|
|
style={{
|
|
color: "var(--color-brand-primary)",
|
|
fontFamily: "var(--font-family-base)",
|
|
}}
|
|
>
|
|
{count}
|
|
</span>
|
|
|
|
<div className="flex items-center mb-4">
|
|
<div
|
|
className="w-2 h-2 mr-3 flex-shrink-0"
|
|
style={{ backgroundColor: "var(--color-brand-accent)" }}
|
|
/>
|
|
<span
|
|
className="text-eyebrow"
|
|
style={{ color: "var(--color-brand-black)" }}
|
|
>
|
|
{label}
|
|
</span>
|
|
</div>
|
|
|
|
<div
|
|
className="w-full h-[1px]"
|
|
style={{ backgroundColor: "var(--color-brand-gray-muted)" }}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function StatsSection({ stats = [], isLoading }: StatsSectionProps) {
|
|
|
|
const sortedStats = [...stats].sort(
|
|
(a, b) => a.display_order - b.display_order
|
|
);
|
|
|
|
if (isLoading) return null;
|
|
|
|
return (
|
|
<section
|
|
className="py-20"
|
|
style={{ backgroundColor: "var(--color-brand-bg-light)" }}
|
|
>
|
|
<div className="section-margin-x">
|
|
<div className="max-w-7xl mx-auto">
|
|
<div className="mb-12 lg:mb-16 md:mb-12 sm:mb-8">
|
|
|
|
<BrandedTag text="Serving Leaders Across Industries" />
|
|
|
|
<div className="grid grid-cols-1 lg:grid-cols-12 gap-8 lg:gap-12 items-start">
|
|
<div className="lg:col-span-6 md:col-span-8 sm:col-span-12">
|
|
<h2 className="text-h2 mb-8">
|
|
Your Partner in Leadership, Culture, and Capability Building
|
|
</h2>
|
|
|
|
<PrimaryCTAButton
|
|
text="About Us"
|
|
onClick={() => console.log("About us clicked")}
|
|
ariaLabel="Learn more about KLC"
|
|
/>
|
|
</div>
|
|
|
|
{/* Desktop */}
|
|
<div className="hidden lg:block lg:col-start-9 lg:col-end-13">
|
|
<div className="space-y-6">
|
|
{sortedStats.map((stat) => (
|
|
<StatItem
|
|
key={stat.id}
|
|
end={stat.number}
|
|
suffix={stat.suffix}
|
|
label={stat.label}
|
|
/>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Mobile */}
|
|
<div className="block lg:hidden mt-12">
|
|
<div className="grid grid-cols-1 gap-6 md:grid-cols-2 sm:gap-8">
|
|
{sortedStats.map((stat) => (
|
|
<StatItem
|
|
key={stat.id}
|
|
end={stat.number}
|
|
suffix={stat.suffix}
|
|
label={stat.label}
|
|
/>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|