129 lines
4.7 KiB
JavaScript
129 lines
4.7 KiB
JavaScript
import ICAL from "../lib/ical.min.js"
|
|
|
|
document.addEventListener("DOMContentLoaded", function() {
|
|
const monthNames = ["January", "February", "March", "April", "May", "June",
|
|
"July", "August", "September", "October", "November", "December"];
|
|
|
|
let currentMonth = new Date().getMonth();
|
|
let currentYear = new Date().getFullYear();
|
|
let eventsData = {};
|
|
|
|
fetch('http://mario.sdf.org/public_events.ical')
|
|
.then(response => response.text())
|
|
.then(data => {
|
|
const parsedICal = ICAL.parse(data);
|
|
const comp = new ICAL.Component(parsedICal);
|
|
const vevents = comp.getAllSubcomponents('vevent');
|
|
|
|
vevents.forEach(event => {
|
|
const eventStart = ICAL.Time.fromData(event.getFirstPropertyValue('dtstart')).toJSDate();
|
|
const eventDate = new Date(eventStart.getFullYear(), eventStart.getMonth(), eventStart.getDate());
|
|
|
|
const key = `${eventDate.getFullYear()}-${eventDate.getMonth() + 1}-${eventDate.getDate()}`;
|
|
if (!eventsData[key]) {
|
|
eventsData[key] = [];
|
|
}
|
|
|
|
eventsData[key].push(event.getFirstPropertyValue('summary'));
|
|
});
|
|
|
|
renderCalendar(currentMonth, currentYear);
|
|
});
|
|
|
|
function renderCalendar(month, year) {
|
|
const firstDay = new Date(year, month, 1).getDay();
|
|
const lastDate = new Date(year, month + 1, 0).getDate();
|
|
const lastDatePrevMonth = new Date(year, month, 0).getDate();
|
|
|
|
document.querySelector(".month th[colspan='5']").textContent = `${monthNames[month]} ${year}`;
|
|
|
|
const daysCells = document.querySelectorAll(".days td");
|
|
daysCells.forEach(cell => {
|
|
cell.textContent = '';
|
|
cell.classList.remove("cal-preview-next", "cal-preview-prev", "active", "event");
|
|
});
|
|
|
|
let startDay = (firstDay === 0) ? 6 : firstDay - 1;
|
|
for (let i = startDay - 1; i >= 0; i--) {
|
|
daysCells[i].textContent = lastDatePrevMonth - (startDay - 1 - i);
|
|
daysCells[i].classList.add("cal-preview-prev");
|
|
}
|
|
|
|
let dayCounter = 1;
|
|
for (let i = startDay; i < startDay + lastDate; i++) {
|
|
const currentDay = dayCounter++;
|
|
|
|
daysCells[i].textContent = currentDay;
|
|
|
|
const eventKey = `${year}-${month + 1}-${currentDay}`;
|
|
|
|
if (eventsData[eventKey] && eventsData[eventKey].length > 0) {
|
|
daysCells[i].classList.add("event");
|
|
}
|
|
|
|
daysCells[i].addEventListener('mouseover', function() {
|
|
const hoverDate = new Date(year, month, currentDay);
|
|
updateEventsTable(hoverDate);
|
|
});
|
|
}
|
|
|
|
let nextMonthCounter = 1;
|
|
for (let i = startDay + lastDate; i < daysCells.length; i++) {
|
|
daysCells[i].textContent = nextMonthCounter++;
|
|
daysCells[i].classList.add("cal-preview-next");
|
|
}
|
|
|
|
const today = new Date();
|
|
if (today.getFullYear() === year && today.getMonth() === month) {
|
|
daysCells[startDay + today.getDate() - 1].classList.add("active");
|
|
updateEventsTable(today);
|
|
}
|
|
|
|
daysCells.forEach(cell => {
|
|
cell.addEventListener('mouseleave', function() {
|
|
updateEventsTable(today)
|
|
});
|
|
});
|
|
}
|
|
|
|
|
|
function updateEventsTable(date) {
|
|
const key = `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`;
|
|
const eventsTable = document.querySelector(".events");
|
|
const header = eventsTable.querySelector("th");
|
|
const eventsBody = eventsTable.querySelector("tr:nth-child(2)");
|
|
|
|
header.textContent = `Events on ${date.toDateString()}`;
|
|
|
|
if (eventsData[key]) {
|
|
eventsBody.innerHTML = eventsData[key].map(event => `<tr><td>${event}</td></tr>`).join('');
|
|
} else {
|
|
eventsBody.innerHTML = "<tr><td>Nothing special today.</td></tr>";
|
|
}
|
|
}
|
|
|
|
function changeMonth(delta) {
|
|
currentMonth += delta;
|
|
|
|
if (currentMonth < 0) {
|
|
currentMonth = 11;
|
|
currentYear--;
|
|
} else if (currentMonth > 11) {
|
|
currentMonth = 0;
|
|
currentYear++;
|
|
}
|
|
|
|
renderCalendar(currentMonth, currentYear);
|
|
}
|
|
|
|
document.querySelector(".prev").addEventListener("click", function() {
|
|
changeMonth(-1);
|
|
});
|
|
|
|
document.querySelector(".next").addEventListener("click", function() {
|
|
changeMonth(1);
|
|
});
|
|
|
|
renderCalendar(currentMonth, currentYear);
|
|
});
|