// Use VITE_API_URL if set at build time, otherwise derive from current origin const API_URL = import.meta.env.VITE_API_URL || `${window.location.origin}/api`; export interface ParticipantAPI { id: string; name: string; email: string; timezone: string; ics_url: string | null; created_at: string; updated_at: string; } export interface TimeSlotAPI { day: string; hour: number; start_time: string; availability: 'full' | 'partial' | 'none'; availableParticipants: string[]; } export interface CreateParticipantRequest { name: string; email: string; timezone: string; ics_url?: string; } export interface UpdateParticipantRequest { timezone?: string; ics_url?: string; } async function handleResponse(response: Response): Promise { if (!response.ok) { const error = await response.json().catch(() => ({ detail: 'Request failed' })); throw new Error(error.detail || 'Request failed'); } return response.json(); } export async function fetchParticipants(): Promise { const response = await fetch(`${API_URL}/api/participants`); return handleResponse(response); } export async function createParticipant(data: CreateParticipantRequest): Promise { const response = await fetch(`${API_URL}/api/participants`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data), }); return handleResponse(response); } export async function updateParticipant(id: string, data: UpdateParticipantRequest): Promise { const response = await fetch(`${API_URL}/api/participants/${id}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data), }); return handleResponse(response); } export async function deleteParticipant(id: string): Promise { const response = await fetch(`${API_URL}/api/participants/${id}`, { method: 'DELETE', }); if (!response.ok) { throw new Error('Failed to delete participant'); } } export async function fetchAvailability(participantIds: string[]): Promise { const response = await fetch(`${API_URL}/api/availability`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ participant_ids: participantIds }), }); const data = await handleResponse<{ slots: TimeSlotAPI[] }>(response); return data.slots; } export async function syncCalendars(): Promise { const response = await fetch(`${API_URL}/api/sync`, { method: 'POST' }); if (!response.ok) { throw new Error('Failed to sync calendars'); } } export async function syncParticipant(id: string): Promise { const response = await fetch(`${API_URL}/api/sync/${id}`, { method: 'POST' }); if (!response.ok) { throw new Error('Failed to sync participant calendar'); } } export async function scheduleMeeting( participantIds: string[], title: string, description: string, startTime: string, endTime: string, ): Promise<{ email_sent: boolean; zulip_sent: boolean }> { const response = await fetch(`${API_URL}/api/schedule`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ participant_ids: participantIds, title, description, start_time: startTime, end_time: endTime, }), }); return handleResponse(response); }