import cx from 'classnames';
import styles from '../Mining.module.scss';
type Props = {
hashrate: number;
isActive: boolean;
samples: number[];
sessionAvg?: number;
countdown?: number;
genesisTimeSec?: number;
};
function buildSparklinePath(samples: number[], width: number, height: number) {
if (samples.length < 2) return { line: '', fill: '' };
const max = Math.max(...samples, 1);
const step = width / (samples.length - 1);
const points = samples.map((s, i) => ({
x: i * step,
y: height - (s / max) * height * 0.85 - height * 0.05,
}));
const line = points.map((p, i) => `${i === 0 ? 'M' : 'L'}${p.x},${p.y}`).join(' ');
const fill = `${line} L${points[points.length - 1].x},${height} L${points[0].x},${height} Z`;
return { line, fill };
}
function formatCountdown(seconds: number): string {
if (seconds < 60) return `${seconds}s`;
if (seconds < 3600) {
const m = Math.floor(seconds / 60);
const s = seconds % 60;
return `${m}m ${s}s`;
}
const h = Math.floor(seconds / 3600);
const m = Math.floor((seconds % 3600) / 60);
const s = seconds % 60;
return `${h}h ${m}m ${s}s`;
}
function HashrateHero({ hashrate, isActive, samples, sessionAvg, countdown, genesisTimeSec }: Props) {
// Countdown mode
if (countdown != null && countdown > 0) {
const launchTime = genesisTimeSec
? new Date(genesisTimeSec * 1000).toLocaleString([], { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' })
: '';
return (
<div className={styles.heroContainer}>
<div className={styles.countdownValue}>
{formatCountdown(countdown)}
</div>
{launchTime && (
<div className={styles.countdownLabel}>
Launch at {launchTime}
</div>
)}
</div>
);
}
// Normal hashrate mode
const { line, fill } = buildSparklinePath(samples, 300, 60);
return (
<div className={styles.heroContainer}>
<div className={cx(styles.heroValue, { [styles.heroPulse]: isActive })}>
{hashrate.toFixed(0)}
<span className={styles.heroUnit}> H/s</span>
</div>
<div className={styles.heroAvg} style={{ visibility: isActive && sessionAvg != null && sessionAvg > 0 ? 'visible' : 'hidden' }}>
avg {sessionAvg != null && sessionAvg > 0 ? sessionAvg.toFixed(0) : '0'} H/s
</div>
<svg className={styles.sparkline} viewBox="0 0 300 60" preserveAspectRatio="none">
{samples.length >= 2 && (
<>
<defs>
<linearGradient id="sparkFill" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stopColor="#36d6ae" stopOpacity="0.3" />
<stop offset="100%" stopColor="#36d6ae" stopOpacity="0" />
</linearGradient>
</defs>
<path d={fill} fill="url(#sparkFill)" />
<path d={line} fill="none" stroke="#36d6ae" strokeWidth="2" />
</>
)}
</svg>
</div>
);
}
export default HashrateHero;