Initial commit: Electron + React touchscreen kiosk dashboard for Home Assistant
This commit is contained in:
143
src/services/googleCalendar/api.ts
Normal file
143
src/services/googleCalendar/api.ts
Normal file
@@ -0,0 +1,143 @@
|
||||
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');
|
||||
}
|
||||
Reference in New Issue
Block a user