"use client"; import { useEffect, useState } from "react"; import { cn } from "@/lib/utils"; type CountdownLabels = { days: string; hours: string; minutes: string; seconds: string; }; type LaunchCountdownProps = { /** Target launch date as an ISO string. */ targetIso: string; labels: CountdownLabels; /** Shown once the target date has passed. */ launchedLabel: string; /** Arabic script: drop uppercase/letter-spacing on labels. */ arabic?: boolean; className?: string; }; type Remaining = { days: number; hours: number; minutes: number; seconds: number; done: boolean; }; function computeRemaining(target: number): Remaining { const diff = target - Date.now(); if (diff <= 0) { return { days: 0, hours: 0, minutes: 0, seconds: 0, done: true }; } const totalSeconds = Math.floor(diff / 1000); return { days: Math.floor(totalSeconds / 86400), hours: Math.floor((totalSeconds % 86400) / 3600), minutes: Math.floor((totalSeconds % 3600) / 60), seconds: totalSeconds % 60, done: false, }; } function pad(value: number): string { return value.toString().padStart(2, "0"); } export function LaunchCountdown({ targetIso, labels, launchedLabel, arabic = false, className, }: LaunchCountdownProps) { // Start null so the server and first client render match (no hydration // mismatch); the real value is filled in on mount and every second after. const [remaining, setRemaining] = useState(null); useEffect(() => { const target = new Date(targetIso).getTime(); if (Number.isNaN(target)) { return; } setRemaining(computeRemaining(target)); const interval = window.setInterval(() => { setRemaining(computeRemaining(target)); }, 1000); return () => window.clearInterval(interval); }, [targetIso]); if (remaining?.done) { return (

{launchedLabel}

); } const units = [ { key: "days", label: labels.days, value: remaining?.days }, { key: "hours", label: labels.hours, value: remaining?.hours }, { key: "minutes", label: labels.minutes, value: remaining?.minutes }, { key: "seconds", label: labels.seconds, value: remaining?.seconds }, ]; return (
{units.map((unit) => (
{unit.value === undefined ? "--" : pad(unit.value)}
{unit.label}
))}
); }