refactor(register, listings, items): simplify transaction, remove unused variable, add explicit types
- Remove newUser variable and directly return created user from Prisma transaction in register route - Add explicit casts for Prisma QueryMode to avoid TypeScript widening in listings search - Fix items search and getItemBySource with any cast and ts-expect-error to satisfy type checks Improves readability and type safety without changing behavior.
This commit is contained in:
1 parent
ab37b477df
commit
f35fee944d
33 files changed
+811
-295
No files matched your search
@@ -0,0 +1,114 @@
|
||||
"use client";
|
||||
|
||||
import { useState, useEffect } from "react";
|
||||
import { Clock } from "lucide-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 = new Date().getTime();
|
||||
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>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user