Files
SatsFaucet/frontend/src/components/Countdown.tsx
Michaël 3734365463 first commit
Made-with: Cursor
2026-02-26 18:33:00 -03:00

51 lines
1.6 KiB
TypeScript

import { useState, useEffect } from "react";
export type CountdownFormat = "clock" | "duration";
interface CountdownProps {
targetUnixSeconds: number;
format?: CountdownFormat;
className?: string;
}
function formatClock(secondsLeft: number): string {
const m = Math.floor(secondsLeft / 60);
const s = secondsLeft % 60;
return `${m}:${s.toString().padStart(2, "0")}`;
}
/**
* Format seconds into "Xd Xh Xm" for "next eligible" style countdown.
* Exported for reuse in denial panel and success modal.
*/
export function formatDuration(secondsLeft: number): string {
if (secondsLeft <= 0) return "0d 0h 0m";
const d = Math.floor(secondsLeft / 86400);
const h = Math.floor((secondsLeft % 86400) / 3600);
const m = Math.floor((secondsLeft % 3600) / 60);
const parts: string[] = [];
if (d > 0) parts.push(`${d}d`);
parts.push(`${h}h`);
parts.push(`${m}m`);
return parts.join(" ");
}
function getSecondsLeft(targetUnixSeconds: number): number {
return Math.max(0, targetUnixSeconds - Math.floor(Date.now() / 1000));
}
export function Countdown({ targetUnixSeconds, format = "clock", className }: CountdownProps) {
const [secondsLeft, setSecondsLeft] = useState(() => getSecondsLeft(targetUnixSeconds));
useEffect(() => {
setSecondsLeft(getSecondsLeft(targetUnixSeconds));
const t = setInterval(() => {
setSecondsLeft(getSecondsLeft(targetUnixSeconds));
}, 1000);
return () => clearInterval(t);
}, [targetUnixSeconds]);
const text = format === "duration" ? formatDuration(secondsLeft) : formatClock(secondsLeft);
return <span className={className}>{text}</span>;
}