|
| 1 | +import { formatEvent, makeCoverImg, makeCell } from "./events.js"; |
| 2 | + |
| 3 | +const renderEventRow = (evt) => { |
| 4 | + const { name, date, time, relative, lumaUrl, location, coverUrl } = |
| 5 | + formatEvent(evt); |
| 6 | + |
| 7 | + const tr = document.createElement("tr"); |
| 8 | + tr.className = "pf-v6-c-table__tr"; |
| 9 | + tr.setAttribute("role", "row"); |
| 10 | + |
| 11 | + tr.append( |
| 12 | + makeCell( |
| 13 | + "pf-v6-c-table__td pf-v6-u-display-none pf-v6-u-display-table-cell-on-md", |
| 14 | + makeCoverImg(coverUrl, name), |
| 15 | + ), |
| 16 | + ); |
| 17 | + |
| 18 | + const mobileCover = document.createElement("span"); |
| 19 | + mobileCover.className = |
| 20 | + "pf-v6-u-display-inline-block pf-v6-u-display-none-on-md"; |
| 21 | + const mobileCoverImg = makeCoverImg(coverUrl, name); |
| 22 | + if (mobileCoverImg) mobileCover.append(mobileCoverImg); |
| 23 | + |
| 24 | + const mobileName = document.createElement("div"); |
| 25 | + mobileName.className = |
| 26 | + "pf-v6-u-font-weight-bold pf-v6-u-display-block pf-v6-u-display-none-on-md"; |
| 27 | + mobileName.textContent = name; |
| 28 | + |
| 29 | + const relativeSpan = document.createElement("span"); |
| 30 | + relativeSpan.className = "pf-v6-u-font-size-xs"; |
| 31 | + relativeSpan.textContent = relative; |
| 32 | + |
| 33 | + const dateLine = document.createElement("div"); |
| 34 | + dateLine.append(`${date} `, relativeSpan); |
| 35 | + |
| 36 | + const timeLine = document.createElement("small"); |
| 37 | + timeLine.className = "pf-v6-u-text-color-subtle"; |
| 38 | + timeLine.textContent = time; |
| 39 | + |
| 40 | + const textBlock = document.createElement("div"); |
| 41 | + textBlock.append(mobileName, dateLine, timeLine); |
| 42 | + |
| 43 | + const flex = document.createElement("div"); |
| 44 | + flex.className = "pf-v6-l-flex pf-m-gap-md pf-m-align-items-center"; |
| 45 | + flex.append(mobileCover, textBlock); |
| 46 | + |
| 47 | + tr.append(makeCell("pf-v6-c-table__td", flex)); |
| 48 | + |
| 49 | + const nameCell = makeCell( |
| 50 | + "pf-v6-c-table__td pf-v6-u-display-none pf-v6-u-display-table-cell-on-md", |
| 51 | + ); |
| 52 | + nameCell.textContent = name; |
| 53 | + tr.append(nameCell); |
| 54 | + |
| 55 | + const locCell = makeCell("pf-v6-c-table__td"); |
| 56 | + locCell.textContent = location; |
| 57 | + tr.append(locCell); |
| 58 | + |
| 59 | + const rsvpLink = document.createElement("a"); |
| 60 | + rsvpLink.href = lumaUrl; |
| 61 | + rsvpLink.target = "_blank"; |
| 62 | + rsvpLink.rel = "noopener"; |
| 63 | + rsvpLink.className = "pf-v6-c-button pf-m-link pf-m-inline pf-m-small"; |
| 64 | + rsvpLink.append("RSVP", document.createElement("icon-external")); |
| 65 | + tr.append(makeCell("pf-v6-c-table__td", rsvpLink)); |
| 66 | + |
| 67 | + return tr; |
| 68 | +}; |
| 69 | + |
| 70 | +customElements.define( |
| 71 | + "luma-upcoming-events", |
| 72 | + class extends HTMLElement { |
| 73 | + async connectedCallback() { |
| 74 | + const cal = this.getAttribute("calendar"); |
| 75 | + const proxy = this.getAttribute("proxy"); |
| 76 | + try { |
| 77 | + const { entries } = await fetch( |
| 78 | + `${proxy}/events?calendar=${encodeURIComponent(cal)}`, |
| 79 | + ).then((r) => r.json()); |
| 80 | + if (!entries?.length) { |
| 81 | + this.textContent = "No upcoming events right now. Check back soon!"; |
| 82 | + return; |
| 83 | + } |
| 84 | + |
| 85 | + const table = document.createElement("table"); |
| 86 | + table.className = "pf-v6-c-table pf-m-grid-md pf-m-compact"; |
| 87 | + table.setAttribute("role", "grid"); |
| 88 | + table.setAttribute("aria-label", "Upcoming events"); |
| 89 | + |
| 90 | + const thead = document.createElement("thead"); |
| 91 | + thead.className = "pf-v6-c-table__thead"; |
| 92 | + const headRow = document.createElement("tr"); |
| 93 | + headRow.className = "pf-v6-c-table__tr"; |
| 94 | + headRow.setAttribute("role", "row"); |
| 95 | + for (const label of ["", "Date", "Event", "Location", ""]) { |
| 96 | + const th = document.createElement("th"); |
| 97 | + th.className = "pf-v6-c-table__th"; |
| 98 | + th.setAttribute("role", "columnheader"); |
| 99 | + th.setAttribute("scope", "col"); |
| 100 | + th.textContent = label; |
| 101 | + headRow.append(th); |
| 102 | + } |
| 103 | + thead.append(headRow); |
| 104 | + table.append(thead); |
| 105 | + |
| 106 | + const tbody = document.createElement("tbody"); |
| 107 | + tbody.className = "pf-v6-c-table__tbody"; |
| 108 | + tbody.setAttribute("role", "rowgroup"); |
| 109 | + for (const evt of entries) { |
| 110 | + tbody.append(renderEventRow(evt)); |
| 111 | + } |
| 112 | + table.append(tbody); |
| 113 | + |
| 114 | + this.replaceChildren(table); |
| 115 | + } catch { |
| 116 | + this.textContent = "Could not load upcoming events. "; |
| 117 | + const a = document.createElement("a"); |
| 118 | + a.href = "https://luma.com/vanlug"; |
| 119 | + a.target = "_blank"; |
| 120 | + a.rel = "noopener"; |
| 121 | + a.textContent = "View on Luma instead."; |
| 122 | + this.append(a); |
| 123 | + } |
| 124 | + } |
| 125 | + }, |
| 126 | +); |
0 commit comments