Last active
May 11, 2023 00:41
-
-
Save mrkmiller/11193874120d26d9b3885addc27d03ad to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import {LitElement, html} from 'https://cdn.jsdelivr.net/gh/lit/dist@2/core/lit-core.min.js' | |
| import jsonapiParse from 'https://cdn.jsdelivr.net/npm/jsonapi-parse@2.0.1/+esm' | |
| import dayjs from 'https://cdn.jsdelivr.net/npm/dayjs@1.11.7/+esm' | |
| class SFEventListing extends LitElement { | |
| static properties = { | |
| baseUrl: {type: String}, | |
| url: {type: String}, | |
| imageUrl: {type: String}, | |
| imageAlt: {type: String}, | |
| title: {type: String}, | |
| startDate: {type: String}, | |
| endDate: {type: String}, | |
| location: {type: String}, | |
| } | |
| // Remove the Shadow Dom since we need the style to cascade from the main page. | |
| createRenderRoot() { | |
| return this; | |
| } | |
| render() { | |
| const url = this.baseUrl + this.url | |
| const getThumbnail = () => { | |
| if (this.imageUrl) { | |
| return html` | |
| <div class="vm-teaser__figure"> | |
| <a href="${url}"> | |
| <img src="${this.baseUrl}${this.imageUrl}" alt="${this.imageAlt}" /> | |
| </a> | |
| </div> | |
| `; | |
| } | |
| } | |
| return html` | |
| <div class="vm-listing"> | |
| ${getThumbnail()} | |
| <div class="vm-listing__body"> | |
| <h3 class="vm-listing__title"><a href="${url}">${this.title}</a></h3> | |
| <div class="vm-listing__submitted"> | |
| ${dayjs(this.startDate).format('MMM-D')}-${dayjs(this.endDate).format('D')}, ${dayjs(this.startDate).format('YYYY')} | |
| </div> | |
| <div class="icon icon--location">${this.location}</div> | |
| </div> | |
| </div> | |
| `; | |
| } | |
| } | |
| customElements.define('sf-event-listing', SFEventListing) | |
| class SFEventTeaser extends LitElement { | |
| static properties = { | |
| baseUrl: {type: String}, | |
| url: {type: String}, | |
| imageUrl: {type: String}, | |
| imageAlt: {type: String}, | |
| title: {type: String}, | |
| summary: {type: String}, | |
| startDate: {type: String}, | |
| endDate: {type: String}, | |
| mapUrl: {type: String}, | |
| mapTitle: {type: String}, | |
| location: {type: String}, | |
| } | |
| // Remove the Shadow Dom since we need the style to cascade from the main page. | |
| createRenderRoot() { | |
| return this; | |
| } | |
| render() { | |
| const url = this.baseUrl + this.url | |
| const getThumbnail = () => { | |
| if (this.imageUrl) { | |
| return html` | |
| <div class="vm-teaser__figure category"> | |
| <a href="${url}"> | |
| <img src="${this.baseUrl}${this.imageUrl}" alt="${this.imageAlt}" /> | |
| </a> | |
| </div> | |
| `; | |
| } | |
| } | |
| return html` | |
| <article class="vm-teaser"> | |
| ${getThumbnail()} | |
| <div class="vm-teaser__body"> | |
| <h3 class="vm-teaser__title"><a href="${url}">${this.title}</a></h3> | |
| <div class="vm-teaser__summary">${this.summary}</div> | |
| <ul class="vm-teaser__contact list--pipe text--smaller"> | |
| <li> | |
| <a class="icon icon--link icon--calendar" href="${url}"> | |
| ${dayjs(this.startDate).format('MMM-D')}-${dayjs(this.endDate).format('D')}, ${dayjs(this.startDate).format('YYYY')} <span class="date-separator">@</span> <span class="date-time"> | |
| ${dayjs(this.startDate).format('h:mma')}-${dayjs(this.endDate).format('h:mma')} | |
| </span> | |
| </a> | |
| </li> | |
| <li> | |
| <a class="icon icon--link icon--map" href="${this.mapUrl}">${this.mapTitle}</a> | |
| </li> | |
| <li> | |
| <div class="icon icon--location">${this.location}</div> | |
| </li> | |
| <li> | |
| <a class="icon icon--link icon--view-more" href="${url}">Event Details</a> | |
| </li> | |
| </ul> | |
| </div> | |
| </article> | |
| `; | |
| } | |
| } | |
| customElements.define('sf-event-teaser', SFEventTeaser) | |
| class SFEvents extends LitElement { | |
| static properties = { | |
| events: {}, | |
| baseUrl: {type: String}, | |
| display: {type: String}, | |
| } | |
| constructor() { | |
| super() | |
| this.events = [] | |
| this.baseUrl = window.location.origin | |
| this.display = 'teaser' | |
| } | |
| connectedCallback() { | |
| super.connectedCallback() | |
| this.getEvents() | |
| } | |
| // Remove the Shadow Dom since we need the style to cascade from the main page. | |
| createRenderRoot() { | |
| return this; | |
| } | |
| async getEvents() { | |
| const today = dayjs().add(-1, 'day').toISOString() | |
| const response = await fetch(`${this.baseUrl}/jsonapi/node/sf_event?include=field_sf_m_primary_media,field_sf_m_primary_media.field_media_image&filter[status][value]=1&sort=field_sf_dates.value&filter[datefilter][condition][path]=field_sf_dates.value&filter[datefilter][condition][path]=field_sf_dates.value&filter[datefilter][condition][operator]=%3E&filter[datefilter][condition][value]=${today}`) | |
| const jsonData = await response.json() | |
| this.events = jsonapiParse.parse(jsonData).data | |
| } | |
| render() { | |
| const eventsMarkup = [] | |
| this.events.forEach((event) => { | |
| const url = this.baseUrl + event.path.alias | |
| if (this.display === 'listing') { | |
| eventsMarkup.push(html` | |
| <sf-event-listing | |
| baseurl="${this.baseUrl}" | |
| url="${event.path?.alias}" | |
| imageUrl="${event.field_sf_m_primary_media?.field_media_image.uri.url}" | |
| imageAlt="${event.field_sf_m_primary_media?.field_media_image.meta?.alt}" | |
| title="${event.title}" | |
| startDate="${event.field_sf_dates?.value}" | |
| endDate="${event.field_sf_dates?.end_value}" | |
| location="${event.field_sf_event_location}" | |
| ></sf-event-listing> | |
| `); | |
| } | |
| else { | |
| eventsMarkup.push(html` | |
| <sf-event-teaser | |
| baseurl="${this.baseUrl}" | |
| url="${event.path?.alias}" | |
| imageUrl="${event.field_sf_m_primary_media?.field_media_image.uri.url}" | |
| imageAlt="${event.field_sf_m_primary_media?.field_media_image.meta?.alt}" | |
| title="${event.title}" | |
| summary="${event.body?.value.replace(/(<([^>]+)>)/gi, "").substring(0, 200)}..." | |
| startDate="${event.field_sf_dates?.value}" | |
| endDate="${event.field_sf_dates?.end_value}" | |
| mapUrl="${event.field_sf_event_map_link?.uri}" | |
| mapTitle="${event.field_sf_event_map_link?.title}" | |
| location="${event.field_sf_event_location}" | |
| ></sf-event-teaser> | |
| `); | |
| } | |
| }); | |
| if (eventsMarkup.length === 0) { | |
| eventsMarkup.push(html`Loading Events...`); | |
| } | |
| return html` | |
| <style> | |
| :is(sf-event-teaser, sf-event-listing) { | |
| display: block; | |
| } | |
| sf-event-teaser + sf-event-teaser { | |
| margin-top: 1.5rem; | |
| } | |
| :is(sf-event-teaser, sf-event-listing) .vm-teaser__figure img { | |
| aspect-ratio: 1; | |
| width: 135px; | |
| object-fit: cover; | |
| } | |
| </style> | |
| ${eventsMarkup} | |
| `; | |
| } | |
| } | |
| customElements.define('sf-events', SFEvents) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment