Files
trackgo-fe/apps/product-site/src/components/sections/Ecosystem.tsx
T

195 lines
8.2 KiB
TypeScript

'use client';
import { useTranslations } from 'next-intl';
import { useEffect } from 'react';
export function Ecosystem() {
const t = useTranslations();
useEffect(() => {
const grid = document.getElementById('bentoGrid');
let obs: IntersectionObserver;
if (grid) {
const bars = grid.querySelectorAll<HTMLElement>('.report-bar');
const ring = grid.querySelector<SVGElement>('.ring-progress');
let done = false;
obs = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting && !done) {
done = true;
bars.forEach((bar, i) => {
setTimeout(() => {
if (bar.dataset.w) bar.style.width = bar.dataset.w;
}, i * 150);
});
if (ring && ring.dataset.dash) {
setTimeout(() => {
ring.style.strokeDasharray = ring.dataset.dash!;
}, 200);
}
obs.disconnect();
}
});
},
{ threshold: 0.35 },
);
obs.observe(grid);
}
return () => {
if (obs) obs.disconnect();
};
}, []);
return (
<section className="ecosystem" id="ecosystem">
<div className="container">
<div className="ecosystem-head">
<h2>{t('Ecosystem.title')}</h2>
<p>{t('Ecosystem.desc')}</p>
</div>
<div className="bento" id="bentoGrid">
{/* Ticketing */}
<div className="bento-card bento-r1">
<h3>{t('Ecosystem.ticketing.title')}</h3>
<p>{t('Ecosystem.ticketing.desc')}</p>
<div className="bento-illustration">
<div className="ticket-rows">
<div className="ticket-row">
<div className="ticket-track drift-a" style={{ marginLeft: '-14px' }}>
<span className="pill pill-outline">TX24409198-8798</span>
<span className="pill pill-orange">TX24409198-8797</span>
<span className="pill pill-lime">TX24409198-8798</span>
<span className="pill pill-outline">TX24409198-8901</span>
<span className="pill pill-navy">TX24409198-8811</span>
</div>
</div>
<div className="ticket-row">
<div className="ticket-track drift-b" style={{ marginLeft: '-32px' }}>
<span className="pill pill-lime">TX24409198-8801</span>
<span className="pill pill-outline">TX24409198-8787</span>
<span className="pill pill-navy">TX24409198-8786</span>
<span className="pill pill-outline">TX24409198-8901</span>
<span className="pill pill-outline">TX24409198-8881</span>
</div>
</div>
<div className="ticket-row">
<div className="ticket-track drift-a" style={{ marginLeft: '-22px', animationDelay: '-1.4s' }}>
<span className="pill pill-outline">TX24409198-8902</span>
<span className="pill pill-lime">TX24409198-8788</span>
<span className="pill pill-outline">TX24409198-8790</span>
<span className="pill pill-orange">TX24409198-8905</span>
<span className="pill pill-outline">TX24409198-8812</span>
</div>
</div>
</div>
</div>
</div>
{/* Access Management */}
<div className="bento-card bento-r2">
<div className="bento-illustration access-illustration">
<div className="chip-row">
<div className="chip active">
<span>{t('Ecosystem.stats.qr')}</span>
<i className="uil uil-qrcode-scan"></i>
</div>
<div className="chip">
<span>{t('Ecosystem.stats.gate')}</span>
<i className="uil uil-monitor-heart-rate"></i>
</div>
<div className="chip">
<span>{t('Ecosystem.stats.rfid')}</span>
<i className="uil uil-rss-interface"></i>
</div>
</div>
<div className="ring-wrap">
<svg width="140" height="140" viewBox="0 0 100 100">
<defs>
<linearGradient id="rainbowGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stopColor="#f66b0e" />
<stop offset="70%" stopColor="#112b3c" />
<stop offset="100%" stopColor="#205375" />
</linearGradient>
</defs>
<circle cx="50" cy="50" r="34" fill="none" stroke="#E1E5E3" strokeWidth="9" />
<circle
className="ring-progress"
cx="50"
cy="50"
r="34"
fill="none"
stroke="url(#rainbowGrad)"
strokeWidth="9"
strokeLinecap="round"
data-dash="166 213.6"
transform="rotate(-90 50 50)"
/>
</svg>
<div className="ring-text">
<b>0.4s</b>
<small>{t('Ecosystem.stats.avg')}</small>
</div>
</div>
</div>
<h3>{t('Ecosystem.access.title')}</h3>
<p>{t('Ecosystem.access.desc')}</p>
</div>
{/* Visitor Operations */}
<div className="bento-card bento-r3">
<div className="bento-illustration visitor-illustration">
<div className="avatar-row">
<div className="avatar-stack">
<div className="avatar" style={{ background: '#b9f001' }}></div>
<div className="avatar" style={{ background: '#f66b0e' }}></div>
<div className="avatar" style={{ background: '#112b3c' }}></div>
<div className="avatar" style={{ background: '#e1e5e3' }}></div>
</div>
<span>{t('Ecosystem.stats.queue')}</span>
</div>
<div className="zone-grid">
<div className="zone-cell" style={{ background: '#e1e5e3' }}></div>
<div className="zone-cell" style={{ background: '#e1e5e3' }}></div>
<div className="zone-cell" style={{ background: '#205375' }}></div>
<div className="zone-cell" style={{ background: '#e1e5e3' }}></div>
<div className="zone-cell" style={{ background: '#e1e5e3' }}></div>
<div className="zone-cell" style={{ background: '#b9f001' }}></div>
<div className="zone-cell" style={{ background: '#e1e5e3' }}></div>
<div className="zone-cell" style={{ background: 'linear-gradient(135deg, #205375, #112b3c)' }}></div>
</div>
</div>
<h3>{t('Ecosystem.visitor.title')}</h3>
<p>{t('Ecosystem.visitor.desc')}</p>
</div>
{/* Report */}
<div className="bento-card bento-r4">
<h3 style={{ marginBottom: '8px' }}>{t('Ecosystem.report.title')}</h3>
<p style={{ marginBottom: '26px' }}>{t('Ecosystem.report.desc')}</p>
<div className="report-bars">
{[
{ w: '150px', bg: '#b9f001', val: 'Rp32.5M', key: 'Ecosystem.stats.revenue' },
{ w: '220px', bg: '#f66b0e', val: '1,284', key: 'Ecosystem.stats.visitors' },
{ w: '300px', bg: '#112b3c', val: '1,120,240', key: 'Ecosystem.stats.checkin' },
].map((item, idx) => (
<div className="report-bar-row" key={idx}>
<div className="report-bar" data-w={item.w} style={{ background: item.bg }}></div>
<div className="report-bar-value">
<b>{item.val}</b>
<small>{(t as any)(item.key)}</small>
</div>
</div>
))}
</div>
</div>
</div>
</div>
</section>
);
}