{"version":3,"file":"js/profile-c852132dc24d31f08a36.js","mappings":"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","sources":["webpack://daocloud/./app/javascript/pages/ProProfileBookableEventTypePage/BookingSection.jsx","webpack://daocloud/./app/javascript/pages/ProProfileBookableEventTypePage/ProProfileBookableEventTypePage.jsx","webpack://daocloud/./app/javascript/@core/bookableEventType/bookableEventType.utils.js","webpack://daocloud/./app/javascript/@core/service/service.utils.js","webpack://daocloud/./app/javascript/components/shared/CheckBox.jsx","webpack://daocloud/./app/javascript/pages/ProProfileServicePage/ServiceAddOnModal.jsx","webpack://daocloud/./app/javascript/pages/ProProfileServicePage/ServiceAvailability.jsx","webpack://daocloud/./app/javascript/pages/ProProfileServicePage/BookingSection.jsx","webpack://daocloud/./app/javascript/pages/ProProfileServicePage/ProProfileServicePage.jsx","webpack://daocloud/./app/javascript/packs/profile.js"],"sourcesContent":["import dayjs from \"dayjs\"\nimport React, { useState, useEffect } from \"react\"\n\nconst BookingSection = ({ bookableEvents, practice }) => {\n const [selectedDate, setSelectedDate] = useState(null)\n const [selectedEvent, setSelectedEvent] = useState(null)\n const [eventsByDate, setEventsByDate] = useState({})\n\n // Group events by date\n useEffect(() => {\n if (!bookableEvents?.length) return\n\n const groupedEvents = bookableEvents.reduce((acc, event) => {\n const date = dayjs(event.startsAt).format(\"YYYY-MM-DD\")\n if (!acc[date]) {\n acc[date] = []\n }\n acc[date].push(event)\n return acc\n }, {})\n\n setEventsByDate(groupedEvents)\n\n // Set initial selected date to the first available date\n if (Object.keys(groupedEvents).length > 0 && !selectedDate) {\n setSelectedDate(Object.keys(groupedEvents)[0])\n }\n }, [bookableEvents, selectedDate])\n\n const handleDateSelect = (date) => {\n setSelectedDate(date)\n setSelectedEvent(null)\n }\n\n const handleEventSelect = (event) => {\n setSelectedEvent(event)\n }\n\n return (\n <div className=\"mt-12\">\n {Object.keys(eventsByDate).length > 0 ? (\n <div>\n {/* Date Selection */}\n <h3 className=\"mb-4 text-xl font-semibold\">Select Date</h3>\n <div className=\"mb-8 grid grid-cols-3 gap-3 md:grid-cols-1\">\n {Object.keys(eventsByDate).map((date) => (\n <button\n key={date}\n className={`rounded-lg border p-3 text-center transition-colors ${\n selectedDate === date ? \"border-teal bg-gray-ultralight text-teal\" : \"border-gray hover:border-teal\"\n }`}\n onClick={() => handleDateSelect(date)}>\n {dayjs(date).format(\"ddd, MMM D\")}\n </button>\n ))}\n </div>\n\n {/* Time Selection */}\n {selectedDate && (\n <div>\n <h3 className=\"mb-4 text-xl font-semibold\">Select Time</h3>\n <div className=\"grid grid-cols-3 gap-3 md:grid-cols-1\">\n {eventsByDate[selectedDate].map((event) => {\n const startTime = dayjs(event.startsAt).format(\"h:mm A\")\n const endTime = dayjs(event.endsAt).format(\"h:mm A\")\n const timeDisplay = event.allDay ? \"All day\" : `${startTime} - ${endTime}`\n\n return (\n <button\n key={event.id}\n className={`rounded-lg border p-3 text-center transition-colors ${\n selectedEvent?.id === event.id\n ? \"border-teal bg-gray-ultralight text-teal\"\n : \"border-gray hover:border-teal\"\n }`}\n onClick={() => handleEventSelect(event)}>\n <div>{timeDisplay}</div>\n {event.spotsAvailable > 0 && (\n <div className=\"mt-1 text-xs text-teal\">\n {event.spotsAvailable} {event.spotsAvailable === 1 ? \"spot\" : \"spots\"} left\n </div>\n )}\n </button>\n )\n })}\n </div>\n </div>\n )}\n\n {/* Selected Event Details */}\n {selectedEvent && (\n <div className=\"mt-6\">\n {/* Booking Button */}\n <div className=\"mt-4\">\n <button\n className=\"w-auto rounded-lg bg-teal px-6 py-3 font-semibold text-white transition-colors hover:bg-teal-dark md:w-full\"\n onClick={() => {\n const practiceId = practice.id\n window.location.href = `/checkout?pid=${practiceId}&beid=${selectedEvent.id}`\n }}>\n Go to checkout\n </button>\n </div>\n </div>\n )}\n </div>\n ) : (\n <div className=\"rounded-lg border border-gray-light bg-gray-ultralight p-6 text-center\">\n <p className=\"text-gray\">No available events at this time.</p>\n </div>\n )}\n </div>\n )\n}\n\nexport default BookingSection\n","import React from \"react\"\nimport { twMerge } from \"tailwind-merge\"\n\nimport { bookableEventTypeDisplayAmount } from \"../../@core/bookableEventType/bookableEventType.utils\"\nimport AnimatingBackgroundImage from \"../../components/shared/AnimatingBackgroundImage\"\nimport { ToastProvider, useToast } from \"../../contexts/ToastContext\"\nimport GraphQLProvider from \"../../providers/GraphQLProvider\"\nimport AnimatedSection from \"../ProProfileShared/AnimatedSection\"\nimport BottomCTA from \"../ProProfileShared/BottomCTA\"\nimport ChatWidget from \"../ProProfileShared/ChatWidget\"\nimport Footer from \"../ProProfileShared/Footer\"\nimport Map from \"../ProProfileShared/Map\"\nimport Navigation from \"../ProProfileShared/Navigation\"\nimport ThemeFiveNavigation from \"../ProProfileThemeFive/ThemeFiveNavigation\"\n\nimport BookingSection from \"./BookingSection\"\n\nconst ProProfileBookableEventTypePage = ({ practice, bookableEventType, currentUser, bookableEvents }) => {\n const toast = useToast()\n\n const theme = practice.theme\n const themeName = theme.name\n const url = practice.headerHeroImageUrl.replace(/\\+/g, \"%20\").replace(/\\(/g, \"%28\").replace(/\\)/g, \"%29\")\n\n const bookableEventTypeHasImage = Boolean(\n bookableEventType.filestackPhoto && Object.keys(bookableEventType.filestackPhoto).length > 0\n )\n\n const NavigationComponent = () => {\n if (themeName === \"vitality\") {\n return <ThemeFiveNavigation practice={practice} theme={theme} />\n }\n\n if (themeName === \"serenity\") {\n return <Navigation practice={practice} theme={theme} color={theme.colorTextDark} />\n }\n\n return <Navigation practice={practice} theme={theme} />\n }\n\n return (\n <GraphQLProvider>\n <ToastProvider>\n <main className=\"md:overflow-x-hidden\">\n <div>\n <AnimatingBackgroundImage\n id=\"hero-section\"\n animationDuration={350}\n url={url}\n className={twMerge(\"relative flex min-h-[300px] items-center justify-center text-center\")}\n style={{ color: theme.colorTextLight }}>\n <AnimatedSection className=\"container z-10 mx-auto delay-[350ms] md:p-8\">\n <h1\n className={twMerge(\"text-[56px] leading-[72px] lg:text-4xl lg:leading-[48px]\")}\n style={{\n fontFamily: theme.fontHeading,\n fontWeight: theme.fontHeadingWeight,\n color: theme.colorTextLight\n }}>\n {bookableEventType.name}\n </h1>\n </AnimatedSection>\n <NavigationComponent />\n <div className=\"absolute inset-0 h-full w-full bg-black-real/40\" />\n </AnimatingBackgroundImage>\n </div>\n <div className=\"container mx-auto px-4 py-12\">\n <div className=\"grid grid-cols-1 gap-8 min_md:grid-cols-3\">\n {/* Left column with service details */}\n <div className=\"min_md:col-span-2\">\n <h2 className=\"mb-4 text-3xl font-bold\">{bookableEventType.name}</h2>\n <div className=\"mb-4 flex items-center gap-2\">\n <div className=\"my-1\">\n {bookableEventTypeDisplayAmount(bookableEventType, practice.defaultCurrency)}\n </div>\n </div>\n <div\n className=\"wysiwyg-content mb-4 mt-2 pb-4\"\n dangerouslySetInnerHTML={{ __html: bookableEventType.description }}\n />\n </div>\n\n {/* Right column with service image */}\n <div>\n {bookableEventTypeHasImage && (\n <img\n src={`https://cdn.filestackcontent.com/${bookableEventType.filestackPhoto.original.any}`}\n alt={bookableEventType.name}\n className=\"w-full rounded-lg object-cover\"\n />\n )}\n </div>\n </div>\n\n {/* Booking Section */}\n <BookingSection bookableEventType={bookableEventType} practice={practice} bookableEvents={bookableEvents} />\n </div>\n <BottomCTA practice={practice} theme={theme} />\n <Map practice={practice} />\n <Footer practice={practice} theme={theme} />\n <ChatWidget practice={practice} currentUser={currentUser} toast={toast} />\n </main>\n </ToastProvider>\n </GraphQLProvider>\n )\n}\n\nexport default ProProfileBookableEventTypePage\n","export const bookableEventTypeDisplayAmount = (bookableEventType, currency) => {\n if (bookableEventType.amountCents === 0) {\n return \"Free\"\n }\n\n if (currency === \"USD\") {\n return `$${bookableEventType.amountCents / 100}`\n }\n\n return `${bookableEventType.amountCents / 100} ${currency}`\n}\n","export const centsToDollars = (cents) => (cents === 0 ? \"Free\" : `$${cents / 100}`)\n\nexport const serviceDisplayAmount = (service) => {\n const variationsSortedByPrice = service.variationsWithParent.sort((a, b) => a.amountCents - b.amountCents)\n const prices = `${centsToDollars(variationsSortedByPrice[0].amountCents)}-${centsToDollars(\n variationsSortedByPrice[variationsSortedByPrice.length - 1].amountCents\n )}`\n return service.variationsWithParent.length > 1 ? prices : centsToDollars(service.amountCents)\n}\n\nexport const serviceDisplayTimeLength = (service) => {\n const variationsSortedByLength = service.variationsWithParent.sort((a, b) => a.timeLength - b.timeLength)\n const lengths = `${variationsSortedByLength[0].timeLength}-${\n variationsSortedByLength[variationsSortedByLength.length - 1].timeLength\n }`\n return (service.variationsWithParent.length > 1 ? lengths : service.timeLength) + \" min\"\n}\n","import React from \"react\"\nimport styled from \"styled-components\"\n\nconst Checkbox = styled.div`\n display: inline-flex;\n\n &:hover {\n cursor: pointer;\n }\n\n input[type=\"checkbox\"] {\n clip: rect(0 0 0 0);\n clip-path: inset(50%);\n height: 1px;\n overflow: hidden;\n position: absolute;\n white-space: nowrap;\n width: 1px;\n }\n\n svg {\n display: inline-block;\n height: 24px;\n width: 24px;\n background: #fff;\n border: 2px #ddd solid;\n margin-right: 12px;\n }\n`\n\nexport default function CheckBox({ inputId, name, handleClick, id, checked }) {\n return (\n <Checkbox\n data-test-id={id}\n onClick={() => {\n handleClick(id)\n }}>\n <input type=\"checkbox\" id={inputId} />\n <svg\n className={`${checked ? \"checkbox--active\" : \"\"}`}\n aria-hidden=\"true\"\n viewBox=\"0 0 15 11\"\n style={{\n backgroundColor: checked ? \"#0D9DA4\" : \"#fff\",\n borderColor: checked ? \"#0D9DA4\" : \"#ddd\"\n }}\n fill=\"none\">\n <path d=\"M1 4.5L5 9L14 1\" strokeWidth=\"2\" stroke=\"#fff\" />\n </svg>\n {name}\n </Checkbox>\n )\n}\n","import PropTypes from \"prop-types\"\nimport React, { useState, useEffect } from \"react\"\n\nimport { Button } from \"../../components/shared/Buttons\"\nimport CheckBox from \"../../components/shared/CheckBox\"\nimport ExpandableText from \"../../components/shared/ExpandableText\"\nimport { AnimatedModal } from \"../../components/shared/Modal\"\n\nconst ServiceAddOnModal = ({ visible, onClose, service, addOns, onCheckout }) => {\n const [selectedAddOns, setSelectedAddOns] = useState([])\n const [totalCost, setTotalCost] = useState(0)\n\n useEffect(() => {\n // Calculate initial cost (just the main service)\n calculateTotalCost([])\n }, [service])\n\n const toggleAddOn = (addOn) => {\n const currentSelected = [...selectedAddOns]\n const index = currentSelected.findIndex((item) => item.id === addOn.id)\n\n if (index === -1) {\n // Add the add-on\n currentSelected.push(addOn)\n } else {\n // Remove the add-on\n currentSelected.splice(index, 1)\n }\n\n setSelectedAddOns(currentSelected)\n calculateTotalCost(currentSelected)\n }\n\n const calculateTotalCost = (selected) => {\n const mainServiceCost = service.amountCents / 100\n const addOnsCost = selected.reduce((sum, addOn) => sum + addOn.amountCents / 100, 0)\n setTotalCost(mainServiceCost + addOnsCost)\n }\n\n const handleGoToCheckout = () => {\n // Create array of service IDs (main service first, then selected add-ons)\n const serviceIds = [service.id, ...selectedAddOns.map((addOn) => addOn.id)]\n onCheckout(serviceIds)\n }\n\n return (\n <AnimatedModal visible={visible} hideModal={onClose} header=\"Select optional add-ons\" showFooter={false}>\n <div className=\"flex flex-col gap-4\">\n {addOns.map((addOn) => (\n <div key={addOn.id} className=\"flex flex-col items-start border-b border-gray-light pb-4\">\n <CheckBox\n id={addOn.id}\n name={`${addOn.name} - Add $${(addOn.amountCents / 100).toFixed(2)}`}\n handleClick={() => toggleAddOn(addOn)}\n checked={selectedAddOns.some((item) => item.id === addOn.id)}\n className=\"mr-4\"\n />\n <ExpandableText text={addOn.description} maxLength={60} className=\"ml-9 text-sm text-gray-dark\" allowHtml />\n </div>\n ))}\n\n <div className=\"mt-6\">\n <div className=\"flex justify-between text-gray-dark\">\n <span>{service.name}</span>\n <span>${(service.amountCents / 100).toFixed(2)}</span>\n </div>\n\n {selectedAddOns.map((addOn) => (\n <div key={addOn.id} className=\"flex justify-between text-gray-dark\">\n <span>{addOn.name}</span>\n <span>${(addOn.amountCents / 100).toFixed(2)}</span>\n </div>\n ))}\n\n <div className=\"my-2 flex justify-between pt-2 font-semibold\">\n <span>Total Cost</span>\n <span>${totalCost.toFixed(2)}</span>\n </div>\n </div>\n\n <div className=\"mt-6\">\n <Button type=\"primary\" className=\"w-full\" size=\"large\" onClick={handleGoToCheckout}>\n Go to checkout\n </Button>\n </div>\n </div>\n </AnimatedModal>\n )\n}\n\nServiceAddOnModal.propTypes = {\n visible: PropTypes.bool.isRequired,\n onClose: PropTypes.func.isRequired,\n service: PropTypes.object.isRequired,\n addOns: PropTypes.array.isRequired,\n onCheckout: PropTypes.func.isRequired\n}\n\nexport default ServiceAddOnModal\n","import dayjs from \"dayjs\"\nimport advancedFormat from \"dayjs/plugin/advancedFormat\"\nimport timezone from \"dayjs/plugin/timezone\"\nimport utc from \"dayjs/plugin/utc\"\nimport React, { useState, useEffect } from \"react\"\nimport Skeleton from \"react-loading-skeleton\"\nimport \"react-loading-skeleton/dist/skeleton.css\"\n\nimport { Button } from \"../../components/shared/Buttons\"\nimport { Banner } from \"../../components/shared/Layout\"\nimport { Link } from \"../../components/shared/Links\"\nimport { urqlClient } from \"../../utils/utils\"\n\nimport ServiceAddOnModal from \"./ServiceAddOnModal\"\n\ndayjs.extend(utc)\ndayjs.extend(timezone)\ndayjs.extend(advancedFormat)\n\nconst AVAILABILITY_QUERY = `\n query Availability($serviceId: ID!, $locationId: ID!, $page: Int) {\n bookingAvailability(serviceId: $serviceId, locationId: $locationId, page: $page) {\n availableSlots {\n date\n datetimes\n }\n lastDateInPage\n }\n }\n`\n\nconst DEFAULT_TIMEZONE = Intl.DateTimeFormat().resolvedOptions().timeZone\nconst DEFAULT_TIMEZONE_ABBR = new Date().toLocaleTimeString(\"en-us\", { timeZoneName: \"short\" }).split(\" \")[2]\n\nconst DayAvailabilitySkeleton = () => (\n <div className=\"mb-8\">\n <Skeleton className=\"mb-4 h-6 w-48\" />\n <div className=\"grid grid-cols-3 gap-3 min_sm:grid-cols-5\">\n {Array(10)\n .fill()\n .map((_, i) => (\n <Skeleton key={i} className=\"h-12 w-full rounded-md\" />\n ))}\n </div>\n </div>\n)\n\nconst ServiceAvailability = ({ service, selectedLocation, selectedVariation, practice }) => {\n const [data, setData] = useState(null)\n const [fetching, setFetching] = useState(true)\n const [page, setPage] = useState(0)\n const [daysShown, setDaysShown] = useState(10)\n const [selectedSlot, setSelectedSlot] = useState(null)\n const [error, setError] = useState(null)\n const [retry, setRetry] = useState(0)\n const [showAddOnModal, setShowAddOnModal] = useState(false)\n\n const timeZone = !selectedLocation\n ? DEFAULT_TIMEZONE\n : selectedLocation.kind === \"virtual\"\n ? Intl.DateTimeFormat().resolvedOptions().timeZone\n : selectedLocation.formattedTimeZone\n\n const timeZoneAbbr = !selectedLocation\n ? DEFAULT_TIMEZONE_ABBR\n : selectedLocation.kind === \"virtual\"\n ? new Date().toLocaleTimeString(\"en-us\", { timeZoneName: \"short\" }).split(\" \")[2]\n : selectedLocation.timeZoneAbbr\n\n // Reset the availability when the location or variation changes\n useEffect(() => {\n setData(null)\n setPage(0)\n setDaysShown(10)\n setSelectedSlot(null)\n }, [selectedLocation?.id, selectedVariation?.id])\n\n // Fetch availability when the location or variation changes\n useEffect(() => {\n const fetchAvailability = async () => {\n setFetching(true)\n setError(null)\n try {\n const response = await urqlClient\n .query(\n AVAILABILITY_QUERY,\n {\n serviceId: selectedVariation?.id || service.id,\n locationId: selectedLocation.id,\n page\n },\n {\n requestPolicy: \"network-only\"\n }\n )\n .toPromise()\n\n if (response.error) {\n throw new Error(response.error.message || \"Failed to fetch availability\")\n }\n\n const newSlots = response.data.bookingAvailability.availableSlots\n setData((prevData) => ({\n bookingAvailability: {\n availableSlots:\n page === 0 ? newSlots : [...(prevData?.bookingAvailability?.availableSlots || []), ...newSlots],\n lastDateInPage: response.data.bookingAvailability.lastDateInPage\n }\n }))\n } catch (err) {\n console.error(\"Error fetching availability:\", err)\n setError(err.message || \"Failed to load availability. Please try again later.\")\n }\n setFetching(false)\n }\n\n if (selectedLocation) {\n fetchAvailability()\n }\n }, [selectedLocation?.id, selectedVariation?.id, service.id, page, retry])\n\n const availableSlots = data?.bookingAvailability?.availableSlots?.filter((day) => day.datetimes.length > 0) || []\n const lastDateInPage = data?.bookingAvailability?.lastDateInPage\n\n // Handler to set the selected slot and navigate to checkout\n const handleSlotClick = (time) => {\n setSelectedSlot(time)\n\n // Check if service has add-ons\n if (service.addOns && service.addOns.length > 0) {\n // Show add-on selection modal\n setShowAddOnModal(true)\n } else {\n // No add-ons, redirect to checkout directly\n redirectToCheckout(time, [selectedVariation ? selectedVariation.id : service.id])\n }\n }\n\n // Function to handle checkout redirection\n const redirectToCheckout = (time, serviceIds) => {\n const serviceParam = serviceIds.join(\",\")\n const checkoutUrl = `/checkout?pid=${practice.id}&sid=${serviceParam}&lid=${\n selectedLocation.id\n }&st=${encodeURIComponent(time)}`\n window.location.href = checkoutUrl\n }\n\n // Handler for when the user completes add-on selection and proceeds to checkout\n const handleAddOnCheckout = (serviceIds) => {\n redirectToCheckout(selectedSlot, serviceIds)\n }\n\n return (\n <>\n <h3 className=\"mb-6 text-xl font-semibold\">Select a Date and Time ({timeZoneAbbr})</h3>\n\n {error && (\n <Banner type=\"error\">\n <p className=\"flex items-center\">{error}</p>\n <Link\n onClick={() => {\n setError(null)\n setPage(0)\n setData(null)\n setFetching(true)\n setRetry((prev) => prev + 1)\n }}>\n Try again\n </Link>\n </Banner>\n )}\n\n {/* Add-on selection modal */}\n <ServiceAddOnModal\n visible={showAddOnModal}\n onClose={() => setShowAddOnModal(false)}\n service={selectedVariation || service}\n addOns={service.addOns || []}\n onCheckout={handleAddOnCheckout}\n />\n\n {fetching && !data ? (\n <>\n {Array(5)\n .fill()\n .map((_, i) => (\n <DayAvailabilitySkeleton key={i} />\n ))}\n </>\n ) : (\n <div className=\"mb-8\">\n {availableSlots.slice(0, daysShown).map((day) => {\n const dayDate = dayjs(day.date)\n const isToday = dayjs().isSame(dayDate, \"day\")\n const isTomorrow = dayjs().add(1, \"day\").isSame(dayDate, \"day\")\n\n return (\n <div key={day.date} className=\"mb-8\">\n <h4 className=\"mb-4 text-lg font-medium\">\n {isToday\n ? `Today, ${dayDate.tz(timeZone).format(\"MMMM D\")}`\n : isTomorrow\n ? `Tomorrow, ${dayDate.tz(timeZone).format(\"MMMM D\")}`\n : dayDate.tz(timeZone).format(\"dddd, MMMM D\")}\n </h4>\n <div className=\"grid grid-cols-3 gap-3 min_sm:grid-cols-5\">\n {day.datetimes.map((time) => (\n <Button\n key={time}\n type=\"secondary\"\n size=\"large\"\n onClick={() => handleSlotClick(time)}\n className={`w-full rounded-md border border-teal text-center text-lg transition-colors\n ${selectedSlot === time ? \"bg-teal text-white\" : \"text-teal hover:bg-teal/50\"}`}>\n {dayjs(time).tz(timeZone).format(\"h:mma\")}\n </Button>\n ))}\n </div>\n </div>\n )\n })}\n\n {fetching ? (\n <div className=\"flex justify-center\">\n <div className=\"h-8 w-8 animate-spin rounded-full border-4 border-teal border-t-transparent\" />\n </div>\n ) : (\n <>\n {lastDateInPage && availableSlots.length === 0 && (\n <p className=\"text-gray-dark\">No available slots through {dayjs(lastDateInPage).format(\"MMMM D\")}</p>\n )}\n <button\n className=\"mt-4 text-teal underline\"\n onClick={() => {\n setDaysShown(daysShown + 10)\n if (daysShown >= availableSlots.length) {\n setPage(page + 1)\n }\n }}>\n Show more times\n </button>\n </>\n )}\n </div>\n )}\n </>\n )\n}\n\nexport default ServiceAvailability\n","import React, { useState, useEffect } from \"react\"\n\nimport { centsToDollars } from \"../../@core/service/service.utils\"\nimport { RadioWithLabel } from \"../../components/shared/RadioButtons\"\n\nimport ServiceAvailability from \"./ServiceAvailability\"\n\nconst BookingSection = ({ service, practice }) => {\n const [selectedLocation, setSelectedLocation] = useState(service.locations?.[0] || null)\n const [selectedVariation, setSelectedVariation] = useState(service.variationsWithParent?.[0] || null)\n const [showAvailability, setShowAvailability] = useState(false)\n\n useEffect(() => {\n if (selectedLocation && (!service.variationsWithParent?.length || selectedVariation)) {\n setShowAvailability(true)\n } else {\n setShowAvailability(false)\n }\n }, [selectedLocation, selectedVariation, service.variationsWithParent])\n\n return (\n <div className=\"mt-12\">\n {/* Location Selection */}\n <div className=\"mb-8\">\n <h3 className=\"mb-4 text-xl font-semibold\">Select Location</h3>\n <div className=\"flex flex-col gap-4\">\n {service.locations?.map((location) => (\n <RadioWithLabel\n key={location.id}\n name=\"location\"\n label={location.name}\n checked={selectedLocation?.id === location.id}\n onChange={() => setSelectedLocation(location)}\n />\n ))}\n </div>\n </div>\n\n {/* Variation Selection - Only show if variations exist */}\n {service.variationsWithParent?.length > 0 && (\n <div className=\"mb-8\">\n <h3 className=\"mb-4 text-xl font-semibold\">Select Duration</h3>\n <div className=\"flex flex-col gap-4\">\n {service.variationsWithParent.map((variation) => (\n <RadioWithLabel\n key={variation.id}\n name=\"variation\"\n label={`${variation.timeLength} minutes - ${centsToDollars(variation.amountCents)}`}\n checked={selectedVariation?.id === variation.id}\n onChange={() => setSelectedVariation(variation)}\n />\n ))}\n </div>\n </div>\n )}\n\n {/* Availability Section */}\n {showAvailability && (\n <ServiceAvailability\n service={service}\n selectedLocation={selectedLocation}\n selectedVariation={selectedVariation}\n practice={practice}\n />\n )}\n </div>\n )\n}\n\nexport default BookingSection\n","import React from \"react\"\nimport { twMerge } from \"tailwind-merge\"\n\nimport { serviceDisplayAmount, serviceDisplayTimeLength } from \"../../@core/service/service.utils\"\nimport AnimatingBackgroundImage from \"../../components/shared/AnimatingBackgroundImage\"\nimport { CurrentUserProvider, useCurrentUser } from \"../../contexts/CurrentUserContext\"\nimport { ToastProvider, useToast } from \"../../contexts/ToastContext\"\nimport GraphQLProvider from \"../../providers/GraphQLProvider\"\nimport AnimatedSection from \"../ProProfileShared/AnimatedSection\"\nimport BottomCTA from \"../ProProfileShared/BottomCTA\"\nimport ChatWidget from \"../ProProfileShared/ChatWidget\"\nimport Footer from \"../ProProfileShared/Footer\"\nimport Map from \"../ProProfileShared/Map\"\nimport Navigation from \"../ProProfileShared/Navigation\"\nimport ThemeFiveNavigation from \"../ProProfileThemeFive/ThemeFiveNavigation\"\nimport { DEFAULT_HIGHLIGHT_CLASSES } from \"../WebsiteBuilder/WebsiteBuilderPage\"\n\nimport BookingSection from \"./BookingSection\"\n\nconst ProProfileServicePage = ({ practice, highlight, service, styles, viewingInBuilder }) => {\n const theme = practice.theme\n const themeName = theme.name\n const currentUser = useCurrentUser()\n const toast = useToast()\n const url = practice.headerHeroImageUrl.replace(/\\+/g, \"%20\").replace(/\\(/g, \"%28\").replace(/\\)/g, \"%29\")\n\n const serviceHasImage = Boolean(service.filestackPhoto && Object.keys(service.filestackPhoto).length > 0)\n\n const NavigationComponent = () => {\n if (themeName === \"vitality\") {\n return <ThemeFiveNavigation practice={practice} theme={theme} viewingInBuilder={viewingInBuilder} />\n }\n\n if (themeName === \"serenity\") {\n return (\n <Navigation practice={practice} theme={theme} color={theme.colorTextDark} viewingInBuilder={viewingInBuilder} />\n )\n }\n\n return <Navigation practice={practice} theme={theme} viewingInBuilder={viewingInBuilder} />\n }\n\n return (\n <CurrentUserProvider>\n <GraphQLProvider>\n <ToastProvider>\n <main style={styles} className=\"md:overflow-x-hidden\">\n <div>\n <AnimatingBackgroundImage\n id=\"hero-section\"\n animationDuration={350}\n url={url}\n className={twMerge(\n \"relative flex min-h-[300px] items-center justify-center text-center\",\n highlight === \"Hero image\" ? DEFAULT_HIGHLIGHT_CLASSES : \"\"\n )}\n style={{ color: theme.colorTextLight }}>\n <AnimatedSection className=\"container z-10 mx-auto delay-[350ms] md:p-8\">\n <h1\n className={twMerge(\n \"text-[56px] leading-[72px] lg:text-4xl lg:leading-[48px]\",\n highlight === \"websiteHeadline\" ? DEFAULT_HIGHLIGHT_CLASSES : \"\"\n )}\n style={{\n fontFamily: theme.fontHeading,\n fontWeight: theme.fontHeadingWeight,\n color: theme.colorTextLight\n }}>\n {service.name}\n </h1>\n </AnimatedSection>\n <NavigationComponent />\n <div className=\"absolute inset-0 h-full w-full bg-black-real/40\" />\n </AnimatingBackgroundImage>\n </div>\n <div className=\"container mx-auto px-4 py-12\">\n <div className=\"grid grid-cols-1 gap-8 min_md:grid-cols-3\">\n {/* Left column with service details */}\n <div className=\"min_md:col-span-2\">\n <h2 className=\"mb-4 text-3xl font-bold\">{service.name}</h2>\n <div className=\"mb-4 flex items-center gap-2\">\n <div className=\"my-1\">\n {serviceDisplayAmount(service)}{\" \"}\n {practice.defaultCurrency !== \"USD\" && service.amountCents > 0 ? practice.defaultCurrency : \"\"}{\" \"}\n • {serviceDisplayTimeLength(service)}\n </div>\n </div>\n <div\n className=\"wysiwyg-content mb-4 mt-2 pb-4\"\n dangerouslySetInnerHTML={{ __html: service.description }}\n />\n </div>\n\n {/* Right column with service image */}\n <div>\n {serviceHasImage && (\n <img\n src={`https://cdn.filestackcontent.com/${service.filestackPhoto.original.any}`}\n alt={service.name}\n className=\"w-full rounded-lg object-cover\"\n />\n )}\n </div>\n </div>\n\n {/* Booking Section */}\n <BookingSection service={service} practice={practice} />\n </div>\n <BottomCTA practice={practice} theme={theme} highlight={highlight} viewingInBuilder={viewingInBuilder} />\n <Map practice={practice} />\n <Footer practice={practice} theme={theme} viewingInBuilder={viewingInBuilder} />\n <ChatWidget practice={practice} currentUser={currentUser} toast={toast} />\n </main>\n </ToastProvider>\n </GraphQLProvider>\n </CurrentUserProvider>\n )\n}\n\nexport default ProProfileServicePage\n","require(\"@rails/ujs\").start()\nrequire(\"../src/application/toggle-controls\")\n\nimport \"../stylesheets/home-search.css.sass\"\nimport ReactOnRails from \"react-on-rails\"\n\nimport MobileMenu from \"../components/header/MobileMenu\"\nimport ProProfile from \"../pages/ProProfile\"\nimport ProProfileBookableEventTypePage from \"../pages/ProProfileBookableEventTypePage/ProProfileBookableEventTypePage\"\nimport ProProfileServicePage from \"../pages/ProProfileServicePage/ProProfileServicePage\"\nimport ProProfileThemeFive from \"../pages/ProProfileThemeFive/ProProfileThemeFive\"\nimport ProProfileThemeFour from \"../pages/ProProfileThemeFour/ProProfileThemeFour\"\nimport ProProfileThemeOne from \"../pages/ProProfileThemeOne/ProProfileThemeOne\"\nimport ProProfileThemeThree from \"../pages/ProProfileThemeThree/ProProfileThemeThree\"\nimport ProProfileThemeTwo from \"../pages/ProProfileThemeTwo/ProProfileThemeTwo\"\nimport ProProfileV2 from \"../pages/ProProfileV2\"\n// eslint-disable-next-line no-unused-vars\nimport dayJsPlugins from \"../utils/dayJsPlugins\"\n\nconst components = {\n ProProfile,\n ProProfileV2,\n ProProfileThemeOne,\n ProProfileThemeTwo,\n ProProfileThemeThree,\n ProProfileThemeFour,\n ProProfileThemeFive,\n MobileMenu,\n ProProfileServicePage,\n ProProfileBookableEventTypePage\n}\n\nReactOnRails.register(components)\n"],"names":["BookingSection","bookableEvents","practice","selectedDate","setSelectedDate","useState","selectedEvent","setSelectedEvent","eventsByDate","setEventsByDate","useEffect","length","groupedEvents","reduce","acc","event","date","dayjs","startsAt","format","push","Object","keys","React","className","map","key","onClick","handleDateSelect","startTime","endTime","endsAt","timeDisplay","allDay","id","handleEventSelect","spotsAvailable","practiceId","window","location","href","ProProfileBookableEventTypePage","bookableEventType","currentUser","toast","useToast","theme","themeName","name","url","headerHeroImageUrl","replace","bookableEventTypeHasImage","Boolean","filestackPhoto","NavigationComponent","ThemeFiveNavigation","Navigation","color","colorTextDark","GraphQLProvider","ToastProvider","AnimatingBackgroundImage","animationDuration","twMerge","style","colorTextLight","AnimatedSection","fontFamily","fontHeading","fontWeight","fontHeadingWeight","bookableEventTypeDisplayAmount","currency","amountCents","defaultCurrency","dangerouslySetInnerHTML","__html","description","src","original","any","alt","BottomCTA","Map","Footer","ChatWidget","centsToDollars","cents","Checkbox","styled","div","CheckBox","inputId","handleClick","checked","type","viewBox","backgroundColor","borderColor","fill","d","strokeWidth","stroke","ServiceAddOnModal","visible","onClose","service","addOns","onCheckout","selectedAddOns","setSelectedAddOns","totalCost","setTotalCost","calculateTotalCost","selected","mainServiceCost","addOnsCost","sum","addOn","AnimatedModal","hideModal","header","showFooter","toFixed","currentSelected","index","findIndex","item","splice","toggleAddOn","some","ExpandableText","text","maxLength","allowHtml","Button","size","handleGoToCheckout","serviceIds","utc","timezone","advancedFormat","DEFAULT_TIMEZONE","Intl","DateTimeFormat","resolvedOptions","timeZone","DEFAULT_TIMEZONE_ABBR","Date","toLocaleTimeString","timeZoneName","split","DayAvailabilitySkeleton","Skeleton","Array","_","i","ServiceAvailability","selectedLocation","selectedVariation","data","setData","fetching","setFetching","page","setPage","daysShown","setDaysShown","selectedSlot","setSelectedSlot","error","setError","retry","setRetry","showAddOnModal","setShowAddOnModal","kind","formattedTimeZone","timeZoneAbbr","async","response","urqlClient","query","serviceId","locationId","requestPolicy","toPromise","Error","message","newSlots","bookingAvailability","availableSlots","prevData","lastDateInPage","err","console","fetchAvailability","filter","day","datetimes","redirectToCheckout","time","serviceParam","join","checkoutUrl","encodeURIComponent","Banner","Link","prev","slice","dayDate","isToday","isSame","isTomorrow","add","tz","handleSlotClick","setSelectedLocation","locations","setSelectedVariation","variationsWithParent","showAvailability","setShowAvailability","RadioWithLabel","label","onChange","variation","timeLength","ProProfileServicePage","highlight","styles","viewingInBuilder","useCurrentUser","serviceHasImage","CurrentUserProvider","DEFAULT_HIGHLIGHT_CLASSES","variationsSortedByPrice","sort","a","b","prices","serviceDisplayAmount","variationsSortedByLength","lengths","serviceDisplayTimeLength","require","components","ProProfile","ProProfileV2","ProProfileThemeOne","ProProfileThemeTwo","ProProfileThemeThree","ProProfileThemeFour","ProProfileThemeFive","MobileMenu","ReactOnRails"],"sourceRoot":""}