"use client"; import { logger } from "@/lib/logger"; import { useEffect, useState } from "react"; import { useAuthStore } from "@/lib/auth/store"; import { Button } from "@/components/ui/button"; interface SessionTimeoutWarningProps { warningTime?: number; // Minutes before token expires to show warning } export function SessionTimeoutWarning({ warningTime = 10, // Show warning 10 minutes before expiry }: SessionTimeoutWarningProps) { const { isAuthenticated, token, logout, checkAuth } = useAuthStore(); const [showWarning, setShowWarning] = useState(false); const [timeLeft, setTimeLeft] = useState(0); useEffect(() => { if (!isAuthenticated || !token) { return undefined; } // Parse JWT to get expiry time try { const parts = token.split("."); if (parts.length !== 3) { throw new Error("Invalid token format"); } const payload = JSON.parse(atob(parts[1])) as { exp?: number }; if (!payload.exp) { logger.warn("Token does not have expiration time"); return undefined; } const expiryTime = payload.exp * 1000; // Convert to milliseconds const currentTime = Date.now(); const warningThreshold = warningTime * 60 * 1000; // Convert to milliseconds const timeUntilExpiry = expiryTime - currentTime; const timeUntilWarning = timeUntilExpiry - warningThreshold; if (timeUntilExpiry <= 0) { // Token already expired void logout(); return undefined; } if (timeUntilWarning <= 0) { // Should show warning immediately setShowWarning(true); setTimeLeft(Math.ceil(timeUntilExpiry / 1000 / 60)); // Minutes left return undefined; } else { // Set timeout to show warning const warningTimeout = setTimeout(() => { setShowWarning(true); setTimeLeft(warningTime); }, timeUntilWarning); return () => clearTimeout(warningTimeout); } } catch (error) { logger.error(error, "Error parsing JWT token"); void logout(); return undefined; } }, [isAuthenticated, token, warningTime, logout]); useEffect(() => { if (!showWarning) return undefined; const interval = setInterval(() => { setTimeLeft(prev => { if (prev <= 1) { void logout(); return 0; } return prev - 1; }); }, 60000); return () => clearInterval(interval); }, [showWarning, logout]); const handleExtendSession = () => { void (async () => { try { await checkAuth(); setShowWarning(false); setTimeLeft(0); } catch (error) { logger.error(error, "Failed to extend session"); await logout(); } })(); }; const handleLogoutNow = () => { void logout(); setShowWarning(false); }; if (!showWarning) { return null; } return (
⚠️

Session Expiring Soon

Your session will expire in{" "} {timeLeft} minute{timeLeft !== 1 ? "s" : ""} . Would you like to extend your session?

); }