Files
doormile_react/src/components/sections/AirFreightCoverage.tsx

129 lines
3.8 KiB
TypeScript

"use client";
import { useEffect, useRef } from "react";
import gsap from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
if (typeof window !== "undefined") {
gsap.registerPlugin(ScrollTrigger);
}
const STATS = [
{ prefix: "", from: 7000, to: 7500, suffix: "", label: "Delivered packages" },
{ prefix: "2.", from: 1, to: 6, suffix: " bil", label: "Tonnes of goods" },
{ prefix: "", from: 10, to: 100, suffix: "+", label: "Countries covered" },
{ prefix: "", from: 100, to: 550, suffix: "+", label: "Warehouses" },
];
export default function AirFreightCoverage() {
const sectionRef = useRef<HTMLDivElement>(null);
const countersRef = useRef<(HTMLSpanElement | null)[]>([]);
useEffect(() => {
const section = sectionRef.current;
if (!section) return;
const trigger = ScrollTrigger.create({
trigger: section,
start: "top 75%",
once: true,
onEnter: () => {
STATS.forEach((stat, i) => {
const el = countersRef.current[i];
if (!el) return;
const obj = { val: stat.from };
gsap.to(obj, {
val: stat.to,
duration: 2,
ease: "power2.out",
delay: i * 0.12,
onUpdate: () => {
if (el) {
el.textContent = Math.round(obj.val).toLocaleString("en-IN");
}
},
});
});
},
});
return () => { trigger.kill(); };
}, []);
return (
<>
<style dangerouslySetInnerHTML={{ __html: `
.afc4-section {
background: #1F1F1F;
padding: 80px 20px;
}
.afc4-inner {
}
.afc4-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 2px;
}
.afc4-item {
padding: 50px 40px;
background: rgba(255,255,255,0.03);
border: 1px solid rgba(255,255,255,0.07);
display: flex;
flex-direction: column;
gap: 8px;
transition: background 0.35s ease, border-color 0.35s ease;
}
.afc4-item:hover {
background: rgba(192,18,39,0.05);
border-color: rgba(192,18,39,0.25);
}
.afc4-number {
font-family: var(--font-manrope), "Manrope", sans-serif;
font-size: clamp(48px, 5vw, 80px);
font-weight: 800;
color: #FFFFFF;
line-height: 1;
letter-spacing: -0.04em;
}
.afc4-number-suffix {
color: #c01227;
}
.afc4-label {
font-family: var(--font-manrope), "Manrope", sans-serif;
font-size: 14px;
font-weight: 600;
color: rgba(255,255,255,0.45);
text-transform: uppercase;
letter-spacing: 0.06em;
margin-top: 4px;
}
@media (max-width: 1020px) {
.afc4-grid { grid-template-columns: repeat(2, 1fr); }
.afc4-section { padding: 60px 20px; }
}
@media (max-width: 600px) {
.afc4-item { padding: 30px 24px; }
.afc4-section { padding: 40px 20px; }
}
`}} />
<section className="afc4-section" ref={sectionRef}>
<div className="afc4-inner dm-section-container">
<div className="afc4-grid">
{STATS.map((stat, i) => (
<div key={stat.label} className="afc4-item">
<div className="afc4-number">
{stat.prefix && <span>{stat.prefix}</span>}
<span ref={(el) => { countersRef.current[i] = el; }}>{stat.from.toLocaleString("en-IN")}</span>
{stat.suffix && <span className="afc4-number-suffix">{stat.suffix}</span>}
</div>
<div className="afc4-label">{stat.label}</div>
</div>
))}
</div>
</div>
</section>
</>
);
}