const SESSION_TIMEOUT_MS = 30 * 60 * 1000; export const API_URL = import.meta.env.VITE_API_URL || "http://localhost:8000"; interface SessionData { token?: string; username?: string; company?: string; lastActivity?: number; } function getSession(): SessionData { try { return JSON.parse(localStorage.getItem("sap_session") || "{}"); } catch { return {}; } } function saveSession(data: SessionData): void { localStorage.setItem("sap_session", JSON.stringify(data)); } function clearSession(): void { localStorage.removeItem("sap_session"); } export function getToken(): string | null { return getSession().token || null; } export function getUsername(): string | null { return getSession().username || null; } export function getCompany(): string | null { return getSession().company || null; } export function setSession(token: string, username: string, company?: string): void { saveSession({ token, username, company, lastActivity: Date.now() }); } function hasTimedOut(): boolean { const session = getSession(); if (!session.lastActivity) return false; return Date.now() - session.lastActivity > SESSION_TIMEOUT_MS; } function updateLastActivity(): void { const session = getSession(); if (session.token) { session.lastActivity = Date.now(); saveSession(session); } } function expireSession(): void { clearSession(); window.location.href = "/login"; } export async function apiFetch(url: string, options: RequestInit = {}): Promise { if (hasTimedOut()) { expireSession(); throw new Error("Sesión expirada"); } const token = getToken(); const headers: Record = { "Content-Type": "application/json", ...(token ? { "X-Session-Token": token } : {}), }; const customHeaders = options.headers as Record | undefined; if (customHeaders) { for (const key of Object.keys(customHeaders)) { headers[key] = customHeaders[key]; } } const response = await fetch(url, { ...options, headers }); if (response.status === 401) { expireSession(); throw new Error("Sesión expirada"); } updateLastActivity(); return response; }