{"version":3,"file":"static/js/7.447d6fb2.chunk.js","mappings":"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","sources":["components/BookingFlow/modules/DateTimeSelect/AppointmentCalendar.tsx","components/BookingFlow/modules/TimeTableSelect/Event.tsx","components/BookingFlow/modules/TimeTableSelect/fullcalendarFunctions.tsx","components/Image/Image.tsx","components/ServiceDescription/ServiceDescription.tsx"],"sourcesContent":["import React from 'react';\r\nimport {\r\n    IEventRenderInfo,\r\n    IEventTimes,\r\n    handleEventClassNames,\r\n} from 'src/components/BookingFlow/modules/TimeTableSelect/fullcalendarFunctions';\r\nimport { useState, useCallback, lazy, Suspense } from 'react';\r\nimport { setTimeOnDate } from 'src/services/dateTime';\r\nimport { IDateInterval, ICalendar } from 'src/entities/calendar';\r\nimport { EventInput, EventSourceFunc } from '@fullcalendar/core';\r\nimport setMinutes from 'date-fns/fp/setMinutes';\r\nimport setHours from 'date-fns/fp/setHours';\r\nimport addMinutes from 'date-fns/fp/addMinutes';\r\nimport getMinutes from 'date-fns/fp/getMinutes';\r\nimport subDays from 'date-fns/subDays';\r\nimport { getCalendarFreeIntervals } from 'src/services/api/calendar';\r\nimport { IService } from 'src/entities/service';\r\nimport { useIntl, IntlShape } from 'react-intl';\r\nimport getDay from 'date-fns/getDay';\r\nimport Placeholder from 'src/components/Placeholder/Placeholder';\r\nimport { ReadonlyInfo } from 'src/components/ReadonlyInfo/ReadonlyInfo';\r\nimport PersonCount from './PersonCount/PersonCount';\r\nimport { IPendingReservation } from 'src/entities/reservation';\r\n\r\nconst Timetable = lazy(() => import(/* webpackChunkName: \"Timetable\" */ './Timetable'));\r\n\r\n/* assuming 1rem = 11px */\r\nconst mobileBreakPoints: Record<number, string> = {\r\n    6: '91rem',\r\n    4: '82rem',\r\n    3: '91rem',\r\n    2: '56rem',\r\n    1: '56rem',\r\n};\r\n\r\nconst getMobileBreakPoint = (cellLength: number) => {\r\n    const rootFontSizeScale = 11 / 16;\r\n    return mobileBreakPoints[getCellCount(cellLength)].replace(/\\d+/g, (value) =>\r\n        String(+value * rootFontSizeScale)\r\n    );\r\n};\r\n\r\nexport const getSlotLength = (resolutionInMinutes: number) => {\r\n    if (resolutionInMinutes < 10) {\r\n        return 30;\r\n    }\r\n\r\n    if (resolutionInMinutes > 30) {\r\n        return resolutionInMinutes;\r\n    }\r\n\r\n    return 60;\r\n};\r\n\r\nconst getCellCount = (cellLength: number) => {\r\n    const slotLength = getSlotLength(cellLength);\r\n    return slotLength / cellLength;\r\n};\r\n\r\ntype IGroupedTimes = Record<string, Date[]>;\r\n\r\nconst toList = (map: IGroupedTimes) =>\r\n    Object.entries(map).map<[Date, Date[]]>(([key, value]) => [new Date(key), value]);\r\n\r\nconst toEventTimes = (dateInterval: IDateInterval): IEventTimes => {\r\n    const { Date, Intervals } = dateInterval;\r\n    return { [Date]: Intervals };\r\n};\r\n\r\nconst indexTime = (date: Date, cellSize: number, slotSize: 60 | 30) => {\r\n    const minutes = getMinutes(date) % slotSize;\r\n    const index = Math.floor(minutes / cellSize);\r\n    return index;\r\n};\r\n\r\nconst floorToHour = (dateTime: Date) => setMinutes(0, dateTime);\r\nconst floorToHalfHour = (dateTime: Date) =>\r\n    getMinutes(dateTime) < 30 ? setMinutes(0, dateTime) : setMinutes(30, dateTime);\r\nconst addTime = (time: Date, key: string, map: IGroupedTimes) => {\r\n    if (!(key in map)) {\r\n        map[key] = [];\r\n    }\r\n    map[key].push(time);\r\n};\r\n\r\nconst groupBy = (dates: string[], step: number): Array<[Date, Date[]]> => {\r\n    if (step > 30) {\r\n        return dates.map((ds) => new Date(ds)).map((d) => [d, [d]]);\r\n    }\r\n\r\n    const grouped = dates\r\n        .map((s) => new Date(s))\r\n        .reduce<IGroupedTimes>((map, dateTime) => {\r\n            const key = (\r\n                step < 10 ? floorToHalfHour(dateTime) : floorToHour(dateTime)\r\n            ).toISOString();\r\n\r\n            addTime(dateTime, key, map);\r\n\r\n            return map;\r\n        }, {});\r\n\r\n    return toList(grouped);\r\n};\r\n\r\nconst mapResponse = (dateIntervals: IDateInterval[], step: number): EventInput[] => {\r\n    const slotLength = getSlotLength(step);\r\n\r\n    const startTimes = dateIntervals\r\n        .map(({ Date, Intervals }) => {\r\n            return Intervals.map((interval) => setTimeOnDate(Date, interval.Start));\r\n        })\r\n        .flat();\r\n\r\n    const groupedTimes = groupBy(startTimes, step);\r\n\r\n    return groupedTimes.map(([endPoint, times]) => {\r\n        return {\r\n            title: endPoint.toString(),\r\n            start: endPoint.toISOString(),\r\n            end: addMinutes(slotLength, endPoint).toISOString(),\r\n            extendedProps: {\r\n                times,\r\n            },\r\n        };\r\n    });\r\n};\r\n\r\ninterface IAppointmentCalendarProps {\r\n    calendar: ICalendar;\r\n    service: IService;\r\n    personCount: number;\r\n    firstFreeSlot: string;\r\n    querySelectedDate?: string | undefined;\r\n    onDateTimeSelect?: (dateTime: string) => void;\r\n    onPersonCountChange: (newPersonCount: number) => void;\r\n    pendingReservations: IPendingReservation[];\r\n}\r\n\r\nconst formatTime = (time: Date, intl: IntlShape) => {\r\n    const formattedTime = intl.formatTime(time);\r\n    if (intl.locale !== 'en') {\r\n        return formattedTime;\r\n    }\r\n    const [numerics, period] = formattedTime.split(' ');\r\n    return numerics + (period === 'AM' ? 'ᴬᴹ' : 'ᴾᴹ');\r\n};\r\n\r\nconst AppointmentCalendar: React.FunctionComponent<IAppointmentCalendarProps> = ({\r\n    calendar,\r\n    service,\r\n    personCount,\r\n    firstFreeSlot,\r\n    querySelectedDate,\r\n    onDateTimeSelect,\r\n    onPersonCountChange,\r\n    pendingReservations,\r\n}) => {\r\n    const [eventTimes, setEventTimes] = useState<IEventTimes>({});\r\n\r\n    const intl = useIntl();\r\n\r\n    const userViewSlotMinutes: number = service.Duration === 0 ? 5 : calendar.UserViewSlotMinutes;\r\n\r\n    const handleEventRender = (\r\n        arg: IEventRenderInfo & {\r\n            currentWeekDay: number | false;\r\n        }\r\n    ) => {\r\n        const times: Date[] = arg.event.extendedProps.times!;\r\n        const { currentWeekDay, view } = arg;\r\n\r\n        const day = getDay(times[0]);\r\n        if (currentWeekDay !== false && day !== currentWeekDay) {\r\n            return null;\r\n        }\r\n\r\n        const slotSize = getSlotLength(userViewSlotMinutes);\r\n        const cellCount = getCellCount(userViewSlotMinutes);\r\n        const cells: Array<Date | null> = Array.from({ length: cellCount }, () => null);\r\n\r\n        if (cellCount === 1) {\r\n            cells[0] = times[0];\r\n        } else {\r\n            times.forEach((time) => {\r\n                const index = indexTime(time, userViewSlotMinutes, slotSize as 30 | 60);\r\n                cells[index] = time;\r\n            });\r\n        }\r\n\r\n        const isInteractive = !calendar.Readonly;\r\n\r\n        const slot = (\r\n            <ol className=\"appointment-calendar__slot\" data-cells={cellCount}>\r\n                {cells.map((time, i) =>\r\n                    time ? (\r\n                        <li className={'appointment-calendar__cell'} key={time.toISOString()}>\r\n                            {isInteractive ? (\r\n                                <button\r\n                                    className={'appointment-calendar__cell-button'}\r\n                                    onClick={() => onDateTimeSelect?.(time.toISOString())}\r\n                                >\r\n                                    <time>{formatTime(time, intl)}</time>\r\n                                </button>\r\n                            ) : (\r\n                                <time>{formatTime(time, intl)}</time>\r\n                            )}\r\n                        </li>\r\n                    ) : (\r\n                        <li key={i} className=\"appointment-calendar__cell--empty\" />\r\n                    )\r\n                )}\r\n            </ol>\r\n        );\r\n\r\n        const isListView = view.type.includes('list');\r\n\r\n        return isListView ? <div style={{ gridColumn: '1 / -1' }}>{slot}</div> : slot;\r\n    };\r\n\r\n    const eventClassNames = (arg: IEventRenderInfo) =>\r\n        handleEventClassNames({\r\n            ...arg,\r\n            minTimeReserve: calendar.MinTimeReserve,\r\n            firstFreeSlot\r\n        });\r\n\r\n    const getEventTimes: EventSourceFunc = useCallback(\r\n        ({ start, end: exclusiveEnd }, successCallback, failureCallback) => {\r\n            const end = subDays(new Date(exclusiveEnd), 1);\r\n            getCalendarFreeIntervals({\r\n                calendarId: calendar.Id,\r\n                serviceId: service.Id,\r\n                personCount,\r\n                startDate: setHours(12, start).toISOString(),\r\n                endDate: setHours(12, end).toISOString(),\r\n                pendingReservations,\r\n            })\r\n                .then((dateIntervals) => {\r\n                    if (dateIntervals) {\r\n                        setEventTimes(\r\n                            dateIntervals\r\n                                .map(({ Date, Intervals }) => {\r\n                                    return {\r\n                                        Date,\r\n                                        Intervals: Intervals.map((interval) => ({\r\n                                            ...interval,\r\n                                            Start: setTimeOnDate(Date, interval.Start),\r\n                                        })),\r\n                                    };\r\n                                })\r\n                                .map(toEventTimes)\r\n                                .reduce((acc, entry) => ({ ...acc, ...entry }))\r\n                        );\r\n                        const mapped =  mapResponse(dateIntervals, userViewSlotMinutes);\r\n                        return mapped;\r\n                    }\r\n                    return [];\r\n                })\r\n                .then(successCallback)\r\n                .catch(failureCallback);\r\n        },\r\n        [personCount]\r\n    );\r\n\r\n    return (\r\n        <div className=\"appointment-calendar\">\r\n            <div className=\"appointment-calendar__text\">\r\n                {calendar.Readonly && <ReadonlyInfo phoneNumber={calendar.PhoneNumber} className='appointment-calendar__readonly' />}\r\n            </div>\r\n            <PersonCount\r\n                    count={personCount}\r\n                    onChange={onPersonCountChange}\r\n                    maxCount={calendar.ConcurrentNum}\r\n                    className='appointment-calendar__person-count'\r\n                />\r\n            <Suspense fallback={<Placeholder />}>\r\n                <Timetable\r\n                    {...{\r\n                        getEventTimes,\r\n                        handleEventRender,\r\n                        handleEventClassNames: eventClassNames,\r\n                        eventTimes,\r\n                        calendar,\r\n                        slotDuration: getSlotLength(userViewSlotMinutes),\r\n                        firstFreeSlot,\r\n                        mobileBreakPoint: getMobileBreakPoint(userViewSlotMinutes),\r\n                        showViewSelectorOnMobile: true,\r\n                        querySelectedDate,\r\n                        userViewSlotMinutes,\r\n                    }}\r\n                />\r\n            </Suspense>\r\n        </div>\r\n    );\r\n};\r\n\r\nexport default AppointmentCalendar;","import React from 'react';\r\nimport { defineMessages, FormattedTime, FormattedMessage, MessageDescriptor } from 'react-intl';\r\nimport { IServiceDetails, IService, calculateGrossPrice } from 'src/entities/service';\r\nimport { ISchedule } from 'src/entities/schedule';\r\nimport { useState, useRef } from 'react';\r\nimport globalMessages from 'src/services/globalMessages';\r\nimport Popup from 'src/components/Popup/Popup';\r\nimport ServiceDescription from 'src/components/ServiceDescription/ServiceDescription';\r\nimport PrimaryButton from 'src/components/form-components/PrimaryButton/PrimaryButton';\r\nimport { useOutsideClick } from 'src/hooks';\r\nimport classNames from 'classnames';\r\nimport PersonCount from '../DateTimeSelect/PersonCount/PersonCount';\r\nimport { getPaymentNeed } from '../../ReservationEnd/functions/helperFunctions';\r\nimport FormattedPrice from '../ServiceSelect/FormattedPrice/FormattedPrice';\r\n\r\nconst messages = defineMessages({\r\n    seat: {\r\n        id: 'seat',\r\n        defaultMessage: '{n} hely'\r\n    }\r\n});\r\n\r\nexport const isFullSchedule = (freeSeatsCount: number): boolean => {\r\n    return freeSeatsCount === 0;\r\n};\r\n\r\nexport const isPassedSchedule = (scheduleStart: string, minTimeReserveHours: number, firstFreeSlot?: string): boolean => {\r\n    const scheduleStartDateTime = new Date(scheduleStart);\r\n    \r\n    if (firstFreeSlot && minTimeReserveHours > 0) {\r\n        const firstFreeSlotDateTime = new Date(firstFreeSlot);\r\n        return scheduleStartDateTime < firstFreeSlotDateTime;\r\n    }\r\n\r\n    const minTimeReserveDateTime = new Date();\r\n    minTimeReserveDateTime.setHours(minTimeReserveDateTime.getHours() + minTimeReserveHours);\r\n    \r\n    return scheduleStartDateTime < minTimeReserveDateTime;\r\n};\r\n\r\nexport const isWeekend = (day: number): boolean => {\r\n    return day === 6 || day === 0;\r\n};\r\n\r\nconst Summary: React.FC<{\r\n    service: IServiceDetails;\r\n    schedule: ISchedule;\r\n    minTimeReserve: number;\r\n    hideSeatCount: boolean;\r\n    isMobile?: boolean;\r\n    firstFreeSlot?: string; \r\n}> = ({ service, schedule, minTimeReserve, hideSeatCount, isMobile, firstFreeSlot }) => {\r\n    const { IsDurationVisible, DurationToUser, DisplayedPrice, DisplayedCurrency } = service;\r\n    const { FreeSeatsCount, Start } = schedule;\r\n\r\n    return (\r\n        <section className=\"event__summary\">\r\n            <h3 className=\"event__name\">{service.Name}</h3>\r\n            <div className=\"event__times\">\r\n                <div className=\"event__times-inner\">\r\n                    <time>\r\n                        <FormattedTime value={Start} />\r\n                    </time>\r\n                    {IsDurationVisible && (\r\n                        <>\r\n                            {' | '}\r\n                            <time dateTime={`P${DurationToUser}M`}>\r\n                                {DurationToUser}\r\n                                {'′'}\r\n                            </time>\r\n                        </>\r\n                    )}\r\n                    {DisplayedPrice && isMobile ? (\r\n                        <>\r\n                            {' | '}{' '}\r\n                            <FormattedPrice value={DisplayedPrice} currency={DisplayedCurrency} />\r\n                        </>\r\n                    ) : (\r\n                        <></>\r\n                    )}\r\n                </div>\r\n            </div>\r\n            <div className=\"event__seats\">\r\n                {isFullSchedule(FreeSeatsCount) ? (\r\n                    <FormattedMessage {...globalMessages.full} />\r\n                ) : isPassedSchedule(schedule.Start, minTimeReserve, firstFreeSlot) ? (\r\n                    <FormattedMessage {...globalMessages.notAvailable} />\r\n                ) : hideSeatCount ? null : (\r\n                    <FormattedMessage {...messages.seat} values={{ n: FreeSeatsCount }} />\r\n                )}\r\n            </div>\r\n        </section>\r\n    );\r\n};\r\n\r\nconst useDetailsElement = (detailsRef: React.RefObject<HTMLDetailsElement>) => {\r\n    const [open, setOpen] = useState(false);\r\n\r\n    useOutsideClick(detailsRef, () => {\r\n        setOpen(false);\r\n    });\r\n\r\n    const handleClickOnDetails = (e: React.MouseEvent<HTMLDetailsElement>) => {\r\n        const { target } = e;\r\n        const shouldStay =\r\n            target instanceof Element && (target.closest('select') || target.closest('.link'));\r\n        setOpen((prev) => (shouldStay ? prev : !prev));\r\n    };\r\n\r\n    const handleClickOnSummary = (e: React.MouseEvent<HTMLElement>) => e.preventDefault();\r\n\r\n    return {\r\n        open,\r\n        handleClickOnDetails,\r\n        handleClickOnSummary,\r\n    };\r\n};\r\n\r\nconst useAvailability = (\r\n    isReadonly: boolean,\r\n    freeSeatsCount: number,\r\n    start: string,\r\n    minTimeReserveHours: number,\r\n    firstFreeSlot?: string\r\n) => {\r\n    const isFull = isFullSchedule(freeSeatsCount);\r\n    const isPassed = isPassedSchedule(start, minTimeReserveHours, firstFreeSlot);\r\n    const isAvailable = !isReadonly && !isFull && !isPassed;\r\n    const notAvailableText: MessageDescriptor | undefined = isPassed\r\n        ? globalMessages.notAvailable\r\n        : isFull\r\n        ? globalMessages.full\r\n        : undefined;\r\n\r\n    return {\r\n        isAvailable,\r\n        notAvailableText,\r\n    };\r\n};\r\n\r\nexport const EventMobile: React.FC<IEventProps & { isListView: boolean }> = ({\r\n    service,\r\n    schedule,\r\n    handleServiceSelect,\r\n    minTimeReserve,\r\n    isListView,\r\n    isReadonly,\r\n    hideSeatCount,\r\n    isPaymentEnabled,\r\n    firstFreeSlot\r\n}) => {\r\n    const { Description, ShortDescription, Price, Currency, PaymentMethod, VatPercentage } =\r\n        service;\r\n    const { FreeSeatsCount, ReservationLimit } = schedule;\r\n\r\n    const needsPayment = getPaymentNeed(isPaymentEnabled, service.Payable);\r\n\r\n    const [isLongDescriptionVisible, setIsLongDescriptionVisible] = useState(false);\r\n    const [personCount, setPersonCount] = useState(1);\r\n\r\n    const detailsRef = useRef<HTMLDetailsElement>(null);\r\n\r\n    const { open, handleClickOnSummary, handleClickOnDetails } = useDetailsElement(detailsRef);\r\n\r\n    const { isAvailable, notAvailableText } = useAvailability(\r\n        isReadonly,\r\n        FreeSeatsCount,\r\n        schedule.Start,\r\n        minTimeReserve,\r\n        firstFreeSlot\r\n    );\r\n\r\n    const event = (\r\n        <details\r\n            className={classNames('event', 'timetable__event--mobile', { 'event--open': open })}\r\n            ref={detailsRef}\r\n            style={{ color: service.Background }}\r\n            open={open}\r\n            onClick={handleClickOnDetails}\r\n        >\r\n            <summary onClick={handleClickOnSummary}>\r\n                <Summary\r\n                    service={service}\r\n                    schedule={schedule}\r\n                    minTimeReserve={minTimeReserve}\r\n                    hideSeatCount={hideSeatCount}\r\n                    isMobile={true}\r\n                    firstFreeSlot={firstFreeSlot}\r\n                />\r\n            </summary>\r\n\r\n            <div className=\"event__description\">\r\n                {needsPayment && (\r\n                    <div className=\"event__price\">\r\n                        <FormattedMessage {...globalMessages.toBePaid} />\r\n                        <FormattedPrice\r\n                            value={calculateGrossPrice({\r\n                                Price,\r\n                                Currency,\r\n                                PaymentMethod,\r\n                                VatPercentage,\r\n                            })}\r\n                            currency={Currency}\r\n                        />\r\n                    </div>\r\n                )}\r\n                {ShortDescription && <p>{ShortDescription}</p>}\r\n                {schedule.Note && <p>{schedule.Note}</p>}\r\n                {Description && (\r\n                    <>\r\n                        <button onClick={() => setIsLongDescriptionVisible(true)} className=\"link\">\r\n                            <FormattedMessage {...globalMessages.readMore} />\r\n                        </button>\r\n                        <Popup\r\n                            visible={isLongDescriptionVisible}\r\n                            closePopup={() => setIsLongDescriptionVisible(false)}\r\n                            title={service.Name}\r\n                        >\r\n                            <ServiceDescription\r\n                                schedule={schedule}\r\n                                service={service}\r\n                                notAvailableText={notAvailableText}\r\n                                needsPayment={needsPayment}\r\n                            />\r\n                        </Popup>\r\n                    </>\r\n                )}\r\n            </div>\r\n            {isAvailable && (\r\n                <div className=\"event__actions\">\r\n                    <PersonCount\r\n                        maxCount={ReservationLimit}\r\n                        count={personCount}\r\n                        onChange={setPersonCount}\r\n                    />\r\n                    <PrimaryButton\r\n                        className=\"event__button\"\r\n                        caption={globalMessages.serviceDescriptionStartReservation}\r\n                        onClick={() => handleServiceSelect(service, schedule, personCount)}\r\n                    />\r\n                </div>\r\n            )}\r\n        </details>\r\n    );\r\n\r\n    return isListView ? <div className=\"timetable__event--list\">{event}</div> : event;\r\n};\r\n\r\ninterface IEventProps {\r\n    service: IServiceDetails,\r\n    schedule: ISchedule,\r\n    handleServiceSelect: (service: IService, schedule: ISchedule, personCount: number) => void,\r\n    minTimeReserve: number,\r\n    isReadonly: boolean,\r\n    hideSeatCount: boolean,\r\n    isPaymentEnabled?: boolean,\r\n    firstFreeSlot?: string\r\n}\r\n\r\nexport const Event: React.FC<IEventProps> = ({ service, schedule, handleServiceSelect, minTimeReserve, isReadonly, hideSeatCount, isPaymentEnabled, firstFreeSlot }) => {\r\n    const [isLongDescriptionVisible, setIsLongDescriptionVisible] = useState(false);\r\n\r\n    const handleClick = (e: React.MouseEvent<HTMLDivElement>) => {\r\n        if (e.target instanceof Element) {\r\n            setIsLongDescriptionVisible(true)\r\n        }\r\n    }\r\n\r\n    const { isAvailable, notAvailableText } = useAvailability(isReadonly, schedule.FreeSeatsCount, schedule.Start, minTimeReserve, firstFreeSlot);\r\n\r\n    return (\r\n        <>\r\n            <div\r\n                onClick={handleClick}\r\n                className=\"event timetable__event\"\r\n                style={{ color: service.Background }}\r\n                tabIndex={0}\r\n            >\r\n                <Summary \r\n                    service={service}\r\n                    schedule={schedule}\r\n                    minTimeReserve={minTimeReserve}\r\n                    hideSeatCount={hideSeatCount}\r\n                    firstFreeSlot={firstFreeSlot} />\r\n            </div>\r\n\r\n            <Popup\r\n                visible={isLongDescriptionVisible}\r\n                closePopup={() => setIsLongDescriptionVisible(false)}\r\n                title={service.Name}>\r\n                <ServiceDescription\r\n                    schedule={schedule}\r\n                    service={service}\r\n                    startReservation={isAvailable\r\n                        ? (personCount) => handleServiceSelect(service, schedule, personCount!)\r\n                        : undefined}\r\n                    notAvailableText={notAvailableText}\r\n                    needsPayment={getPaymentNeed(isPaymentEnabled, service.Payable)}\r\n                />\r\n            </Popup>\r\n        </>\r\n    )\r\n}\r\n","import { getScheduleList } from 'src/services/api/schedule';\r\nimport { useCallback, useState } from 'react';\r\nimport { ICalendar, IInterval } from '../../../../entities/calendar';\r\nimport { IScheduleLists } from '../../../../entities/schedule';\r\nimport { ISchedule } from 'src/entities/schedule';\r\nimport { IServiceDetails } from 'src/entities/service';\r\nimport { EventInput, EventApi, EventSourceFunc, ViewApi } from '@fullcalendar/core';\r\nimport hu from '@fullcalendar/core/locales/hu';\r\nimport de from '@fullcalendar/core/locales/de';\r\nimport sk from '@fullcalendar/core/locales/sk';\r\nimport enGb from '@fullcalendar/core/locales/en-gb';\r\nimport getDay from 'date-fns/getDay';\r\nimport { getServicesByCalendar } from '../../../../services/api/service';\r\nimport { useSubscription } from 'src/hooks';\r\nimport { IntlShape } from 'react-intl';\r\nimport {\r\n    isFullSchedule,\r\n    EventMobile,\r\n    Event,\r\n    isPassedSchedule,\r\n    isWeekend,\r\n} from 'src/components/BookingFlow/modules/TimeTableSelect/Event';\r\nimport MediaQuery from 'react-responsive';\r\nimport React from 'react';\r\nimport subDays from 'date-fns/fp/subDays';\r\n\r\nconst locales = { hu, de, sk };\r\n\r\nexport interface IEventRenderInfo {\r\n    isMirror: boolean;\r\n    isStart: boolean;\r\n    isEnd: boolean;\r\n    event: EventApi & {\r\n        extendedProps: { schedule: ISchedule; service: IServiceDetails };\r\n    };\r\n    el: HTMLElement;\r\n    view: ViewApi;\r\n}\r\n\r\nexport type IEventTimes = Record<string, IInterval[]>;\r\n\r\nexport const getFullCalendarLocale = (locale: string) => {\r\n    const fallbackCalendarLocale = enGb;\r\n    if (locale === 'en') {\r\n        return enGb;\r\n    }\r\n\r\n    const calendarLocale = locales[locale as keyof typeof locales];\r\n    return calendarLocale ?? fallbackCalendarLocale;\r\n};\r\n\r\nexport const mapScheduleResponse = (\r\n    schedules: IScheduleLists,\r\n    services: IServiceDetails[]\r\n): EventInput[] =>\r\n    Object.values(schedules)\r\n        .flat()\r\n        .map((schedule) => ({\r\n            schedule,\r\n            service: services.find((s) => s.Id === schedule.ServiceId),\r\n        }))\r\n        .map(({ schedule, service }) => ({\r\n            title: service!.Name,\r\n            start: schedule.Start,\r\n            end: schedule.End,\r\n            borderColor: undefined,\r\n            extendedProps: {\r\n                schedule,\r\n                service,\r\n            },\r\n        }));\r\n\r\nexport const useSchedules = (calendar: ICalendar) => {\r\n    const getServices = useCallback(() => getServicesByCalendar(calendar.Id), [calendar.Id]);\r\n    const [services, areServicesLoading] = useSubscription(getServices, []);\r\n\r\n    const [eventSourceParams, setEventSourceParams] = useState<\r\n        Parameters<EventSourceFunc> | undefined\r\n    >(undefined);\r\n\r\n    const getSchedules: EventSourceFunc = useCallback(\r\n        (...arg: Parameters<EventSourceFunc>) => setEventSourceParams(arg),\r\n        []\r\n    );\r\n\r\n    const fetchSchedules = useCallback(async () => {\r\n        if (eventSourceParams && !areServicesLoading) {\r\n            const [{ start, end: exclusiveEnd }, successCallback, failureCallback] =\r\n                eventSourceParams;\r\n\r\n            const end = subDays(1, new Date(exclusiveEnd));\r\n\r\n            try {\r\n                const result = await getScheduleList(\r\n                    calendar.Id,\r\n                    start.toISOString(),\r\n                    end.toISOString(),\r\n                    true\r\n                );\r\n                successCallback(mapScheduleResponse(result, services));\r\n                return result;\r\n            } catch (e) {\r\n                failureCallback(e);\r\n                throw e;\r\n            }\r\n        }\r\n\r\n        return null;\r\n    }, [\r\n        services,\r\n        areServicesLoading,\r\n        eventSourceParams && eventSourceParams[0].start.toISOString(),\r\n        eventSourceParams && eventSourceParams[0].end.toISOString(),\r\n        eventSourceParams && eventSourceParams[1],\r\n        eventSourceParams && eventSourceParams[2],\r\n    ]);\r\n\r\n    const [scheduleLists, isLoading, error] = useSubscription(fetchSchedules);\r\n\r\n    return {\r\n        getSchedules,\r\n        scheduleLists,\r\n        isLoading: areServicesLoading || isLoading,\r\n        error,\r\n    };\r\n};\r\n\r\nexport const handleEventClassNames = (\r\n    arg: IEventRenderInfo & {\r\n        minTimeReserve: number;\r\n        firstFreeSlot?: string;\r\n    }\r\n) => {\r\n    const { event, minTimeReserve, firstFreeSlot } = arg;\r\n    const { schedule } = event.extendedProps;\r\n\r\n    if (typeof schedule === 'undefined') {\r\n        return '';\r\n    }\r\n\r\n    return isFullSchedule(schedule.FreeSeatsCount) ||\r\n    isPassedSchedule(schedule.Start, minTimeReserve, firstFreeSlot)\r\n        ? 'fc-event-disabled'\r\n        : '';\r\n};\r\n\r\nexport const handleEventRender: (\r\n    arg: IEventRenderInfo & {\r\n        handleServiceSelect: (\r\n            service: IServiceDetails,\r\n            schedule: ISchedule,\r\n            personCount: number\r\n        ) => void;\r\n        intl: IntlShape;\r\n        currentWeekDay: number | false;\r\n        minTimeReserve: number;\r\n        isReadonly: boolean;\r\n        hideSeatCount: boolean;\r\n        isWeekendDisabled: boolean;\r\n        isPaymentEnabled?: boolean;\r\n        firstFreeSlot?: string;\r\n    }\r\n) => JSX.Element | null = ({\r\n    event,\r\n    handleServiceSelect,\r\n    currentWeekDay,\r\n    minTimeReserve,\r\n    view,\r\n    isReadonly,\r\n    hideSeatCount,\r\n    isWeekendDisabled,\r\n    isPaymentEnabled,\r\n    firstFreeSlot\r\n}) => {\r\n    const { schedule, service } = event.extendedProps as {\r\n        service: IServiceDetails;\r\n        schedule: ISchedule;\r\n    };\r\n\r\n    const day = getDay(new Date(schedule.Start));\r\n\r\n    if (currentWeekDay !== false && day !== currentWeekDay) {\r\n        return null;\r\n    }\r\n\r\n    if (isWeekendDisabled && isWeekend(day)) {\r\n        return null;\r\n    }\r\n\r\n    const eventProps = {\r\n        schedule,\r\n        service,\r\n        handleServiceSelect,\r\n        minTimeReserve,\r\n        isReadonly,\r\n        hideSeatCount,\r\n        isPaymentEnabled,\r\n        firstFreeSlot\r\n    };\r\n\r\n    return (\r\n        <MediaQuery query=\"(max-width: 48rem)\">\r\n            {(matches) =>\r\n                matches ? (\r\n                    <EventMobile {...eventProps} isListView={view.type.includes('list')} />\r\n                ) : (\r\n                    <Event {...eventProps} />\r\n                )\r\n            }\r\n        </MediaQuery>\r\n    );\r\n};","import React, { useState } from 'react';\r\n\r\nexport interface IImageProps {\r\n    src: string;\r\n    className?: string;\r\n    usePlaceholder?: true;\r\n}\r\n\r\nconst Image: React.FC<IImageProps> = ({ src, className, usePlaceholder }) => {\r\n    const [loadingFailed, setLoadingFailed] = useState(false);\r\n\r\n    return (\r\n        <>\r\n            {!loadingFailed ? (\r\n                <img className={className} src={src} onError={() => setLoadingFailed(true)} />\r\n            ) : (\r\n                <>{usePlaceholder ? <div className={className + ' placeholder-image'} /> : null}</>\r\n            )}\r\n        </>\r\n    );\r\n};\r\n\r\nexport default Image;\r\n","import React from 'react';\r\nimport CustomScroll from 'react-custom-scroll';\r\nimport { calculateGrossPrice, IServiceDetails } from '../../entities/service';\r\nimport PrimaryButton from '../form-components/PrimaryButton/PrimaryButton';\r\nimport SecondaryButton from '../form-components/SecondaryButton/SecondaryButton';\r\nimport { IPopupable } from '../Popup/Popup';\r\nimport globalMessages from 'src/services/globalMessages';\r\nimport PersonCount from '../BookingFlow/modules/DateTimeSelect/PersonCount/PersonCount';\r\nimport { useState } from 'react';\r\nimport FormattedPrice from '../BookingFlow/modules/ServiceSelect/FormattedPrice/FormattedPrice';\r\nimport { useStyleLinks } from 'src/hooks';\r\nimport { useRef } from 'react';\r\nimport { FormattedMessage, FormattedDate, MessageDescriptor } from 'react-intl';\r\nimport { ISchedule } from 'src/entities/schedule';\r\nimport Image from '../Image/Image';\r\n\r\ninterface IServiceDescriptionProps extends IPopupable {\r\n    service: IServiceDetails;\r\n    schedule?: ISchedule;\r\n    startReservation?: (freeSeatCount?: number) => void;\r\n    notAvailableText?: MessageDescriptor;\r\n    needsPayment?: boolean;\r\n}\r\n\r\nconst ServiceDescription: React.FunctionComponent<IServiceDescriptionProps> = props => {\r\n    const { IsDurationVisible, DurationToUser, Description, ShortDescription, DisplayedPrice, DisplayedCurrency, Price, Currency, Note, PictureLink, VatPercentage: Vat, PaymentMethod } = props.service;\r\n    const { startReservation, closePopup, schedule, notAvailableText, needsPayment } = props;\r\n    const freeSeatCount = props.schedule?.FreeSeatsCount;\r\n    const reservationLimit = props.schedule?.ReservationLimit;\r\n\r\n    const handleOk = () => {\r\n        closePopup?.();\r\n        if (startReservation) { startReservation(personCount); }\r\n    }\r\n\r\n    const bodyRef = useRef<HTMLDivElement>(null);\r\n    useStyleLinks(bodyRef);\r\n\r\n    const [personCount, setPersonCount] = useState(1);\r\n\r\n    return (\r\n        <section className=\"service-description\">\r\n            <CustomScroll>\r\n                <div className=\"service-description-scroll\">\r\n                    <div className=\"service-description__details\">\r\n                        {schedule?.Start &&\r\n                            <time dateTime={schedule.Start} className=\"service-description__detail\">\r\n                                <FormattedDate\r\n                                    value={schedule.Start}\r\n                                    year=\"numeric\"\r\n                                    month=\"numeric\"\r\n                                    day=\"numeric\"\r\n                                    hour=\"numeric\"\r\n                                    minute=\"numeric\" />\r\n                            </time>\r\n                        }\r\n                        {IsDurationVisible &&\r\n                            <span className=\"service-description__detail\">\r\n                                <FormattedMessage {...globalMessages.minute} values={{ n: DurationToUser }} />\r\n                            </span>\r\n                        }\r\n                        {DisplayedPrice ?\r\n                            <FormattedPrice className=\"service-description__detail\" value={DisplayedPrice} currency={DisplayedCurrency} />\r\n                            : <></>\r\n                        }\r\n                        {needsPayment &&\r\n                            <div className=\"service-description__price\">\r\n                                <span className=\"service-description__online-payable\">\r\n                                    <FormattedMessage {...globalMessages.toBePaid} />\r\n                                </span>\r\n                                <span className=\"service-description__online-price\">\r\n                                    <FormattedPrice value={calculateGrossPrice({ Price, Currency, PaymentMethod, VatPercentage: Vat })} currency={Currency} />\r\n                                </span>\r\n                            </div>\r\n                        }\r\n                    </div>\r\n                    {schedule?.Note &&\r\n                        <div className=\"service-description-note service-description-note--schedule\">{schedule.Note}</div>\r\n                    }\r\n                    {ShortDescription &&\r\n                        <div className=\"service-description__body\">{ShortDescription}</div>\r\n                    }\r\n                    {Note &&\r\n                        <div className=\"service-description-note\">{Note}</div>\r\n                    }\r\n                    {PictureLink &&\r\n                        <Image className=\"service-description__service-logo\" src={PictureLink} />\r\n                    }\r\n                    {Description &&\r\n                        <div ref={bodyRef} className=\"service-description__body\" dangerouslySetInnerHTML={{ __html: Description }} />\r\n                    }\r\n                </div>\r\n            </CustomScroll>\r\n            {startReservation &&\r\n                <div className=\"service-description__buttons\">\r\n                    {closePopup && freeSeatCount === undefined &&\r\n                        <SecondaryButton\r\n                            className=\"service-description__button service-description__cancel\"\r\n                            onClick={closePopup}\r\n                            caption={globalMessages.close} />\r\n                    }\r\n                    {!!reservationLimit &&\r\n                        <div className=\"service-description__person-count\">\r\n                            <PersonCount count={personCount} maxCount={reservationLimit} onChange={setPersonCount} />\r\n                        </div>\r\n                    }\r\n                    {(freeSeatCount === undefined || freeSeatCount > 0) &&\r\n                        <PrimaryButton\r\n                            autoFocus={true}\r\n                            className=\"service-description__button\"\r\n                            onClick={handleOk} caption={globalMessages.serviceDescriptionStartReservation} />\r\n                    }\r\n                    {freeSeatCount === 0 &&\r\n                        <FormattedMessage {...globalMessages.full} />\r\n                    }\r\n                </div>\r\n            }\r\n            {notAvailableText &&\r\n                <div className=\"service-description__not-available\">\r\n                    <FormattedMessage {...notAvailableText} />\r\n                </div>\r\n            }\r\n        </section>\r\n    );\r\n}\r\n\r\nexport default ServiceDescription;"],"names":["Timetable","lazy","mobileBreakPoints","getSlotLength","resolutionInMinutes","getCellCount","cellLength","toEventTimes","dateInterval","Date","Intervals","formatTime","time","intl","formattedTime","locale","split","calendar","service","personCount","firstFreeSlot","querySelectedDate","onDateTimeSelect","onPersonCountChange","pendingReservations","useState","eventTimes","setEventTimes","userViewSlotMinutes","Duration","UserViewSlotMinutes","getEventTimes","useCallback","successCallback","failureCallback","start","exclusiveEnd","end","calendarId","Id","serviceId","startDate","toISOString","endDate","then","dateIntervals","map","interval","Start","reduce","acc","entry","mapped","step","slotLength","startTimes","flat","dates","ds","d","grouped","s","dateTime","key","floorToHalfHour","floorToHour","push","addTime","Object","entries","value","groupBy","endPoint","times","title","toString","extendedProps","mapResponse","catch","className","Readonly","phoneNumber","PhoneNumber","count","onChange","maxCount","ConcurrentNum","Suspense","fallback","handleEventRender","arg","event","currentWeekDay","view","day","slotSize","cellCount","cells","Array","from","length","forEach","index","date","cellSize","minutes","Math","floor","indexTime","isInteractive","slot","i","onClick","type","includes","style","gridColumn","handleEventClassNames","minTimeReserve","MinTimeReserve","slotDuration","mobileBreakPoint","replace","String","showViewSelectorOnMobile","messages","seat","id","defaultMessage","isFullSchedule","freeSeatsCount","isPassedSchedule","scheduleStart","minTimeReserveHours","scheduleStartDateTime","minTimeReserveDateTime","setHours","getHours","Summary","schedule","hideSeatCount","isMobile","IsDurationVisible","DurationToUser","DisplayedPrice","DisplayedCurrency","FreeSeatsCount","Name","FormattedPrice","currency","globalMessages","full","notAvailable","values","n","useAvailability","isReadonly","isFull","isPassed","isAvailable","notAvailableText","undefined","EventMobile","handleServiceSelect","isListView","isPaymentEnabled","Description","ShortDescription","Price","Currency","PaymentMethod","VatPercentage","ReservationLimit","needsPayment","Payable","isLongDescriptionVisible","setIsLongDescriptionVisible","setPersonCount","detailsRef","useRef","open","setOpen","handleClickOnDetails","e","target","shouldStay","Element","closest","prev","handleClickOnSummary","preventDefault","useDetailsElement","ref","color","Background","toBePaid","Note","readMore","Popup","visible","closePopup","ServiceDescription","PersonCount","PrimaryButton","caption","serviceDescriptionStartReservation","Event","tabIndex","startReservation","locales","hu","de","sk","getFullCalendarLocale","fallbackCalendarLocale","calendarLocale","useSchedules","getServices","services","areServicesLoading","eventSourceParams","setEventSourceParams","getSchedules","fetchSchedules","subDays","result","schedules","find","ServiceId","End","borderColor","mapScheduleResponse","scheduleLists","isLoading","error","isWeekendDisabled","getDay","isWeekend","eventProps","query","matches","src","usePlaceholder","loadingFailed","setLoadingFailed","onError","props","PictureLink","Vat","freeSeatCount","reservationLimit","bodyRef","year","month","hour","minute","dangerouslySetInnerHTML","__html","close","autoFocus"],"sourceRoot":""}