'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])); 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 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 parsing JWT token:', error); logout(); return undefined; } }, [isAuthenticated, token, warningTime, logout]); useEffect(() => { if (!showWarning) return undefined; const interval = setInterval(() => { setTimeLeft((prev) => { if (prev <= 1) { // Time's up, log out logout(); return 0; } return prev - 1; }); }, 60000); // Update every minute return () => clearInterval(interval); }, [showWarning, logout]); const handleExtendSession = async () => { try { await checkAuth(); // This will refresh the user data and validate the token setShowWarning(false); setTimeLeft(0); } catch (error) { logger.error('Failed to extend session:', error); logout(); } }; const handleLogoutNow = () => { 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?

); }