1import{scrollLock,createMessage}from"helpers";import{MODAL_ICONS}from"event-modal-icons";const MODAL_ID="GlobalQuickModal";let eventDetailsModalSnapshot=null,modalNavigationInitialized=!1;function escapeHtml(value){return String(value).replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""").replaceAll("'","'")}function getModal(){return document.getElementById(MODAL_ID)}function isModalOpen(modal=getModal()){return!!(modal?.open||modal?.hasAttribute("open"))}function setModalContent(className,content){const modal=getModal();if(!modal)return;modal.classList.remove("modal--quick-view","modal--quick-add","modal--event-details","modal--event-calendar"),modal.classList.add(className);const title=modal.querySelector(".modal__title"),body=modal.querySelector(".modal__body");title&&(title.textContent=""),body&&(body.innerHTML=content)}function canRestoreEventDetailsModal(){return eventDetailsModalSnapshot!==null}function snapshotEventDetailsModal(){const body=getModal()?.querySelector(".modal__body");body?.innerHTML&&(eventDetailsModalSnapshot=body.innerHTML)}function clearEventDetailsModalSnapshot(){eventDetailsModalSnapshot=null}export function restoreEventDetailsModal(){if(!canRestoreEventDetailsModal())return!1;const content=eventDetailsModalSnapshot;return clearEventDetailsModalSnapshot(),setModalContent("modal--event-details",content),!0}function ensureModalNavigation(){if(modalNavigationInitialized)return;const modal=getModal();modal&&(modalNavigationInitialized=!0,modal.querySelector(".modal__close-button")?.addEventListener("click",event=>{canRestoreEventDetailsModal()&&(event.preventDefault(),restoreEventDetailsModal())}),modal.addEventListener("click",event=>{event.target===modal&&canRestoreEventDetailsModal()&&(event.preventDefault(),event.stopImmediatePropagation(),restoreEventDetailsModal())},!0),modal.addEventListener("close",()=>{clearEventDetailsModalSnapshot()}))}function openModal(className,content){const modal=getModal();if(!modal)return;const alreadyOpen=isModalOpen(modal);setModalContent(className,content),alreadyOpen||(typeof modal.showModal=="function"?modal.showModal():modal.setAttribute("open","true"),scrollLock.enable())}export function openEventDetailsModal(event){ensureModalNavigation(),clearEventDetailsModalSnapshot(),openModal("modal--event-details",buildEventDetailsHTML(event))}export function openAddToCalendarModal(event,options={}){ensureModalNavigation();const fromEventDetails=options.fromEventDetails??getModal()?.classList.contains("modal--event-details");fromEventDetails?snapshotEventDetailsModal():clearEventDetailsModalSnapshot(),openModal("modal--event-calendar",buildAddToCalendarHTML(event,{showBack:fromEventDetails}))}function findEvent(events,eventId){return events.find(item=>item.id===eventId)}function getEventIdFromTrigger(trigger){return trigger?.dataset.eventId||""}function formatEventCost(cost){if(cost==null||String(cost).trim()==="")return"Free";const costString=String(cost).trim();if(costString.toLowerCase()==="free")return"Free";const numericCost=Number(costString.replace(/[^0-9.-]/g,""));return Number.isNaN(numericCost)?costString:numericCost===0?"Free":`$${numericCost.toFixed(2)}`}function getTagIcon(tag){const normalized=String(tag).trim().toUpperCase();return normalized==="ZOOM"?MODAL_ICONS.video:normalized.includes("DAY")?MODAL_ICONS.calendar:MODAL_ICONS.location}function buildTagsHTML(metaTags){const tags=(metaTags||[]).filter(Boolean);if(!tags.length)return"";const separator='<span class="event-details-modal__tag-separator" aria-hidden="true">\u2022</span>';return tags.map((tag,index)=>`
2 <span class="event-details-modal__tag"> 3 <span class="event-details-modal__tag-icon tag-icon--${tag.toUpperCase().replace(" ","_")}" aria-hidden="true">${getTagIcon(tag)}</span> 4 ${escapeHtml(tag)} 5 </span> 6 ${index<tags.length-1?separator:""} 7 `).join("")}function metaRow(icon,value,options={},heading){if(!value)return"";const{isHtml=!1,eventMoreInfo}=options,valueMarkup=isHtml?value:escapeHtml(value),headingMarkup=heading||"",valueWithLink=eventMoreInfo?valueMarkup.replace(/<\/div>\s*$/,` <a class="event-details-modal__calendar_link" href="${eventMoreInfo}">Learn More</a></div>`):valueMarkup;return` 8 <div class="event-details-modal__meta-row"> 9 <span class="event-details-modal__meta-icon" aria-hidden="true">${icon}</span> 10 <div class="event-details-modal__meta-info"> 11 <span class="event-details-modal__meta-heading">${headingMarkup}</span> 12 <div class="event-details-modal__meta-value">${valueWithLink}</div> 13 </div> 14 </div> 15 `}function shareButtonHTML(event,modifier=""){return` 16 <button type="button" class="event-details-modal__share${modifier?` ${modifier}`:""}" data-event-share data-event-id="${escapeHtml(event.id)}"> 17 <span class="event-details-modal__share-text">Share Event</span> 18 <span class="event-details-modal__share-icon" aria-hidden="true">${MODAL_ICONS.share_icon}</span> 19 </button> 20 `}function calendarButtonHTML(event){return` 21 <button type="button" class="event-details-modal__calendar" data-event-add-calendar data-event-id="${escapeHtml(event.id)}"> 22 <span>Add to calendar</span> 23 <span class="event-details-modal__calendar-icon" aria-hidden="true">${MODAL_ICONS.plus}</span> 24 </button> 25 `}function buildEventDetailsHTML(event){const tags=buildTagsHTML(event.metaTags);return` 26 <div class="event-details-modal"> 27 <div class="event-details-modal__media-column"> 28 <div class="event-details-modal__media">${event.image?`<img class="event-details-modal__image" src="${escapeHtml(event.image)}" alt="${escapeHtml(event.title)}" loading="lazy">`:""}</div> 29 ${shareButtonHTML(event,"event-details-modal__share--media")} 30 </div> 31 <div class="event-details-modal__content"> 32 ${tags?`<div class="event-details-modal__tags">${tags}</div>`:""} 33 <h2 class="event-details-modal__title">${escapeHtml(event.title)}</h2> 34 ${event.brief?`<p class="event-details-modal__brief">${escapeHtml(event.brief)}</p>`:""} 35 <div class="event-details-modal__divider" aria-hidden="true"></div> 36 <div class="event-details-modal__meta"> 37 ${metaRow(MODAL_ICONS.calendar,event.dateLabel,{},"Date")} 38 ${metaRow(MODAL_ICONS.clock,event.timeLabel,{},"Time")} 39 ${metaRow(MODAL_ICONS.location,event.locationAddress,{},"Location")} 40 ${metaRow(MODAL_ICONS.cost,formatEventCost(event.cost),{},"Cost")} 41 ${metaRow(MODAL_ICONS.users,event.whoItsFor,{},"Who Its For")} 42 ${event.about?metaRow(MODAL_ICONS.info,event.about,{isHtml:!0,eventMoreInfo:event.moreInfo},"About the event"):""} 43 </div> 44 <div class="event-details-modal__actions"> 45 ${shareButtonHTML(event,"event-details-modal__share--footer")} 46 ${calendarButtonHTML(event)} 47 </div> 48 </div> 49 </div> 50 `}function buildAddToCalendarHTML(event,options={}){const links=getCalendarLinks(event);return` 51 <div class="event-add-calendar-modal"> 52 ${options.showBack?'<button type="button" class="event-add-calendar-modal__back" data-event-modal-back>← Back to event details</button>':""} 53 <p class="event-add-calendar-modal__intro"> 54 Add this event to your calendar and get notified before it begins 55 </p> 56 <div class="event-add-calendar-modal__options"> 57 <a class="event-add-calendar-modal__option" href="${links.apple}" download="${escapeHtml(event.icsFilename)}"> 58 <span> 59 ${MODAL_ICONS.apple_calendar} 60 </span> 61 <span>Apple Calendar</span></a> 62 <a class="event-add-calendar-modal__option" href="${links.google}" target="_blank" rel="noopener noreferrer">
63 <span> 64 ${MODAL_ICONS.google_calendar} 65 </span> 66 <span>Google Calendar</span></a> 67 <a class="event-add-calendar-modal__option" href="${links.outlook}" target="_blank" rel="noopener noreferrer"> 68 <span> 69 ${MODAL_ICONS.outlook_calendar} 70 </span> 71 <span>Outlook Calendar</span></a> 72 <a class="event-add-calendar-modal__option" href="${links.other}" download="${escapeHtml(event.icsFilename)}"> 73 <span> 74 ${MODAL_ICONS.other_calendar} 75 </span> 76 <span>Other Calendar</span></a> 77 </div> 78 </div> 79 `}function getCalendarLinks(event){const icsContent=buildICS(event),icsBlob=new Blob([icsContent],{type:"text/calendar;charset=utf-8"}),icsUrl=URL.createObjectURL(icsBlob);return{apple:icsUrl,other:icsUrl,google:buildGoogleCalendarUrl(event),outlook:buildOutlookCalendarUrl(event)}}function buildGoogleCalendarUrl(event){return`https://calendar.google.com/calendar/render?${new URLSearchParams({action:"TEMPLATE",text:event.title,dates:`${formatCalendarDate(event.startDateTime)}/${formatCalendarDate(event.endDateTime)}`,details:event.brief||"",location:event.locationAddress||""}).toString()}`}function buildOutlookCalendarUrl(event){return`https://outlook.live.com/calendar/0/deeplink/compose?${new URLSearchParams({subject:event.title,body:event.brief||"",location:event.locationAddress||"",startdt:event.startDateTime,enddt:event.endD
79ateTime,path:"/calendar/action/compose",rru:"addevent"}).toString()}`}function buildICS(event){return`${["BEGIN:VCALENDAR","VERSION:2.0","PRODID:-//Bambi Baby//Event Details//EN","BEGIN:VEVENT",`UID:${escapeICS(event.id)}@bambibaby.com`,`DTSTAMP:${formatCalendarDate(new Date().toISOString())}`,`DTSTART:${formatCalendarDate(event.startDateTime)}`,`DTEND:${formatCalendarDate(event.endDateTime)}`,`SUMMARY:${escapeICS(event.title)}`,`DESCRIPTION:${escapeICS(event.brief||"")}`,`LOCATION:${escapeICS(event.locationAddress||"")}`,"END:VEVENT","END:VCALENDAR"].join(`\r 80`)}\r 81`}function formatCalendarDate(value){const date=new Date(value);return Number.isNaN(date.getTime())?"":date.toISOString().replace(/[-:]/g,"").split(".")[0]+"Z"}function escapeICS(value){return String(value).replace(/\\/g,"\\\\").replace(/\n/g,"\\n").replace(/,/g,"\\,").replace(/;/g,"\\;")}function buildEventShareUrl(event){const url=new URL(`${window.location.origin}${window.location.pathname}`);return url.searchParams.set("event",event.id),url.toString()}function buildEventShareDetails(event){return[[event.dateLabel,event.timeLabel].filter(Boolean).join(" \xB7 "),[event.locationAddress,formatEventCost(event.cost)].filter(Boolean).join(" \xB7 "),event.brief].filter(Boolean).join(` 82`)}export async function shareEvent(event,trigger){const shareUrl=buildEventShareUrl(event),shareDetails=buildEventShareDetails(event);try{if(navigator.share){await navigator.share({title:event.title,text:shareDetails,url:shareUrl});return}}catch(error){if(error?.name==="AbortError")return}try{if(await navigator.clipboard.writeText(shareUrl),createMessage("Event link copied to clipboard!",{type:"success"}),trigger){const originalLabel=trigger.textContent;trigger.textContent="Link copied!",trigger.disabled=!0,window.setTimeout(()=>{trigger.textContent=originalLabel,trigger.disabled=!1},2e3)}}catch{createMessage("Unable to copy link. Please try again.",{type:"error"})}}export function openSharedEventFromUrl(events){const params=new URLSearchParams(window.location.search),eventId=params.get("event");if(!eventId)return;const selectedEvent=findEvent(events,eventId);selectedEvent&&openEventDetailsModal(selectedEvent),params.delete("event");const query=params.toString(),nextUrl=`${window.location.pathname}${query?`?${query}`:""}${window.location.hash}`;window.history.replaceState({},"",nextUrl)}export function bindEventModalActions(root,events,handlers){document.addEventListener("click",async event=>{if(!(root.contains(event.target)||!!event.target.closest(`#${MODAL_ID}`)))return;const isMobileCalendar=window.matchMedia("(max-width: 768px)").matches,detailsTrigger=event.target.closest("[data-event-open-details]"),calendarTrigger=event.target.closest("[data-event-add-calendar]"),shareTrigger=event.target.closest("[data-event-share]"),calendarEvent=!isMobileCalendar&&event.target.closest(".event-details-calendar__event:not([data-enelio-availability='true'])");if(detailsTrigger||calendarEvent){event.preventDefault(),detailsTrigger?.closest(".event-details-calendar__popover")&&(document.querySelectorAll(".event-details-calendar__popover").forEach(popover=>popover.remove()),document.querySelectorAll(".event-details-calendar__day.is-popover-open").forEach(day=>day.classList.remove("is-popover-open")));const eventId=getEventIdFromTrigger(detailsTrigger)||calendarEvent?.dataset.eventKey,selectedEvent=findEvent(events,eventId);selectedEvent&&handlers.openDetails(selectedEvent);return}if(calendarTrigger){event.preventDefault();const selectedEvent=findEvent(events,getEventIdFromTrigger(calendarTrigger));selectedEvent&&handlers.openCalendar(selectedEvent,{fromEventDetails:!!calendarTrigger.closest(".event-details-modal")});return}if(event.target.closest("[data-event-modal-back]")){event.preventDefault(),restoreEventDetailsModal();return}if(shareTrigger){event.preventDefault();const selectedEvent=findEvent(events,getEventIdFromTrigger(shareTrigger));selectedEvent&&await shareEvent(selectedEvent,shareTrigger)}})} 83//# sourceMappingURL=/cdn/shop/t/292/assets/event-details-modals.js.map?v=53297670589154571701784295506
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.