46 lines
1.5 KiB
JavaScript
46 lines
1.5 KiB
JavaScript
"use client";
|
|
|
|
import { useEffect, useMemo, useState } from "react";
|
|
|
|
function getRemaining(target) {
|
|
const diff = Math.max(0, target - Date.now());
|
|
const days = Math.floor(diff / 86400000);
|
|
const hours = Math.floor((diff % 86400000) / 3600000);
|
|
const minutes = Math.floor((diff % 3600000) / 60000);
|
|
const seconds = Math.floor((diff % 60000) / 1000);
|
|
return { days, hours, minutes, seconds };
|
|
}
|
|
|
|
export default function Countdown() {
|
|
const target = useMemo(() => Date.now() + 72 * 60 * 60 * 1000, []);
|
|
const [time, setTime] = useState(() => getRemaining(target));
|
|
const [isMounted, setIsMounted] = useState(false);
|
|
const units = [
|
|
["seconds", "ثانیه", time.seconds],
|
|
["minutes", "دقیقه", time.minutes],
|
|
["hours", "ساعت", time.hours],
|
|
["days", "روز", time.days]
|
|
];
|
|
|
|
useEffect(() => {
|
|
setIsMounted(true);
|
|
const timer = setInterval(() => setTime(getRemaining(target)), 1000);
|
|
return () => clearInterval(timer);
|
|
}, [target]);
|
|
|
|
return (
|
|
<div className="sale-countdown" aria-label="زمان باقی مانده فروش ویژه">
|
|
<span className="sale-countdown-label">پایان فروش ویژه</span>
|
|
{units.map(([name, label, value]) => {
|
|
const display = String(value).padStart(2, "0");
|
|
return (
|
|
<span className="flip-unit" key={name}>
|
|
<strong className={`flip-card ${isMounted ? "flip-changing" : ""}`} key={`${name}-${display}`}>{display}</strong>
|
|
<small>{label}</small>
|
|
</span>
|
|
);
|
|
})}
|
|
</div>
|
|
);
|
|
}
|