diff --git a/com/api.py b/com/api.py index 64f375fd..95e7fe92 100644 --- a/com/api.py +++ b/com/api.py @@ -3,6 +3,7 @@ from datetime import timedelta import urllib3 from django.core.cache import cache from django.http import HttpResponse +from django.urls import reverse from django.utils import timezone from ics import Calendar, Event from ninja_extra import ControllerBase, api_controller, route @@ -38,12 +39,14 @@ class CalendarController(ControllerBase): calendar = Calendar() for news_date in NewsDate.objects.filter( news__is_moderated=True, - start_date__lte=timezone.now() + timedelta(days=30), + end_date__gte=timezone.now() + - (timedelta(days=30) * 60), # Roughly get the last 6 months ).prefetch_related("news"): event = Event( name=news_date.news.title, begin=news_date.start_date, end=news_date.end_date, + url=reverse("com:news_detail", kwargs={"news_id": news_date.news.id}), ) calendar.events.add(event) diff --git a/com/static/bundled/com/components/ics-calendar-index.ts b/com/static/bundled/com/components/ics-calendar-index.ts index 227694c0..e3baddc6 100644 --- a/com/static/bundled/com/components/ics-calendar-index.ts +++ b/com/static/bundled/com/components/ics-calendar-index.ts @@ -61,18 +61,24 @@ export class IcsCalendar extends inheritHtmlElement("div") { oldPopup.remove(); } - const makePopupTitle = (event: EventImpl) => { + const makePopupInfo = (info: HTMLElement, iconClass: string) => { const row = document.createElement("div"); const icon = document.createElement("i"); - const infoRow = document.createElement("div"); - const title = document.createElement("h4"); - const time = document.createElement("span"); + row.setAttribute("class", "event-details-row"); - icon.setAttribute( - "class", - "fa-solid fa-calendar-days fa-xl event-detail-row-icon", - ); + icon.setAttribute("class", `event-detail-row-icon fa-xl ${iconClass}`); + + row.appendChild(icon); + row.appendChild(info); + + return row; + }; + + const makePopupTitle = (event: EventImpl) => { + const row = document.createElement("div"); + const title = document.createElement("h4"); + const time = document.createElement("span"); title.setAttribute("class", "event-details-row-content"); title.textContent = event.title; @@ -80,13 +86,33 @@ export class IcsCalendar extends inheritHtmlElement("div") { time.setAttribute("class", "event-details-row-content"); time.textContent = `${this.formatDate(event.start)} - ${this.formatDate(event.end)}`; - infoRow.appendChild(title); - infoRow.appendChild(time); + row.appendChild(title); + row.appendChild(time); + return makePopupInfo( + row, + "fa-solid fa-calendar-days fa-xl event-detail-row-icon", + ); + }; - row.appendChild(icon); - row.appendChild(infoRow); + const makePopupLocation = (event: EventImpl) => { + if (event.extendedProps.location === null) { + return null; + } + const info = document.createElement("div"); + info.innerText = event.extendedProps.location; - return row; + return makePopupInfo(info, "fa-solid fa-location-dot"); + }; + + const makePopupUrl = (event: EventImpl) => { + if (event.url === "") { + return null; + } + const url = document.createElement("a"); + url.href = event.url; + url.textContent = gettext("More info"); + + return makePopupInfo(url, "fa-solid fa-link"); }; // Create new popup @@ -98,6 +124,16 @@ export class IcsCalendar extends inheritHtmlElement("div") { popupContainer.appendChild(makePopupTitle(event.event)); + const location = makePopupLocation(event.event); + if (location !== null) { + popupContainer.appendChild(location); + } + + const url = makePopupUrl(event.event); + if (url !== null) { + popupContainer.appendChild(url); + } + popup.appendChild(popupContainer); // We can't just add the element relative to the one we want to appear under @@ -143,6 +179,8 @@ export class IcsCalendar extends inheritHtmlElement("div") { eventClick: (event) => { // Avoid our popup to be deleted because we clicked outside of it event.jsEvent.stopPropagation(); + // Don't auto-follow events URLs + event.jsEvent.preventDefault(); this.createEventDetailPopup(event); }, }); diff --git a/com/static/com/components/ics-calendar.scss b/com/static/com/components/ics-calendar.scss index 1483cb2b..21aa55d7 100644 --- a/com/static/com/components/ics-calendar.scss +++ b/com/static/com/components/ics-calendar.scss @@ -39,6 +39,7 @@ ics-calendar { border-radius: var(--event-details-border-radius); background-color: var(--event-details-background-color); box-shadow: var(--event-details-box-shadow); + gap: 20px; } .event-detail-row-icon {