{"version":3,"file":"bookableTimes-881c67c0.js","sources":["../../../../app/frontend/components/b2c/directory/bookableTimes.js"],"sourcesContent":["import {getContextProperties, trackDOMEvent, trackSegmentEvent} from '~/components/shared/tracking/segmentAnalytics';\nimport {parseToRelativeTime,} from '../../shared/dateUtilities';\n\n/**\n * Checks if two dates are the same\n * @param date1\n * @param date2\n * @return {boolean}\n */\nfunction isDate(date1, date2) {\n return date1.toDateString() === date2.toDateString();\n}\n\nconst convertTZ = (date, tzString) => {\n return new Date((typeof date === \"string\" ? new Date(date) : date).toLocaleString(\"en-US\", { timeZone: tzString }));\n}\n\n/**\n * Helper function that filters the slots that are on a particular day\n * @param slots {Array[{object}]}\n * @param date {Date}\n * @param card {element}\n * @return {Array[{object}]}\n */\nconst slotsOnDate = (slots, date, card) => {\n const timezone = card.dataset.timezoneName;\n const filtered_slots = [];\n\n for (let i = 0; i < slots.length; i++) {\n let slotDate = new Date(slots[i].appointment_date);\n if (slotDate.getUTCDate() === date.getUTCDate()) {\n slotDate = convertTZ(slotDate, timezone);\n }\n if (isDate(slotDate, date)) {\n filtered_slots.push(slots[i]);\n }\n }\n\n return filtered_slots;\n}\n\n/**\n * Get all the slots for today\n * @param slots {Array[{Object}]}\n * @return {Array[{Object}]}\n */\nconst slotsToday = (slots, card) => {\n const todaysDate = new Date();\n return slotsOnDate(slots, todaysDate, card);\n}\n\n/**\n * Get all the slots for tomorrow\n * @param slots {Array[{Object}]}\n * @param card {element}\n * @return {Array[{Object}]}\n */\nconst slotsTomorrow = (slots, card) => {\n const today = new Date();\n const tomorrow = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1);\n let tomorrowSlots = slotsOnDate(slots, tomorrow, card);\n // we only want the first four slots\n tomorrowSlots = tomorrowSlots.slice(0, 4);\n return tomorrowSlots;\n}\n\nconst getSegmentProperties = (card) => {\n let props = '';\n if (card.dataset.segmentCardRank) {\n props += `data-segment-card-rank=\"${card.dataset.segmentCardRank}\" `;\n }\n if (card.dataset.segmentLocationId) {\n props += `data-segment-location-id=\"${card.dataset.segmentLocationId}\"`;\n }\n return props;\n};\n\nconst buildLink = (card, href, linkText, params, classes, appointment_date) => {\n\n const slotDate = new Date(appointment_date);\n const today = new Date();\n const tomorrow = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1);\n const isToday = today.getDate() == slotDate.getDate();\n const isTomorrow = slotDate.getFullYear() && tomorrow.getMonth() == slotDate.getMonth() && tomorrow.getDate() == slotDate.getDate()\n\n\n let segmentAction = 'Click bookable time'\n\n if (appointment_date == 'view more') {\n segmentAction = 'Click view more'\n } else if (isToday) {\n segmentAction += ' - today'\n } else if (isTomorrow) {\n segmentAction += ' - tomorrow'\n }\n\n return `\n ${linkText}\n `;\n};\n\nconst buildTimeSlotButtons = (card, slots, buttonClasses ) => {\n let buttons = '';\n const directBookingHref = `${card.dataset.directBookingLink}?rel=nofollow`;\n const bookingLinkParams = card.dataset.bookingLinkParams;\n\n slots.forEach((slot) => {\n const time = parseToRelativeTime(slot.appointment_date, card.dataset.timezoneName);\n const params = `&slot=${encodeURIComponent(slot.appointment_date)}&${bookingLinkParams}`;\n buttons += buildLink(card, directBookingHref, time, params, buttonClasses, slot.appointment_date);\n });\n\n return buttons;\n};\n\nconst newBookingTimesSection = (card, date, slots, options) => {\n const buttons = buildTimeSlotButtons(card, slots, options.buttonClasses, options.seeMoreText);\n return `
${message}
`;\n card.dataset.segmentSocialProof = message;\n }\n};\n\nconst updateCardWithAPIData = (data) => {\n const controllerEl = document.querySelector('[data-booking-times-controller]');\n const buttonClasses = controllerEl.dataset.buttonClasses || 'primary-button sm';\n const seeMoreText = controllerEl.dataset.seeMoreText || 'View more';\n\n const locationId = data.location_id;\n let card = controllerEl.querySelector(`.unified-listing-card--bookable.listing-card[data-segment-location-id=\"${locationId}\"]`);\n\n if (!card) {\n card = controllerEl.querySelector(`.unified-listing-card--bookable[data-segment-location-id=\"${locationId}\"]`);\n }\n if (!card) {\n return;\n }\n\n card.dataset.slotsLoaded = 'true';\n const slots = data.slots;\n\n if (slots && slots.length > 0) {\n insertBookingTimesContent(card, slots, { buttonClasses, seeMoreText });\n const todaysSlots = slotsToday(slots, card);\n if (todaysSlots.length < 5 && todaysSlots.length > 0) {\n insertActFastSocialProofAttribute(card, todaysSlots);\n }\n } else {\n insertErrorMessage(card);\n }\n}\n\nconst bookingTimesLoaded = () => {\n const bookableCounts = {\n nearby_bookable_same_day_availability: 0,\n nearby_bookable_next_day_availability: 0,\n }\n document.querySelectorAll('[data-booking-times-controller] [data-booking-times-card] .bookable-times__title').forEach(title => {\n if (title.textContent.includes('TODAY')) {\n bookableCounts.nearby_bookable_same_day_availability += 1;\n } else if (title.textContent.includes('TOMORROW')) {\n bookableCounts.nearby_bookable_next_day_availability += 1;\n }\n });\n\n const properties = getContextProperties('Directory - Slots')\n\n properties.nearby_bookable_same_day_availability = bookableCounts.nearby_bookable_same_day_availability\n properties.nearby_bookable_next_day_availability = bookableCounts.nearby_bookable_next_day_availability\n properties.results_contain.nearby_bookable_same_day_availability = bookableCounts.nearby_bookable_same_day_availability\n properties.results_contain.nearby_bookable_next_day_availability = bookableCounts.nearby_bookable_next_day_availability\n\n trackSegmentEvent('Directory - Slots', properties)\n}\n\nconst insertErrorMessages = (id_hashes) => {\n id_hashes.forEach((id_hash) => {\n const card = document.querySelector(`.unified-listing-card--bookable[data-segment-location-id=\"${id_hash}\"]`);\n insertErrorMessage(card);\n })\n}\n\nconst useHttpForBookingTimes = (locationDataObject) => {\n const locationDataJSON = JSON.stringify(locationDataObject);\n const exceptionURL = `/dir/load-booking-times?location_data=${locationDataJSON}&source=directory&page=${window.location.pathname}`\n const xmlHttp = new XMLHttpRequest();\n xmlHttp.open('GET', exceptionURL, false);\n xmlHttp.addEventListener('load', () => {\n const status = xmlHttp.status;\n if (status === 200) {\n const data = JSON.parse(xmlHttp.response);\n const status = data.status;\n if (status === 'success') {\n const location_data = data.location_data;\n location_data.forEach((data) => {\n updateCardWithAPIData(data);\n })\n bookingTimesLoaded();\n } else {\n insertErrorMessages(id_hashes);\n }\n } else {\n insertErrorMessages(id_hashes);\n }\n });\n\n xmlHttp.send();\n\n}\n\nconst reportError = (id_hashes) => {\n const exceptionURL = `/dir/booking-times-failed?id_hashes=${id_hashes.join()}&source=directory&page=${window.location.pathname}}`\n const xmlHttp = new XMLHttpRequest();\n xmlHttp.open('GET', exceptionURL, false);\n xmlHttp.send();\n}\n\nexport { bookingTimesLoaded, updateCardWithAPIData, useHttpForBookingTimes, reportError }\n\n\n"],"names":["isDate","date1","date2","convertTZ","date","tzString","slotsOnDate","slots","card","timezone","filtered_slots","i","slotDate","slotsToday","slotsTomorrow","today","tomorrow","tomorrowSlots","getSegmentProperties","props","buildLink","href","linkText","params","classes","appointment_date","isToday","isTomorrow","segmentAction","buildTimeSlotButtons","buttonClasses","buttons","directBookingHref","bookingLinkParams","slot","time","parseToRelativeTime","newBookingTimesSection","options","addTrackingToCardBookingLinks","container","el","event","trackDOMEvent","insertBookingTimesContent","todaySlots","bookingTimesContent","insertErrorMessage","buttonContainer","cdp_params","insertActFastSocialProofAttribute","socialProof","isTop20","isDirectory","icon","message","updateCardWithAPIData","data","controllerEl","seeMoreText","locationId","todaysSlots","bookingTimesLoaded","bookableCounts","title","properties","getContextProperties","trackSegmentEvent","insertErrorMessages","id_hashes","id_hash","useHttpForBookingTimes","locationDataObject","exceptionURL","xmlHttp","reportError"],"mappings":"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"}