104 lines
2.5 KiB
TypeScript
104 lines
2.5 KiB
TypeScript
"use client";
|
|
|
|
import { useInView } from "@/hooks/use-in-view";
|
|
import { useCountUp } from "@/hooks/use-count-up";
|
|
import { Leaf, Zap, Recycle, Music } from "lucide-react";
|
|
|
|
const stats = [
|
|
{
|
|
icon: Recycle,
|
|
value: 2.5,
|
|
suffix: "M lbs",
|
|
label: "Waste Diverted from Landfill",
|
|
decimals: 1,
|
|
},
|
|
{
|
|
icon: Zap,
|
|
value: 850,
|
|
suffix: " MWh",
|
|
label: "Clean Energy Generated",
|
|
decimals: 0,
|
|
},
|
|
{
|
|
icon: Leaf,
|
|
value: 1200,
|
|
suffix: " tons",
|
|
label: "CO2 Emissions Saved",
|
|
decimals: 0,
|
|
},
|
|
{
|
|
icon: Music,
|
|
value: 500,
|
|
suffix: "+",
|
|
label: "Festivals Powered",
|
|
decimals: 0,
|
|
},
|
|
];
|
|
|
|
function StatCard({
|
|
stat,
|
|
isInView,
|
|
delay,
|
|
}: {
|
|
stat: (typeof stats)[0];
|
|
isInView: boolean;
|
|
delay: number;
|
|
}) {
|
|
const count = useCountUp(stat.value, isInView, 2500, stat.decimals);
|
|
|
|
return (
|
|
<div
|
|
className={`text-center ${isInView ? "animate-fade-in-up" : "opacity-0"}`}
|
|
style={{ animationDelay: `${delay}s` }}
|
|
>
|
|
<div className="mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-neon/10 border border-neon/30">
|
|
<stat.icon className="h-7 w-7 text-neon" />
|
|
</div>
|
|
<div className="text-4xl sm:text-5xl font-bold text-cream neon-text mb-2">
|
|
{count}
|
|
{stat.suffix}
|
|
</div>
|
|
<p className="text-cream-dim text-sm">{stat.label}</p>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function ImpactSection() {
|
|
const { ref, isInView } = useInView(0.15);
|
|
|
|
return (
|
|
<section id="impact" className="py-24 px-4" ref={ref}>
|
|
<div className="mx-auto max-w-6xl">
|
|
<div className="text-center mb-16">
|
|
<h2
|
|
className={`text-3xl sm:text-4xl md:text-5xl font-bold mb-4 ${
|
|
isInView ? "animate-fade-in-up" : "opacity-0"
|
|
}`}
|
|
>
|
|
Our <span className="text-neon">Impact</span>
|
|
</h2>
|
|
<p
|
|
className={`text-cream-dim text-lg max-w-2xl mx-auto ${
|
|
isInView ? "animate-fade-in-up" : "opacity-0"
|
|
}`}
|
|
style={{ animationDelay: "0.1s" }}
|
|
>
|
|
Proof that giving a shit actually changes the world.
|
|
</p>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-2 md:grid-cols-4 gap-8 md:gap-12">
|
|
{stats.map((stat, index) => (
|
|
<StatCard
|
|
key={stat.label}
|
|
stat={stat}
|
|
isInView={isInView}
|
|
delay={0.2 + index * 0.1}
|
|
/>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|