112 lines
2.7 KiB
TypeScript
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>
|
|
);
|
|
}
|