Origem: D:/Documents/Github/Downloader Arquivos omitidos (segredos, bancos de dados, logs, >50 MB): 0
78 lines
2.6 KiB
TypeScript
78 lines
2.6 KiB
TypeScript
import { useEffect, useState } from "react";
|
|
import { Clock } from "lucide-react";
|
|
import { cn } from "../../lib/utils";
|
|
|
|
interface SessionTimerProps {
|
|
expiresAt: string | null;
|
|
className?: string;
|
|
}
|
|
|
|
export function SessionTimer({ expiresAt, className }: SessionTimerProps) {
|
|
const [timeLeft, setTimeLeft] = useState<string>("--:--");
|
|
const [isCritical, setIsCritical] = useState(false);
|
|
|
|
useEffect(() => {
|
|
if (!expiresAt) {
|
|
return;
|
|
}
|
|
|
|
const tick = () => {
|
|
const now = Date.now();
|
|
const end = new Date(expiresAt).getTime();
|
|
const diff = Math.max(0, end - now);
|
|
|
|
if (diff <= 0) {
|
|
setTimeLeft("Expired");
|
|
setIsCritical(true);
|
|
return;
|
|
}
|
|
|
|
const minutes = Math.floor(diff / 60000);
|
|
const seconds = Math.floor((diff % 60000) / 1000);
|
|
|
|
setTimeLeft(`${minutes.toString().padStart(2, "0")}:${seconds.toString().padStart(2, "0")}`);
|
|
setIsCritical(minutes < 5);
|
|
};
|
|
|
|
tick();
|
|
const interval = setInterval(tick, 1000);
|
|
return () => clearInterval(interval);
|
|
}, [expiresAt]);
|
|
|
|
if (!expiresAt) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<div
|
|
className={cn(
|
|
"inline-flex items-center justify-between gap-4 rounded-[1.5rem] border px-4 py-3 shadow-[0_20px_60px_-40px_rgba(15,23,42,0.95)] backdrop-blur-xl",
|
|
isCritical
|
|
? "border-destructive/30 bg-destructive/10"
|
|
: "border-primary/20 bg-primary/10",
|
|
className
|
|
)}
|
|
>
|
|
<div className="flex items-center gap-3">
|
|
<div
|
|
className={cn(
|
|
"flex h-10 w-10 items-center justify-center rounded-[1rem] border",
|
|
isCritical
|
|
? "border-destructive/30 bg-destructive/10 text-destructive"
|
|
: "border-primary/20 bg-primary/10 text-primary"
|
|
)}
|
|
>
|
|
<Clock className="h-4 w-4" />
|
|
</div>
|
|
<div>
|
|
<p className="text-[11px] font-semibold uppercase tracking-[0.22em] text-muted-foreground/75">
|
|
Session window
|
|
</p>
|
|
<p className="mt-1 text-sm font-semibold text-foreground">Expires in {timeLeft}</p>
|
|
</div>
|
|
</div>
|
|
<span className="text-xs font-medium text-muted-foreground">Auto cleanup</span>
|
|
</div>
|
|
);
|
|
}
|