document.addEventListener("DOMContentLoaded", (event) => { const DateTime = luxon.DateTime; class Webinar { constructor(industry, duration=25, description, parent, date, time, timeZone, parsedDateTime, endDateTime, link) { this.industry = industry; this.duration = duration; this.description = description; this.parent = parent; this.date = date; this.time = time; this.timeZone = timeZone; this.link = link; this.parsedDateTime = parsedDateTime; this.endDateTime = endDateTime; } parseDateTime() { return DateTime.fromFormat(`${this.date} - ${this.time}`, "LLLL d, yyyy - t").setZone(this.timeZone, { keepLocalTime: true }); } getEndDateTime() { if (!this.parsedDateTime) this.parsedDateTime = this.parseDateTime(); // Extracts numbers from "20 Minutes" or "25 Minutes" const mins = parseInt(this.duration.replace(/\D/g, '')) || 25; return this.parsedDateTime.plus({ minutes: mins }); } getISODuration() { const mins = parseInt(this.duration.replace(/\D/g, '')) || 25; return `PT${mins}M`; } createDate() { if (!this.parsedDateTime) this.parsedDateTime = this.parseDateTime(); return this.parsedDateTime.setZone('local').toFormat("LLLL d, yyyy"); } createTime() { if (!this.parsedDateTime) this.parsedDateTime = this.parseDateTime(); return this.parsedDateTime.setZone('local').toFormat("hh:mm a"); } createTimeZone() { if (!this.parsedDateTime) this.parsedDateTime = this.parseDateTime(); return this.parsedDateTime.setZone('local').toFormat("ZZZZ"); } returnMilliseconds(){ if (!this.parsedDateTime) this.parsedDateTime = this.parseDateTime(); return this.parsedDateTime.toMillis(); } } // Webinar class let allFutureWebinars = []; const industries = Array.from(document.querySelectorAll(".upcoming-webinar-industry-container")); industries.forEach((industry) => { const industryID = industry.querySelector(".upcoming-webinar-title").innerText.trim(), duration = industry.querySelector(".upcoming-webinar-duration").innerText.trim(), description = industry.querySelector(".upcoming-webinars-description").innerText.trim(); const scheduledWebinars = Array.from(industry.querySelectorAll(".upcoming-webinar-row")); let webinars = []; scheduledWebinars.forEach((scheduledWebinar) => { const webinar = new Webinar, inputDate = scheduledWebinar.querySelector(".upcoming-webinar-date"), inputTime = scheduledWebinar.querySelector(".upcoming-webinar-time"), inputTimeZone = scheduledWebinar.querySelector(".upcoming-webinar-timezone"), inputIANAZone = scheduledWebinar.querySelector(".upcoming-webinar-iana-zone"), link = scheduledWebinar.querySelector("a"); link.setAttribute("target", "_blank"); webinar.industry = industryID; webinar.duration = duration; webinar.description = description; webinar.parent = scheduledWebinar; webinar.date = inputDate.innerText; webinar.time = inputTime.innerText; webinar.timeZone = inputIANAZone.innerText; webinar.parsedDateTime = webinar.parseDateTime(); webinar.link = link; // UI Localization inputDate.innerText = webinar.createDate(); inputTime.innerText = webinar.createTime(); inputTimeZone.innerText = webinar.createTimeZone(); // SCHEMA LOGIC if (webinar.parsedDateTime.isValid && webinar.parsedDateTime > DateTime.now()){ allFutureWebinars.push(webinar); } webinars.push(webinar); }); // forEach webinar const sortedWebinars = webinars.sort((a, b) => a.returnMilliseconds() - b.returnMilliseconds()); // sorting webinars for(let i = 0; i < sortedWebinars.length; i++){ sortedWebinars[i].parent.style.order = i + 1; sortedWebinars[i].parent.classList.add("localized"); } // for sortedWebinars }); // forEach industry if (allFutureWebinars.length > 0){ const schemaItems = allFutureWebinars.map((webinar, index) => ({ "@type" : "ListItem", "position": index + 1, "item" : { "@type": "Event", "name": webinar.industry, "description": webinar.description, "startDate": webinar.parsedDateTime.toISO(), "endDate": webinar.getEndDateTime().toISO(), "duration": webinar.getISODuration(), "url": webinar.link.getAttribute("href") || window.location.href, "eventAttendanceMode": "https://schema.org/OnlineEventAttendanceMode", "eventStatus": "https://schema.org/EventScheduled", "location": { "@type": "VirtualLocation", "url": webinar.link.getAttribute("href") || window.location.href }, "organizer": { "@type": "Organization", "name": "Keycafe", "url": "https://www.keycafe.com" } } })); // schemaItems map const script = document.createElement('script'); script.type = 'application/ld+json'; script.text = JSON.stringify({ "@context": "https://schema.org", "@type" : "ItemList", "name": "Keycafe Industry Training Webinars", "itemListElement": schemaItems }); document.head.appendChild(script); } // if allFutureWebinars }); // DOMContentLoaded