Files
imperial-command-center/src/services/googleCalendar/api.ts

144 lines
3.4 KiB
TypeScript

import { googleCalendarAuth } from './auth';
import { startOfMonth, endOfMonth, format } from 'date-fns';
const CALENDAR_API_BASE = 'https://www.googleapis.com/calendar/v3';
export interface CalendarEvent {
id: string;
summary: string;
description?: string;
location?: string;
start: {
dateTime?: string;
date?: string;
timeZone?: string;
};
end: {
dateTime?: string;
date?: string;
timeZone?: string;
};
status: string;
colorId?: string;
}
export interface Calendar {
id: string;
summary: string;
description?: string;
primary?: boolean;
backgroundColor?: string;
foregroundColor?: string;
}
export interface CalendarListResponse {
items: Calendar[];
}
export interface EventsListResponse {
items: CalendarEvent[];
nextPageToken?: string;
}
async function fetchWithAuth(url: string): Promise<Response> {
const token = await googleCalendarAuth.getAccessToken();
if (!token) {
throw new Error('Not authenticated with Google Calendar');
}
const response = await fetch(url, {
headers: {
Authorization: `Bearer ${token}`,
},
});
if (response.status === 401) {
// Token might be invalid, clear and throw
googleCalendarAuth.clearTokens();
throw new Error('Authentication expired, please re-authenticate');
}
if (!response.ok) {
throw new Error(`Calendar API error: ${response.status}`);
}
return response;
}
export async function getCalendarList(): Promise<Calendar[]> {
const response = await fetchWithAuth(`${CALENDAR_API_BASE}/users/me/calendarList`);
const data: CalendarListResponse = await response.json();
return data.items;
}
export async function getEventsForMonth(
calendarId: string = 'primary',
date: Date = new Date()
): Promise<CalendarEvent[]> {
const timeMin = startOfMonth(date).toISOString();
const timeMax = endOfMonth(date).toISOString();
const params = new URLSearchParams({
timeMin,
timeMax,
singleEvents: 'true',
orderBy: 'startTime',
maxResults: '100',
});
const url = `${CALENDAR_API_BASE}/calendars/${encodeURIComponent(calendarId)}/events?${params}`;
const response = await fetchWithAuth(url);
const data: EventsListResponse = await response.json();
return data.items;
}
export async function getEventsForDay(
calendarId: string = 'primary',
date: Date = new Date()
): Promise<CalendarEvent[]> {
const dayStart = new Date(date);
dayStart.setHours(0, 0, 0, 0);
const dayEnd = new Date(date);
dayEnd.setHours(23, 59, 59, 999);
const params = new URLSearchParams({
timeMin: dayStart.toISOString(),
timeMax: dayEnd.toISOString(),
singleEvents: 'true',
orderBy: 'startTime',
});
const url = `${CALENDAR_API_BASE}/calendars/${encodeURIComponent(calendarId)}/events?${params}`;
const response = await fetchWithAuth(url);
const data: EventsListResponse = await response.json();
return data.items;
}
export function getEventTime(event: CalendarEvent): { start: Date; end: Date; allDay: boolean } {
const allDay = !!event.start.date;
let start: Date;
let end: Date;
if (allDay) {
start = new Date(event.start.date!);
end = new Date(event.end.date!);
} else {
start = new Date(event.start.dateTime!);
end = new Date(event.end.dateTime!);
}
return { start, end, allDay };
}
export function formatEventTime(event: CalendarEvent): string {
const { start, allDay } = getEventTime(event);
if (allDay) {
return 'All day';
}
return format(start, 'h:mm a');
}