o2o-triple-pick/frontend/src/components/Countdown.tsx

48 lines
1.6 KiB
TypeScript

import { useEffect, useState } from "react";
import { type Lang, dict } from "@/lib/i18n";
// "투표 종료까지" 카운트다운 (D7). 마감 = 킥오프 정각(lockAt).
export default function Countdown({ to, lang = "ko" }: { to: string; lang?: Lang }) {
const t = dict(lang);
const label = t.cdUntil;
const [left, setLeft] = useState<number | null>(null);
useEffect(() => {
const target = new Date(to).getTime();
const tick = () => setLeft(Math.max(0, target - Date.now()));
tick();
const id = setInterval(tick, 1000);
return () => clearInterval(id);
}, [to]);
const ended = left !== null && left <= 0;
return (
<div className="flex items-center justify-center gap-2 rounded-xl border border-[var(--line-d)] bg-[var(--bg2)] px-3 py-2.5">
<span className="text-[12px] font-semibold text-[var(--ink-muted)]">
{ended ? t.cdClosed : label}
</span>
{!ended && (
<span
className="font-mono text-[18px] font-extrabold tabular-nums text-[var(--green)]"
style={{ textShadow: "0 0 12px rgba(74,255,160,0.45)" }}
>
{left === null ? "--:--:--" : fmt(left, lang)}
</span>
)}
</div>
);
}
function fmt(ms: number, lang: Lang): string {
const s = Math.floor(ms / 1000);
const d = Math.floor(s / 86400);
const h = Math.floor((s % 86400) / 3600);
const m = Math.floor((s % 3600) / 60);
const sec = s % 60;
const pad = (n: number) => String(n).padStart(2, "0");
const dayUnit = lang === "en" ? "d" : "일";
if (d > 0) return `${d}${dayUnit} ${pad(h)}:${pad(m)}:${pad(sec)}`;
return `${pad(h)}:${pad(m)}:${pad(sec)}`;
}