105 lines
3.0 KiB
TypeScript
105 lines
3.0 KiB
TypeScript
// TODO: could probably be a dynamic import
|
|
import intl from 'intl';
|
|
import 'intl/locale-data/jsonp/en.js';
|
|
|
|
if (!window.Intl) {
|
|
// No `Intl`, so use and load the polyfill.
|
|
window.Intl = intl;
|
|
}
|
|
|
|
import { EventInput, Calendar, CalendarOptions } from '@fullcalendar/core';
|
|
import iCalendarPlugin from '@fullcalendar/icalendar';
|
|
import resourceTimeGridPlugin from '@fullcalendar/resource-timegrid';
|
|
|
|
import { unique_colors } from 'unique-colors';
|
|
|
|
import './index.html';
|
|
import './index.css';
|
|
|
|
const calendars: { [key: string]: string } = {
|
|
computer_lab: '6mmjp85e4732ru6skf1dda54ls@group.calendar.google.com',
|
|
electronics: '1g8atbdschshrg2inf162rcqt4@group.calendar.google.com',
|
|
wood_shop: '4unv3ia1n9mc9u31n2n5lv8nd8@group.calendar.google.com',
|
|
fiber_arts_studio: '7gbndciog37ge0hd8ug33ml70k@group.calendar.google.com',
|
|
jewelry_studio: 'l0dl2jq3vhbi9f4lfmaf5negc0@group.calendar.google.com',
|
|
metal_shop: 'a4p97kiiafatqdr52c3a0cpre0@group.calendar.google.com',
|
|
room_reservations: 'f4ro53uklj2u6pr0se7ucskm6g@group.calendar.google.com',
|
|
};
|
|
|
|
const colors: string[] = unique_colors(Object.keys(calendars).length);
|
|
|
|
const urlParams = new URLSearchParams(window.location.search);
|
|
const toolFilter: string[] | undefined = urlParams.get('tool')?.split(';');
|
|
|
|
function eventDataTransform(eventData: EventInput): EventInput {
|
|
// clear the url to prevent clicking on the event
|
|
delete eventData.url;
|
|
|
|
const match = eventData?.title?.match(/([^\/]*) \| ([^-]*) - (.*)/);
|
|
if (match) {
|
|
const [, member, shop, tool] = match;
|
|
eventData.title = `${member}`;
|
|
eventData.resourceId = tool;
|
|
if (!toolFilter) {
|
|
calendar.addResource({ id: tool, title: tool }, false);
|
|
}
|
|
}
|
|
return eventData;
|
|
}
|
|
|
|
const calendarOptions: CalendarOptions = {
|
|
schedulerLicenseKey: 'CC-Attribution-NonCommercial-NoDerivatives',
|
|
plugins: [iCalendarPlugin, resourceTimeGridPlugin],
|
|
allDaySlot: false,
|
|
nowIndicator: true,
|
|
headerToolbar: { start: '', center: 'title', end: '' },
|
|
initialView: 'resourceTimeGrid',
|
|
height: 'auto',
|
|
slotMinTime: '8:00',
|
|
slotMaxTime: '22:00',
|
|
businessHours: {
|
|
daysOfWeek: [0, 1, 2, 3, 4, 5, 6],
|
|
startTime: '10:00',
|
|
endTime: '21:00',
|
|
},
|
|
eventSources: Object.values(calendars).map((id, idx) => {
|
|
return {
|
|
url: '/calendar/ical/' + id + '/public/basic.ics',
|
|
format: 'ics',
|
|
color: colors[idx],
|
|
eventDataTransform: eventDataTransform,
|
|
};
|
|
}),
|
|
slotLabelFormat: {
|
|
hour: 'numeric',
|
|
minute: '2-digit',
|
|
hour12: false,
|
|
},
|
|
eventTimeFormat: {
|
|
hour: 'numeric',
|
|
minute: '2-digit',
|
|
hour12: false,
|
|
},
|
|
resources: toolFilter
|
|
? toolFilter.map((tool) => {
|
|
return {
|
|
id: tool,
|
|
title: tool,
|
|
};
|
|
})
|
|
: [],
|
|
};
|
|
|
|
const calendarEl = document.getElementById('calendar');
|
|
const calendar = new Calendar(calendarEl!, calendarOptions);
|
|
|
|
calendar.render();
|
|
|
|
function refresh() {
|
|
calendar.refetchEvents();
|
|
calendar.today();
|
|
}
|
|
|
|
// refresh data every five minutes
|
|
window.setInterval(refresh, 5 * 60 * 1000);
|