{"version":3,"file":"nonApiBookableTimes-060c87cc.js","sources":["../../../../app/frontend/components/b2c/directory/nonApiBookableTimes.js"],"sourcesContent":["import { trackDOMEvent } from '~/components/shared/tracking/segmentAnalytics';\nimport {\n ONE_MINUTE,\n ONE_HOUR,\n ONE_DAY,\n combineDateTime,\n addTime,\n getDatestring,\n formatTime,\n} from '../../shared/dateUtilities';\n\n\n// Get a time 15 minutes in the future\nconst getNextTime = (date) => new Date(date.getTime() + 15 * ONE_MINUTE);\n\nconst getFirstPossibleTime = (startTime = new Date()) => {\n // round to the nearest 15 minute interval\n let firstPossibleTime =\n Math.round(startTime.getTime() / (15 * ONE_MINUTE)) * 15 * ONE_MINUTE;\n if (firstPossibleTime - startTime.getTime() < 30 * ONE_MINUTE) {\n firstPossibleTime = new Date(firstPossibleTime + 15 * ONE_MINUTE);\n }\n return firstPossibleTime;\n};\n\n\ndocument.querySelectorAll('[data-booking-times-controller]').forEach(controllerEl => {\n // Find cards that need fake times and do those\n controllerEl.querySelectorAll('[data-booking-times-fake-card]').forEach(card => {\n const dataset = card.dataset;\n const max_times = parseInt(dataset.numberOfBookingTimes) || 4;\n if (typeof dataset.alwaysOpen !== \"undefined\") {\n const href = dataset.bookableTimesHref;\n const buttonsWrapperEl = card.querySelector(\n \"[data-bookable-buttons-wrapper]\"\n );\n const firstPossibleTime = getFirstPossibleTime();\n const seeMoreText = dataset.seeMoreText || \"See more\";\n const times = [];\n\n times.push(firstPossibleTime);\n\n let nextTime = getNextTime(firstPossibleTime);\n while (times.length < max_times) {\n times.push(nextTime);\n nextTime = getNextTime(nextTime);\n }\n\n const segmentEvent = dataset.bookableEvent;\n const segmentAction = \"click bookable time\";\n\n const createButtonLink = (\n time,\n href\n ) => `${formatTime(\n time\n )}`;\n\n const createSeeMoreLink = (href) =>\n `${seeMoreText}`;\n\n const buttons = [\n ...times.map((time) => createButtonLink(time, href)),\n createSeeMoreLink(href),\n ];\n\n buttonsWrapperEl.innerHTML = buttons.join(\"\");\n const listingProperties = getElementProperties(card);\n buttonsWrapperEl.querySelectorAll(\"a\").forEach((el) => {\n el.addEventListener(\"click\", (event) =>\n trackDOMEvent(event, listingProperties)\n );\n });\n } else {\n const hasHours = (hoursString) => {\n const noHoursStrings = [\"Unknown\", \"Closed\"];\n for (const noString of noHoursStrings) {\n if (hoursString.includes(noString)) {\n return false;\n }\n }\n return true;\n };\n\n const parseHoursString = (hoursString) => {\n const dayName = hoursString.substr(0, 3);\n\n const [startTime, endTime] = hoursString\n .substr(3)\n .split(\"-\")\n .map((s) => s.trim());\n return [dayName, startTime, endTime];\n };\n\n // check the time isn't too close to closing\n const isTimeValid = (time, closeTime) => closeTime - time >= 15 * ONE_MINUTE;\n\n let hoursList;\n let todaysHours;\n\n if (dataset.fakeHours === 'true') {\n hoursList = [\n \"Mon 9:00 am - 5:00 pm\",\n \"Tue 9:00 am - 5:00 pm\",\n \"Wed 9:00 am - 5:00 pm\",\n \"Thu 9:00 am - 5:00 pm\",\n \"Fri 9:00 am - 5:00 pm\",\n \"Sat 9:00 am - 5:00 pm\",\n \"Sun 9:00 am - 5:00 pm\",\n ];\n const todayDayName = new Date().toLocaleDateString(\"en-US\", {\n weekday: \"short\",\n });\n todaysHours = hoursList.find((hoursString) =>\n hoursString.includes(todayDayName)\n );\n } else {\n hoursList = Array.from(\n card.querySelector(\"[data-hours-list]\").children\n ).map((el) => el.innerText);\n\n todaysHours = card.querySelector(\n \".unified_listing-card__current-hours\"\n )?.dataset.todaysHours;\n\n }\n\n const getNextOpenHours = () => {\n const todayDayName = new Date().toLocaleDateString(\"en-US\", {\n weekday: \"short\",\n });\n const todayIndex = hoursList.findIndex((hoursString) =>\n hoursString.includes(todayDayName)\n );\n\n let nextDayIndex = todayIndex + 1;\n let nextDayHours = hoursList[nextDayIndex % hoursList.length];\n\n while (!hasHours(nextDayHours)) {\n nextDayIndex += 1;\n nextDayHours = hoursList[nextDayIndex % hoursList.length];\n }\n\n const [_day, startTime, endTime] = parseHoursString(nextDayHours);\n const nextDayDate = addTime((nextDayIndex - todayIndex) * ONE_DAY);\n const openingTime = combineDateTime(nextDayDate, startTime);\n const closingTime = combineDateTime(nextDayDate, endTime);\n return [openingTime, closingTime];\n };\n\n // Get the first valid opening/closing times\n const getOpeningAndClosing = (currentTime) => {\n if (todaysHours && hasHours(todaysHours)) {\n const [_day, startTime, endTime] = parseHoursString(todaysHours);\n const openingTime = combineDateTime(new Date(), startTime);\n const closingTime = combineDateTime(new Date(), endTime);\n // need to check if we're too close to closing time, if so we need to just move on and get the next days opening time\n if (isTimeValid(getFirstPossibleTime(currentTime), closingTime)) {\n return [openingTime, closingTime];\n }\n }\n return getNextOpenHours();\n };\n\n // Get title text for availability\n const getTitle = (time, times_name = \"times\") => {\n const currentDatestring = getDatestring();\n const firstTimeDatestring = getDatestring(time);\n const tomorrowDatestring = getDatestring(addTime(ONE_DAY));\n\n if (currentDatestring === firstTimeDatestring) {\n return `Available ${times_name} today`;\n }\n if (currentDatestring === tomorrowDatestring) {\n return `Available ${times_name} tomorrow`;\n }\n\n const dayName = time.toLocaleDateString(\"en-US\", { weekday: \"long\" });\n return `Available ${times_name} on ${dayName}`;\n };\n\n const getSegmentActionDay = (time) =>\n getTitle(time).includes(\"today\") ? \"today\" : \"tomorrow\";\n\n const getSegmentAction = (time) => {\n return `click bookable time - ${getSegmentActionDay(time)}`;\n };\n\n const getSegmentProperties = () => {\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\n const setTarget = (href) => {\n if (href === 'javascript:void(0);') {\n return '';\n }\n return '_blank';\n }\n\n const createButtonLink = (time, href, event = \"Directory - CDP Card\") => {\n\n return `${formatTime(time)}`;\n\n }\n const renderNoTimes = () => {\n const timesContainer = card.querySelector(\n \".unified-listing-card__bookable-times\"\n );\n\n const title = \"No available times today or tomorrow\";\n\n const titleEl = `