Files
2025-11-11 03:08:36 -03:00

112 lines
2.7 KiB
TypeScript

"use client";
import { Clock } from "lucide-react";
import { useEffect, useState } from "react";
import { cn } from "@/lib/utils";
interface AuctionCountdownProps {
endsAt: Date | string | null;
className?: string;
showIcon?: boolean;
}
export function AuctionCountdown({
endsAt,
className,
showIcon = true,
}: AuctionCountdownProps) {
const [timeRemaining, setTimeRemaining] = useState<{
hours: number;
minutes: number;
seconds: number;
total: number;
} | null>(null);
useEffect(() => {
if (!endsAt) {
setTimeRemaining(null);
return;
}
const calculateTimeRemaining = () => {
const endTime = new Date(endsAt).getTime();
const now = Date.now();
const total = endTime - now;
if (total <= 0) {
setTimeRemaining({ hours: 0, minutes: 0, seconds: 0, total: 0 });
return;
}
const hours = Math.floor(total / (1000 * 60 * 60));
const minutes = Math.floor((total % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((total % (1000 * 60)) / 1000);
setTimeRemaining({ hours, minutes, seconds, total });
};
// Calcular imediatamente
calculateTimeRemaining();
// Atualizar a cada segundo
const interval = setInterval(calculateTimeRemaining, 1000);
return () => clearInterval(interval);
}, [endsAt]);
if (!endsAt || !timeRemaining) {
return null;
}
// Determinar cor baseada no tempo restante
const getColorClass = () => {
const totalMinutes = timeRemaining.hours * 60 + timeRemaining.minutes;
if (timeRemaining.total <= 0) {
return "text-red-600 dark:text-red-400";
}
if (totalMinutes < 5) {
return "text-red-500 dark:text-red-400 font-semibold animate-pulse";
}
if (totalMinutes < 60) {
return "text-yellow-600 dark:text-yellow-400";
}
return "text-green-600 dark:text-green-400";
};
// Formatar texto
const getTimeText = () => {
if (timeRemaining.total <= 0) {
return "Leilão encerrado";
}
const totalMinutes = timeRemaining.hours * 60 + timeRemaining.minutes;
if (totalMinutes < 5) {
return "Termina em breve";
}
if (timeRemaining.hours > 0) {
return `${timeRemaining.hours}h ${timeRemaining.minutes}m`;
}
if (timeRemaining.minutes > 0) {
return `${timeRemaining.minutes}m ${timeRemaining.seconds}s`;
}
return `${timeRemaining.seconds}s`;
};
return (
<div className={cn("flex items-center gap-1.5", className)}>
{showIcon && <Clock className={cn("h-3.5 w-3.5", getColorClass())} />}
<span className={cn("text-xs font-medium", getColorClass())}>
{getTimeText()}
</span>
</div>
);
}