const API_BASE_URL = "http://localhost:8000/api"; let authToken = null; let tokenRefreshTimer = null; export function setToken(token) { authToken = token; localStorage.setItem("authToken", token); scheduleTokenRefresh(); } export function getToken() { if (!authToken) { authToken = localStorage.getItem("authToken"); } return authToken; } export function clearToken() { authToken = null; localStorage.removeItem("authToken"); if (tokenRefreshTimer) { clearTimeout(tokenRefreshTimer); } } function scheduleTokenRefresh() { // Refresh token 5 minutes before expiry (assuming 24h token) const refreshIn = 23 * 60 * 60 * 1000; // 23 hours if (tokenRefreshTimer) { clearTimeout(tokenRefreshTimer); } tokenRefreshTimer = setTimeout(async () => { try { // Re-login would require stored credentials // For now, just notify user to re-login console.warn("Token expiring soon, please re-login"); } catch (error) { console.error("Token refresh failed:", error); } }, refreshIn); } async function request(endpoint, options = {}) { const url = `${API_BASE_URL}${endpoint}`; const headers = { "Content-Type": "application/json", ...options.headers, }; const token = getToken(); if (token) { headers["Authorization"] = `Bearer ${token}`; } const response = await fetch(url, { ...options, headers, }); if (response.status === 401) { const error = await response.json(); if (error.detail?.error === "token_expired") { clearToken(); window.electronAPI.navigate("login"); throw new Error("Session expired, please login again"); } throw new Error(error.detail || "Unauthorized"); } if (!response.ok) { const error = await response.json().catch(() => ({})); throw new Error(error.detail || `HTTP error ${response.status}`); } // Handle blob responses for export if (options.responseType === "blob") { return response.blob(); } return response.json(); } // Auth API export async function login(email, password) { const data = await request("/login", { method: "POST", body: JSON.stringify({ email, password }), }); setToken(data.token); localStorage.setItem("userEmail", data.email); localStorage.setItem("userRole", data.role); return data; } export async function getMe() { return request("/me"); } // Meetings API export async function getMeetings() { return request("/meetings"); } export async function getMeeting(id) { return request(`/meetings/${id}`); } export async function createMeeting(meeting) { return request("/meetings", { method: "POST", body: JSON.stringify(meeting), }); } export async function updateMeeting(id, meeting) { return request(`/meetings/${id}`, { method: "PUT", body: JSON.stringify(meeting), }); } export async function deleteMeeting(id) { return request(`/meetings/${id}`, { method: "DELETE", }); } export async function updateActionItem(meetingId, actionId, data) { return request(`/meetings/${meetingId}/actions/${actionId}`, { method: "PUT", body: JSON.stringify(data), }); } // AI API export async function summarizeTranscript(transcript) { return request("/ai/summarize", { method: "POST", body: JSON.stringify({ transcript }), }); } // Export API export async function exportMeeting(id) { return request(`/meetings/${id}/export`, { responseType: "blob", }); }