{"id":1654,"date":"2024-08-01T15:19:18","date_gmt":"2024-08-01T15:19:18","guid":{"rendered":"https:\/\/summithealth.sisnettdesign.com\/prendre-rendez-vous\/"},"modified":"2025-04-29T13:03:18","modified_gmt":"2025-04-29T13:03:18","slug":"prendre-rendez-vous","status":"publish","type":"page","link":"https:\/\/summithealth.ca\/fr\/prendre-rendez-vous\/","title":{"rendered":"Prendre rendez-vous"},"content":{"rendered":"\n\n<!DOCTYPE html>\n\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" \/>\n    <meta\n      http-equiv=\"Content-Security-Policy\"\n      content=\"upgrade-insecure-requests\"\n    \/>\n    <meta\n      name=\"viewport\"\n      content=\"width=device-width, initial-scale=1.0, maximum-scale=1\"\n    \/>\n\n    <!-- Bootstrap -->\n    <script src=\"https:\/\/cliniquevoyageur.ca\/external-js\/bootstrap.min.js\"><\/script>\n    <link rel=\"stylesheet\" href=\"https:\/\/cliniquevoyageur.ca\/external-js\/bootstrap.min.css\">\n    <!-- Font Awesome -->\n    <!-- <link rel=\"stylesheet\" href=\"https:\/\/cliniquevoyageur.ca\/external-js\/all.min.css\"> -->\n    <link rel=\"stylesheet\" href=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/font-awesome\/6.7.2\/css\/all.min.css\"\n      integrity=\"sha512-Evv84Mr4kqVGRNSgIGL\/F\/aIDqQb7xQ2vcrdIwxfjThSH8CSR7PBEakCr51Ck+w+\/U6swU2Im1vVX0SVk9ABhg==\"\n      crossorigin=\"anonymous\" referrerpolicy=\"no-referrer\" \/>\n    <!-- jQuery -->\n    <script src=\"https:\/\/cliniquevoyageur.ca\/external-js\/jquery.min.js\"><\/script>\n    <!-- Semantic UI -->\n    <script src=\"https:\/\/cliniquevoyageur.ca\/external-js\/semantic.min.js\"><\/script>\n    <!-- <link rel=\"stylesheet\" href=\"https:\/\/cliniquevoyageur.ca\/external-js\/semantic.min.css\"> -->\n    <link href=\"https:\/\/cdn.jsdelivr.net\/npm\/semantic-ui@2.5.0\/dist\/semantic.min.css\" rel=\"stylesheet\">\n  \n    <style>\n      .App {\n        transition: 0.3s;\n        padding-top: 10px;\n        min-height: 100vh;\n      }\n      \n      .book {\n        color: #0058a4;\n        font-family: \"Poppins\", sans-serif;\n      }\n\n      .info {\n        color: #6b655b;\n      }\n\n      .info-container {\n        border: 3px solid rgb(244, 119, 33);\n        border-radius: 10px;\n      }\n\n      .tip {\n        color: #0058a4;\n        align-self: flex-start;\n        flex: 1;\n      }\n\n      .button {\n        background-color: #1e73be;\n        border-color: #1e73be;\n        min-width: 100px;\n      }\n\n      button.light {\n        background-color: white;\n        border-color: white;\n        color: #1e73be;\n      }\n\n      .button:hover {\n        background-color: #1e73be;\n        border-color: #1e73be;\n      }\n\n      .button.light:hover {\n        background-color: white;\n        border-color: white;\n        color: #1e73be;\n      }\n\n      .map-container {\n        overflow: hidden;\n        padding-bottom: 56.25%;\n        position: relative;\n        height: 0;\n      }\n\n      .map-container iframe {\n        left: 0;\n        top: 0;\n        height: 100%;\n        width: 100%;\n        position: absolute;\n      }\n\n      #loading-spinner {\n        width: 60px;\n        height: 60px;\n        color: #1e73be;\n      }\n\n      .hl-day {\n        flex: 1;\n        margin: 0;\n      }\n\n      .hl-day .day {\n        font-size: 14px;\n      }\n\n      .day.text-muted {\n        background-color: #9e9e9e;\n      }     \n\n      .day:hover {\n        background-color: #cdcdcd; \n      }\n\n      .time-slot {\n        color: #0058a4;\n        border-color: #1e73be;\n        border-radius: 3px;\n      }\n\n      .time-slot:hover {\n        color: white;\n        border-color: white;\n        background-color: #1e73be;\n      }\n\n      .time-slot.selected {\n        color: white;\n        border-color: white;\n        background-color: #1e73be;\n      }\n\n      .map-cont {\n        border-bottom: #1e73be 2px solid;\n        margin: 20px 0px;\n      }\n\n      .scrolling-wrapper {\n        overflow-x: auto;\n        -ms-overflow-style: none;\n        scrollbar-width: none;\n        display: flex;\n      }\n\n      .scrolling-wrapper::-webkit-scrollbar {\n        display: none;\n      }\n\n      .day {\n        width: 60px;\n        height: 60px;\n      }\n\n      .entryRow {\n        box-shadow: 0 4px 8px 0 rgb(0 0 0 \/ 20%);\n        transition: 0.3s;\n        padding-top: 10px;\n      }\n\n      .locationName {\n        font-size: 25px;\n        font-weight: 500;\n      }\n\n      .bg-primary {\n        background-color: #0058a4 !important;\n      }\n\n      .chevron {\n        background-color: white;\n      }\n\n      .chevronDay {\n        background-color: #0058a4;\n      }\n\n      .rescheduleDiv {\n        background-color: #ffeea46e;\n      }\n      \n      .progress-bar {\n        background-color: #59a1ff;\n        border-radius: 10px;\n      }\n\n      .progressLabel {\n        color: \"gray\";\n        font-family: \"Poppins\", sans-serif;\n        font-size: 18px;\n      }\n\n      .service-info {\n        border-right: 1px solid #cccccc;\n        padding-right: 50px;\n      }\n\n      input[type=\"date\"] {\n        text-align: right;\n      }\n\n      input[type=\"date\"]:before {\n        color: gray;\n        content: attr(placeholder) !important;\n        margin-right: 0.5em;\n      }\n\n      .input-error {\n        border: 2px solid rgb(214, 0, 0);\n        border-radius: 4px;\n      }\n\n      .input-container {\n        display: flex;\n        flex-direction: column;\n        align-items: flex-start;\n        width: 100%;\n      }\n\n      .input-wrapper {\n        width: 100%;\n        position: relative;\n      }\n\n      .error-message {\n        color: rgb(214, 0, 0);\n        font-size: 14px;\n        display: inline-block;       \n        white-space: nowrap;         \n        margin-top: 0 !important;\n      }\n\n      .error-border select {\n        border: 2px solid rgb(214, 0, 0) !important;\n      }\n\n      .date-input {\n        width: 100%;\n        margin-bottom: 0; \n        padding-bottom: 0;\n      }\n\n      [id^=\"date\"] {\n        background-color: #fafafa !important;\n      }\n\n      .chip {\n        display: inline-block;\n        padding: 0px 10px;\n        font-size: 14px;\n        line-height: 30px;\n        border-radius: 25px;\n        background-color: #fafafa;\n        margin-right: 10px;\n        margin-bottom: 5px;\n        align-items: center;\n      }\n\n      .closebtn {\n        padding-left: 10px;\n        color: #0058a4;\n        font-weight: bold;\n        float: right;\n        font-size: 20px;\n        cursor: pointer;\n      }\n\n      .closebtn:hover {\n        color: #59a1ff;\n      }\n\n      .birthdate-col {\n        padding-left: 2px;\n        padding-right: 2px;\n      }\n\n      .birthdate-col-dd {\n        padding-right: 2px;\n      }\n\n      @media screen and (max-width: 500px) {\n        .hl-day {\n          padding: 0 5px;\n          margin: 0;\n        }\n\n        .day {\n          width: 42px;\n          height: 42px;\n        }\n\n        .day-font {\n          font-size: 13px;\n        }\n\n        .progressLabel {\n          font-size: small;\n        }\n\n        .birthdate-col,\n        .birthdate-col-dd {\n          margin-bottom: 8px !important; \n          width: 100px; \n        }\n      }\n      @media screen and (max-width: 767px) {\n        .service-info {\n          border: 0;\n          padding-right: 0;\n        }\n\n        .birthdate-col,\n        .birthdate-col-dd {\n          margin-bottom: 8px !important; \n          width: 100px; \n        }\n      }\n    <\/style>\n  <\/head>\n\n  <body>\n    <div id=\"book-form\"><\/div>\n    <!-- Google Maps API -->\n    <script type=\"text\/javascript\" src=\"https:\/\/maps.google.com\/maps\/api\/js?libraries=places&#038;language=en-US&#038;key=AIzaSyB5DtRtOTmliqRm1yRgblVnEVDTxJTxdV8\"><\/script>\n    <!-- Babel Standalone -->\n    <script src=\"https:\/\/cliniquevoyageur.ca\/external-js\/babel.min.js\"><\/script>\n    <!-- React & ReactDOM -->\n    <script src=\"https:\/\/cliniquevoyageur.ca\/external-js\/react.production.min.js\"><\/script>\n    <script src=\"https:\/\/cliniquevoyageur.ca\/external-js\/react-dom.production.min.js\"><\/script>\n    <!-- React Bootstrap -->\n    <script src=\"https:\/\/cliniquevoyageur.ca\/external-js\/react-bootstrap.min.js\"><\/script>\n    <!-- React Modal -->\n    <script src=\"https:\/\/cliniquevoyageur.ca\/external-js\/react-modal.min.js\"><\/script>\n    <!-- SweetAlert2 -->\n    <script src=\"https:\/\/cliniquevoyageur.ca\/external-js\/sweetalert2.all.min.js\"><\/script>\n    <link rel=\"stylesheet\" href=\"https:\/\/cliniquevoyageur.ca\/external-js\/sweetalert2.min.css\">\n    <!-- Moment.js -->\n    <script src=\"https:\/\/cliniquevoyageur.ca\/external-js\/moment.min.js\"><\/script>\n    <!-- Lodash -->\n    <script src=\"https:\/\/cliniquevoyageur.ca\/external-js\/lodash.min.js\"><\/script>\n    <!-- Google reCAPTCHA -->\n    <script src=\"https:\/\/cliniquevoyageur.ca\/external-js\/recaptcha-api.js\"><\/script>\n    <!-- Semantic UI Calendar React -->\n    <script src=\"https:\/\/cliniquevoyageur.ca\/external-js\/semantic-ui-calendar-react.js\"><\/script>\n    <!-- Moment Timezone -->\n    <script src=\"https:\/\/cliniquevoyageur.ca\/external-js\/moment-timezone-with-data.min.js\"><\/script>\n\n    <script type=\"text\/babel\">\n      let NO_BYPASSED_DAYS = 0;\n      const BASE_URL = \"https:\/\/api.summittravelhealthdev.com\/v1\/\";\n      const PROD_BASE_URL = \"https:\/\/api.summittravelhealthdev.com\/v1\/\";\n      const DEV_BASE_URL = \"https:\/\/dev.summittravelhealthdev.com\/v1\/\";\n\n      const get = async (url, params) => {\n        const formattedParams = new URLSearchParams(params);\n        const res = await fetch(BASE_URL + url + formattedParams);\n        const data = await res.json();\n        return data;\n      };\n\n      const post = async (url, params) => {\n        const res = await fetch(BASE_URL + url, {\n          method: \"POST\",\n          headers: {\n            \"Content-Type\": \"application\/json\",\n          },\n          body: JSON.stringify(params),\n        });\n        const data = await res.json();\n        return data;\n      };\n\n      const getServiceForOnlineBooking = async (params) => {\n        return get(\"appointment\/getServiceForOnlineBooking?\", params);\n      };\n\n      const getLocations = (params) => {\n        return get(\"appointment\/getLocations?\", params);\n      };\n\n      const getAvailabilities = (params) => {\n        return post(\"appointment\/getAvailabilities\", params);\n      };\n\n      const getVirtualAvailabilities = (params) => {\n        return post(\"appointment\/getVirtualAvailabilities\", params);\n      };\n\n      const book = (params) => {\n        return post(\"appointment\/bookConvergeAppointment\", params);\n      };\n\n      const getAppointment = (params) => {\n        return get(`appointment\/${params.id}?`, params);\n      };\n\n      const rescheduleAppointment = (params) => {\n        return post(`appointment\/${params.id}\/rescheduleAppointment`, params);\n      };\n\n      const addLocationSearch = (params) => {\n        return post(`appointment\/addLocationSearch`, params);\n      };\n\n      const checkDuplicateAppointments = (params) => {\n        return post(`user\/checkDuplicateAppointments?`, params);\n      };\n\n      const validatePromoCode = (params) => {\n        return get(`appointment\/validatePromoCode?`, params);\n      };\n\n      const getCountries = (params) => {\n        return get(\"questionnaire\/countries\", params);\n      };\n\n      const getVaccines = (params) => {\n        return get(\"appointment\/getVaccines\", params);\n      };\n\n      const { React, ReactBootstrap } = window;\n      const {\n        useState,\n        useRef,\n        useEffect,\n        useCallback,\n        useMemo,\n        useLayoutEffect,\n      } = React;\n      const {\n        Form,\n        Col,\n        Row,\n        Card,\n        Button,\n        Container,\n        Spinner,\n        Image,\n        ProgressBar,\n        Tab,\n        Tabs,\n      } = ReactBootstrap;\n\n      const debounce = _.debounce;\n\n      const useRecaptcha = (action, params) => {\n        return new Promise((resolve, reject) => {\n          grecaptcha.ready(async () => {\n            const recaptchaToken = await grecaptcha.execute(\n              \"6Lc_N-ccAAAAAIk6kJA_6lrea6jnEW7rcO8gKMOZ\",\n              {\n                action: \"book\",\n              }\n            );\n            try {\n              const response = await action({\n                recaptchaToken,\n                ...params,\n              });\n              if (!response.errorCode) {\n                resolve(response);\n              } else {\n                reject(response);\n              }\n            } catch (e) {\n              reject(e);\n            }\n          });\n        });\n      };\n\n      const getAddressAttribute = (\n        loc,\n        param,\n        defaultValue = \"\",\n        long = true\n      ) => {\n        if (loc && loc.address_components) {\n          const component = loc.address_components.find((component) =>\n            component.types.includes(param)\n          );\n          if (component) {\n            return long ? component.long_name : component.short_name;\n          }\n        }\n        return defaultValue;\n      };\n\n      const getFormattedAddress = (address) => {\n        return `${address.street}, ${address.apartment}, ${address.city}, ${address.province}`;\n      };\n\n      const validateCard = (cardNumber) => {\n        \/\/ Remove any spaces or dashes from the card number\n        cardNumber = cardNumber.replace(\/\\s+|-\/g, \"\");\n\n        \/\/ Check if the card number is the correct length\n        if (cardNumber.length < 13 || cardNumber.length > 19) {\n          return false;\n        }\n\n        \/\/ Use the Luhn algorithm to check the validity of the card number\n        let sum = 0;\n        let isEven = false;\n        for (let i = cardNumber.length - 1; i >= 0; i--) {\n          let digit = parseInt(cardNumber.charAt(i));\n          if (isEven) {\n            digit *= 2;\n            if (digit > 9) {\n              digit -= 9;\n            }\n          }\n          sum += digit;\n          isEven = !isEven;\n        }\n\n        return sum % 10 === 0;\n      };\n\n      var removeBookedSlot = function (slotJson) {\n        if (slotJson == null) return [];\n        for (var k = 0; k < slotJson.length; k++) {\n          var avaiableSlot = [];\n          var selectedSlots = slotJson[k].slots;\n          var bookedSlot = {};\n          if (selectedSlots != null) {\n            for (var index in selectedSlots) {\n              if (selectedSlots[index].isBookedSlot)\n                bookedSlot[selectedSlots[index].slot] = true;\n            }\n            for (var index in selectedSlots) {\n              if (\n                selectedSlots[index].slot &#038;&#038;\n                !selectedSlots[index].isBookedSlot\n              ) {\n                var isSlotAvailable = true;\n                for (var blockedindex in bookedSlot) {\n                  var eventStart, eventEnd, slotStart, slotEnd;\n                  var slotTime = selectedSlots[index].slot.split(\"_\");\n                  var eventTime = blockedindex.split(\"_\");\n                  if (\n                    !isSlotAvailableforBooking(\n                      eventTime[0],\n                      eventTime[1],\n                      slotTime[0],\n                      slotTime[1]\n                    )\n                  ) {\n                    isSlotAvailable = false;\n                    break;\n                  }\n                }\n                if (!isSlotAvailable) {\n                  continue;\n                }\n                avaiableSlot.push(selectedSlots[index]);\n              }\n            }\n          }\n          slotJson[k].slots = avaiableSlot;\n        }\n        return slotJson;\n      };\n      \/\/ Additional method,\n      var getTimeValue = function (e) {\n          var t = 0,\n            a = e.split(\" \"),\n            i = a[0].split(\":\");\n          return (\n            \"PM\" == a[1] &#038;&#038; \"12\" != i[0]\n              ? (t += 720)\n              : \"AM\" == a[1] &#038;&#038; \"12\" == i[0] &#038;&#038; (i[0] = 0),\n            (t += 60 * parseInt(i[0])),\n            (t += parseInt(i[1]))\n          );\n        },\n        isSlotAvailableforBooking = function (e, t, a, i) {\n          var l = getTimeValue(e),\n            r = getTimeValue(t),\n            n = getTimeValue(a),\n            u = getTimeValue(i);\n          return (\n            \"12:00 AM\" == t &#038;&#038; (r = 1440),\n            !(\n              (l < n &#038;&#038; r > n) ||\n              (l < u &#038;&#038; r > u) ||\n              (l < n &#038;&#038; r > u) ||\n              (l >= n && r <= u)\n            )\n          );\n        };\n\n      const getMergedDates = (availableExpert) => {\n        let dates = {};\n        let experts = {};\n        for (let key in availableExpert) {\n          let expert = availableExpert[key];\n          expert = removeBookedSlot(expert);\n          experts[key] = expert;\n        }\n        if (availableExpert) {\n          let mergedExperts = _(experts).toArray().flatten().value();\n          mergedExperts.forEach((value) => {\n            const existingSlots = dates[value.strDate]\n              ? dates[value.strDate].slots\n              : {};\n            dates[value.strDate] = {\n              ...value,\n              slots: [...existingSlots, ...value.slots],\n            };\n          });\n        }\n        return dates;\n      };\n\n      const weekDays = [\"Dim\", \"Lun\", \"Mar\", \"Mer\", \"Jeu\", \"Ven\", \"Sam\"];\n\n      const DatePicker = ({\n        selectedDate,\n        onChange,\n        showDateModal,\n        minDate,\n        maxDate,\n        disableNavigation,\n      }) => {\n        const [showDate, setShowDate] = useState(new Date(selectedDate));\n        const [startDate, setStartDate] = useState(new Date()); \n        const containerRef = useRef(null);\n        const currentDayRef = useRef();\n        const selectedDateRef = useRef(selectedDate);\n        const [initialized, setInitialized] = useState(false);\n\n        const shouldBypassDates = minDate || maxDate;\n\n        const date = new Date();\n        const now = new Date(\n          date.getFullYear(),\n          date.getMonth(),\n          date.getDate()\n        );\n\n        useLayoutEffect(() => {\n          if (currentDayRef.current) {\n            requestAnimationFrame(() => {\n              currentDayRef.current.scrollIntoView({\n                inline: \"center\",\n                block: \"nearest\",\n                behavior: \"smooth\",\n              });\n            });\n          }\n          if (selectedDateRef.current !== selectedDate) {\n            setShowDate(new Date(selectedDate));\n            selectedDateRef.current = selectedDate;\n          }\n        }, [currentDayRef.current, selectedDate]);\n\n        \/\/ first day of the month, CAREFULL: object will change by for loop!\n        const firstDayThisMonth = new Date(\n          showDate.getFullYear(),\n          showDate.getMonth(),\n          1\n        );\n\n        \/\/ getDay sunday=0 and we monday=0\n        const dayOfWeek = (firstDayThisMonth.getDay() + 6) % 7;\n\n        \/\/ first day of next month\n        const firstDayNextMonth = new Date(\n          showDate.getFullYear(),\n          showDate.getMonth() + 1,\n          1\n        );\n\n        \/\/ useEffect(() => {\n        \/\/   if(initialTBDateTime){\n        \/\/     if (minDate) {\n        \/\/       setStartDate(minDate);\n        \/\/     }\n        \/\/   } else {\n        \/\/     if (minDate) {\n        \/\/       setStartDate(minDate);\n        \/\/       setShowDate(minDate);\n        \/\/     }\n        \/\/   }\n        \/\/ }, [minDate, initialTBDateTime]);\n\n        useEffect(() => {\n          if (!initialized && minDate) {\n            setStartDate(minDate);\n            setShowDate(minDate);\n            onChange(minDate); \n            setInitialized(true);\n          }\n        }, [minDate, initialized]);\n\n        const isPastDate = (d) => {\n          return (\n            d.getDate() < now.getDate() &#038;&#038;\n            d.getMonth() === now.getMonth() &#038;&#038;\n            d.getFullYear() === now.getFullYear()\n          );\n        };\n\n        const chunkSize = 11;\n        const totalDays = moment(maxDate).diff(moment(minDate), 'days') + 1;\n        const canScroll = totalDays > chunkSize;\n\n        \/\/ loop whole month and keep in memo to save 1ms per time\n        const month = useMemo(() => {\n          const m = [];\n          let d = new Date(startDate);\n\n          for (let i = 0; i < chunkSize; i++) {\n            const shouldByPassDate =\n              isPastDate(d) ||\n              (minDate &#038;&#038; moment(d).isBefore(moment(minDate), \"day\")) ||\n              (maxDate &#038;&#038; moment(d).isAfter(moment(maxDate), \"day\"));\n\n            if (!shouldByPassDate) {\n              m.push(new Date(d));\n            }\n            d.setDate(d.getDate() + 1);\n          }\n\n          return m;\n        }, [startDate, minDate, maxDate]);\n\n        const isAtLeftBoundary = !minDate ? false : startDate <= minDate;\n        const isAtRightBoundary = !maxDate ? false : moment(startDate).add(chunkSize, 'days').isAfter(maxDate);\n        const disablePrevMonth = minDate ? moment(showDate).startOf('month').isSameOrBefore(moment(minDate).startOf('month')) : false;\n        const disableNextMonth = maxDate ? moment(showDate).startOf('month').isSameOrAfter(moment(maxDate).startOf('month')) : false;\n\n        const canShowModal = (e) => {\n          return (\n            e.scrollLeft <= 0 &#038;&#038;\n            showDate.getMonth() === now.getMonth() &#038;&#038;\n            showDate.getFullYear() === now.getFullYear() &#038;&#038;\n            !!shouldBypassDates &#038;&#038;\n            NO_BYPASSED_DAYS > 0\n          );\n        };\n\n        const goRight = () => {\n          const newStartDate = new Date(startDate);\n          newStartDate.setDate(startDate.getDate() + 11);\n          setStartDate(newStartDate);\n\n          if (newStartDate.getMonth() !== startDate.getMonth()) {\n            setShowDate(newStartDate);\n          }\n        };\n\n        const goLeft = (e) => {\n          const today = new Date();\n          today.setHours(0, 0, 0, 0);\n\n          const newStartDate = new Date(startDate);\n          newStartDate.setDate(startDate.getDate() - 11);\n\n          if (newStartDate < today) {\n            setStartDate(today);\n          } else {\n            setStartDate(newStartDate);\n          }\n\n          if (newStartDate.getMonth() !== startDate.getMonth()) {\n            setShowDate(newStartDate);\n          }\n        };\n\n        const onPressLeft = () => {\n          let e = containerRef.current;\n          if (canShowModal(e)) {\n            showDateModal();\n          } else {\n            goLeft(e);\n          }\n        };\n\n        const canGoPastMonth =\n          (!(\n            minDate &&\n            minDate.getMonth() === showDate.getMonth() &&\n            minDate.getFullYear() === showDate.getFullYear()\n          ) &&\n            showDate.getMonth() > now.getMonth()) ||\n          showDate.getFullYear() > now.getFullYear();\n\n        const handleScroll = () => {\n          if (!containerRef.current) return;\n          const { scrollLeft, scrollWidth, clientWidth } = containerRef.current;\n\n          if (scrollLeft === 0) {\n            const newShowDate = new Date(showDate);\n            newShowDate.setMonth(newShowDate.getMonth() - 1);\n            setShowDate(newShowDate);\n          } else if (scrollLeft + clientWidth >= scrollWidth) {\n            const newShowDate = new Date(showDate);\n            newShowDate.setMonth(newShowDate.getMonth() + 1);\n            setShowDate(newShowDate);\n          }\n        };\n\n        useEffect(() => {\n          const container = containerRef.current;\n          if (container) {\n            container.addEventListener(\"scroll\", handleScroll);\n          }\n          return () => {\n            if (container) {\n              container.removeEventListener(\"scroll\", handleScroll);\n            }\n          };\n        }, [showDate]);\n\n        const isCurrentMonth = (day) => day.getMonth() === showDate.getMonth();\n\n        const days = useMemo(() => month, [month]);\n        \/\/console.log(\"Dates g\u00e9n\u00e9r\u00e9es :\", days);\n\n        const handlePrevMonth = () => {\n          const newShowDate = new Date(showDate);\n          newShowDate.setMonth(newShowDate.getMonth() - 1);\n          if (minDate && newShowDate < minDate) return;\n          if (newShowDate < now) return;\n          setShowDate(newShowDate);\n          setStartDate(new Date(newShowDate.getFullYear(), newShowDate.getMonth(), 1));\n          containerRef.current.scrollLeft = 0;\n        };\n\n        const handleNextMonth = () => {\n          const newShowDate = new Date(showDate);\n          newShowDate.setMonth(newShowDate.getMonth() + 1);\n          setShowDate(newShowDate);\n          setStartDate(new Date(newShowDate.getFullYear(), newShowDate.getMonth(), 1));\n          containerRef.current.scrollLeft = 0;\n        };\n\n        return (\n          <div className=\"bg-white pb-2\">\n            <div className=\"d-flex flex-wrap flex-row align-items-baseline justify-content-center px-3 py-3 bg-primary\">\n              {canGoPastMonth && !disablePrevMonth && (\n                <Button\n                  onClick={disableNavigation ? undefined : handlePrevMonth}\n                  disabled={disableNavigation || disablePrevMonth}\n                  className=\"bg-white\"\n                >\n                  <i className=\"fas fa-chevron-left text-primary fs-0.75 chevron\" \/>\n                <\/Button>\n              )}\n              <div className=\"h4 text-white px-3\">\n                {showDate.toLocaleString(\"fr-fr\", {\n                  month: \"long\",\n                  year: \"numeric\",\n                })}\n              <\/div>\n              {!disableNextMonth && (\n                <Button\n                  onClick={disableNavigation ? undefined : handleNextMonth}\n                  disabled={disableNavigation || disableNextMonth}\n                  className=\"bg-white\"\n                >\n                  <i className=\"fas fa-chevron-right text-primary fs-0.75 chevron\" \/>\n                <\/Button>\n              )}\n            <\/div>\n            <div className=\"d-flex align-items-center \">\n              <Button\n                onClick={disableNavigation ? undefined : onPressLeft}\n                disabled={disableNavigation || isAtLeftBoundary}\n                className=\"mx-2 mx-sm-3 mt-3 position-relative\"\n              >\n                <i className=\"fas fa-chevron-left fs-0.75\" \/>\n              <\/Button>\n              <div\n                className=\"scrolling-wrapper row flex-nowrap mt-3 py-2 mx-0 mx-sm-2\"\n                ref={containerRef}\n              >\n              {days.map((day) => {\n                  const isSelectedDate =\n                    selectedDate &&\n                    selectedDate.getDate() === day.getDate() &&\n                    selectedDate.getMonth() === day.getMonth() &&\n                    selectedDate.getFullYear() === day.getFullYear();\n\n                  const highlightSelectedDate = isSelectedDate;\n                  return (\n                    <div\n                      key={day}\n                      className={`hl-day ${isCurrentMonth(day) ? \"\" : \"text-muted custom-highlight\"}`}\n                      ref={isSelectedDate ? currentDayRef : null}\n                    >\n                      <Button\n                        onClick={() => onChange(day)}\n                        className={`day hl-bc0 border-0 p-0`}\n                        variant={highlightSelectedDate ? \"primary\" : \"light\"}\n                      >\n                        <div className=\"h-3 day-font\">{day.getDate()}<\/div>\n                        <div className=\"h-6 day-font d-flex justify-content-center\">\n                          {weekDays[day.getDay()]}\n                        <\/div>\n                      <\/Button>\n                    <\/div>\n                  );\n                })}\n              <\/div>\n              <div className=\"d-flex justify-content-end flex-fill\">\n                <Button\n                  onClick={disableNavigation ? undefined : goRight}\n                  disabled={disableNavigation || isAtRightBoundary}\n                  className=\"mx-2 mx-sm-3 mt-3 position-relative\"\n                >\n                  <i className=\"fas fa-chevron-right fs-0.75\" \/>\n                <\/Button>\n              <\/div>\n            <\/div>\n          <\/div>\n        );\n      };\n\n      const FormComponent = (props) => {\n        const { component, required, onChange, disabled, defaultValue, value } =\n          props;\n        const [val, setVal] = useState(defaultValue || value || \"\");\n        let myRef = null;\n        const setRef = (ref) => {\n          myRef = ref;\n        };\n        useEffect(() => {\n          if (defaultValue || value) {\n            setVal(defaultValue || value || \"\");\n          }\n        }, [defaultValue, value]);\n        const onValueChange = (value, actionMeta) => {\n          onChange(value, actionMeta);\n          setVal(value.target.value);\n        };\n        let Component = component;\n        return (\n          <div className=\"position-relative\">\n            <Component {...props} ref={setRef} onChange={onValueChange} \/>\n            <Form.Control\n              tabIndex={-1}\n              autoComplete=\"off\"\n              style={{\n                opacity: 0,\n                width: \"100%\",\n                height: 0,\n                bottom: \"-5px\",\n                position: \"absolute\",\n              }}\n              value={val}\n              onChange={() => {}}\n              onFocus={() => myRef.focus && myRef.focus()}\n              required={required}\n              disabled={disabled}\n            \/>\n          <\/div>\n        );\n      };\n      const DropDown = (props) => {\n        const {\n          options,\n          onChange,\n          disabled,\n          md = 4,\n          type,\n          labelparam = \"label\",\n          selectparam = \"value\",\n          className = \"my-4\",\n          required = true,\n        } = props;\n        return (\n          <Col md={md} className={className}>\n            <FormComponent\n              component={Form.Select}\n              type={type}\n              onChange={onChange}\n              required\n              disabled={disabled}\n              style={{\n                height: \"47px\",\n                borderRadius: \"2px\",\n                backgroundColor: \"#FAFAFA\",\n              }}\n              {...props}\n            >\n              {options.map((option) => (\n                <option\n                  value={option[selectparam]}\n                  key={option[labelparam] + option[selectparam]}\n                >\n                  {option[labelparam]}\n                <\/option>\n              ))}\n            <\/FormComponent>\n          <\/Col>\n        );\n      };\n\n      const PlacesInput = (props) => {\n        const {\n          onChange,\n          md = 4,\n          id,\n          required,\n          disabled,\n          value,\n          onChangeValue,\n        } = props;\n\n        useEffect(() => {\n          \/\/center around montreal\n          const center = { lat: 45.49959233117481, lng: -73.56980872646967 };\n          const defaultBounds = {\n            north: center.lat + 1.0,\n            south: center.lat - 1.0,\n            east: center.lng + 1.0,\n            west: center.lng - 1.0,\n          };\n\n          const autocomplete = new google.maps.places.Autocomplete(\n            document.getElementById(id),\n            {\n              language: \"fr-CA\",\n              fields: [\n                \"name\",\n                \"geometry.location\",\n                \"place_id\",\n                \"formatted_address\",\n                \"address_components\",\n              ],\n              componentRestrictions: {\n                country: [\"ca\"],\n              },\n              bounds: defaultBounds,\n              strictBounds: false,\n              radius: \"1000\",\n            }\n          );\n          google.maps.event.addListener(autocomplete, \"place_changed\", () => {\n            onChange(autocomplete.getPlace());\n          });\n        }, []);\n        return (\n          <Col md={md} className=\"my-3\">\n            <Form.Control\n              id={id}\n              required={required}\n              type=\"text\"\n              className=\"form-control\"\n              placeholder=\"Recherchez votre adresse*\"\n              style={{\n                height: \"47px\",\n                borderRadius: \"2px\",\n                backgroundColor: \"#FAFAFA\",\n              }}\n              disabled={disabled}\n              value={value}\n              onChange={onChangeValue}\n              role=\"presentation\"\n              autoComplete=\"off\"\n            \/>\n          <\/Col>\n        );\n      };\n\n      const LocalizedDateInput = ({ ...props }) => {\n        return (\n          <SemanticUiCalendarReact.DateInput {...props} localization=\"fr\" \/>\n        );\n      };\n\n      const DateInput = React.memo((props) => {\n        const {\n          onChange,\n          id,\n          placeholder,\n          md = 4,\n          style = {},\n          required = true,\n          max,\n          min,\n          value,\n          label = \"Select Date\",\n          dateFormat = \"YYYY-MM-DD\",\n          useInitialDate = true,\n        } = props;\n        const [dateKey, setDateKey] = useState(0);\n        const [canHandleBlur, setCanHandleBlur] = useState(true);\n        moment.locale(\"fr\");\n        const reset = (resetBlurHandler) => {\n          onChange(\"\", { value: undefined });\n          setTimeout(() => {\n            setDateKey(dateKey + 1);\n          }, 50);\n          setCanHandleBlur(!resetBlurHandler);\n        };\n\n        useEffect(() => {\n          reset();\n        }, [max, min]);\n\n        const onChangeDate = (value, actionMeta) => {\n          onChange(value, actionMeta);\n        };\n\n        const checkTypedDate = () => {\n          if (value) {\n            if (value.length === dateFormat.length) {\n              const date = moment(value, dateFormat);\n              if (date.isValid()) {\n                if (\n                  (!max && !min) ||\n                  (max && min && !date.isAfter(max) && !date.isBefore(min)) ||\n                  (max && !min && !date.isAfter(max)) ||\n                  (min && !max && !date.isBefore(min))\n                ) {\n                  onChange(\"\", { value: date.format(dateFormat) });\n                } else {\n                  reset(true);\n                }\n              } else {\n                reset(true);\n              }\n            } else {\n              reset(true);\n            }\n          } else {\n            reset(true);\n          }\n        };\n\n        return (\n          <Col md={md} className=\"my-3 text-start\">\n            <span style={{ position: \"relative\", bottom: 19 }}>{label}<\/span>\n            <Form.Control\n              key={id + dateKey}\n              id={id}\n              className=\"form-control border-0 p-0\"\n              placeholder={placeholder || dateFormat}\n              required={required}\n              onChange={onChangeDate}\n              style={{\n                height: \"47px\",\n                borderRadius: \"2px\",\n                width: \"100%\",\n                bottom: 19,\n                ...style,\n              }}\n              as={LocalizedDateInput}\n              value={value}\n              popupPosition=\"bottom center\"\n              closable\n              hideMobileKeyboard\n              autoComplete=\"off\"\n              minDate={min &#038;&#038; moment(min, dateFormat)}\n              maxDate={max &#038;&#038; moment(max, dateFormat)}\n              dateFormat={dateFormat}\n              initialDate={useInitialDate &#038;&#038; min &#038;&#038; moment(min, dateFormat)}\n              onBlur={() => {\n                if (canHandleBlur) {\n                  checkTypedDate();\n                }\n              }}\n              onFocus={() => {\n                setCanHandleBlur(true);\n              }}\n            \/>\n          <\/Col>\n        );\n      });\n\n      const Input = (props) => {\n        const {\n          options,\n          onChange,\n          id,\n          placeholder,\n          minLength,\n          maxLength,\n          type = \"text\",\n          pattern,\n          md = 4,\n          style = {},\n          as,\n          required = true,\n          max,\n          min,\n          value,\n          onKeyDown,\n          hasError,\n          error,\n        } = props;\n\n        const isValid = () => {\n          const input = document.getElementById(id);\n          if (input && input.value !== \"\") {\n            return input.checkValidity();\n          }\n          return true;\n        };\n\n        const errorMessage = () => {\n          const input = document.getElementById(id);\n          if (input && input.value !== \"\") {\n            return input.validationMessage;\n          }\n          return \"\";\n        };\n\n        return (\n          <Col md={md} className=\"my-3\">\n            <Form.Control\n              id={id}\n              type={type}\n              className={`form-control ${hasError ? \"text-danger\" : \"\"}`}\n              placeholder={placeholder}\n              required={required}\n              onChange={onChange}\n              minLength={minLength}\n              maxLength={maxLength}\n              pattern={pattern}\n              style={{\n                height: \"47px\",\n                borderRadius: \"2px\",\n                backgroundColor: \"#FAFAFA\",\n                ...style,\n              }}\n              as={as}\n              max={max}\n              min={min}\n              value={value}\n              onKeyDown={onKeyDown}\n              isInvalid={!isValid()}\n            \/>\n            <Form.Control.Feedback type={isValid() ? \"valid\" : \"invalid\"}>\n              {errorMessage()}\n            <\/Form.Control.Feedback>\n            {!!error && hasError && (\n              <div className=\"text-start text-danger\">{error}<\/div>\n            )}\n          <\/Col>\n        );\n      };\n\n      const Radio = (props) => {\n        const { label, onClick, value, index } = props;\n        return (\n          <div key={`default-Radio}`} className=\"mb-3 text-start\">\n            <Form.Check\n              type={\"radio\"}\n              name=\"locations\"\n              value={value}\n              label={label}\n              onClick={onClick}\n              required\n              defaultChecked={!index}\n            \/>\n          <\/div>\n        );\n      };\n\n      const Checkbox = (props) => {\n        const { label, onClick, value, required, defaultChecked } = props;\n        return (\n          <div className=\"text-start d-flex my-2\">\n            <Form.Check\n              name=\"sameAsContact\"\n              required={required}\n              defaultChecked={defaultChecked}\n              onClick={onClick}\n              value={value}\n            \/>\n            <span className=\"px-3\" style={{ color: \"#6D757D\" }}>\n              {label}\n            <\/span>\n          <\/div>\n        );\n      };\n\n      const TermsConditions = () => {\n        return (\n          <div\n            key={`default-terms`}\n            className=\"text-start d-flex my-2\"\n            style={{ color: \"#0058a4\" }}\n          >\n            <Form.Check name=\"terms\" required \/>\n            <a\n              href={`https:\/\/cliniquevoyageur.ca\/termes-et-conditions-pour-les-tests-virtuels-de-covid\/?lang=fr`}\n              target=\"_blank\"\n              className=\"px-3\"\n            >\n              {\"Je suis d'accord avec les termes et conditions\"}\n            <\/a>\n          <\/div>\n        );\n      };\n\n      const LoadingView = () => (\n        <div className=\"spinner-cont d-flex  h-100 justify-content-center align-items-center\">\n          <Spinner animation=\"border\" id=\"loading-spinner\" \/>\n        <\/div>\n      );\n\n      let AppointmentReasons = [{ label: \"Reason For Appointment\", value: \"\" }];\n\n      const queryString = window.location.search;\n      const urlParams = new URLSearchParams(queryString);\n\n      const initialTBDateTime = urlParams.get('initialTBDateTime');\n      const minDateParam = urlParams.get('minDate'); \n      const maxDateParam = urlParams.get('maxDate');\n\n      const initialUTC = moment.utc(initialTBDateTime);\n      const initialEST = initialUTC.tz('America\/New_York');\n      \/\/ console.log(\"Initial EST:\", initialEST && initialEST.format());\n      \n      const minDate = minDateParam ? moment(minDateParam, \"DD-MM-YYYY\").toDate() : null;\n      const maxDate = maxDateParam ? moment(maxDateParam, \"DD-MM-YYYY\").toDate() : null;\n      \/\/ console.log(\"Min date:\", minDate);\n      \/\/ console.log(\"Max date:\", maxDate);\n      \n      \n      const getAgeLabel = (months) => {\n        if (months >= 12) {\n          const years = months \/ 12;\n          return `${years}${years > 1 ? ' ans' : ' an'}`;\n        }\n        return `${months} mois`;\n      };\n\n      let TbReading =\n        urlParams.get(\"TbReading\") &&\n        urlParams.get(\"TbReading\").toLowerCase() === \"true\";\n      console.log(\"TbReading = \" + TbReading);\n      if (TbReading) {\n        console.log(\"TbReading\");\n        AppointmentReasons = [\n          { \n            label: \"Reason For Appointment\", \n            value: \"\",\n            isVirtual: false, \n            isSinglePatientService: false,\n            minimumAgeMonths: 6,\n            minimunAgeText: \"\"  \n          },\n          {\n            label: \"Test cutan\u00e9 TB \u2013 Rendez-vous de lecture\",\n            value: \"TB Skin Test Reading\",\n            isVirtual: false, \n            isSinglePatientService: false,\n            minimumAgeMonths: 60,\n            get minimunAgeText() {\n              const ageLabel = getAgeLabel(this.minimumAgeMonths);\n              return `Il est important de noter que le Test Cutan\u00e9 TB \u2013 Rendez-vous initial et Test Cutan\u00e9 TB \u2013 Rendez-vous de lecture sont offerts aux enfants \u00e2g\u00e9s de ${ageLabel} et plus. Si votre enfant a moins de ${ageLabel}, veuillez choisir une date de rendez-vous ult\u00e9rieure, lorsqu\u2019il ou elle aura plus de ${ageLabel}, ou appelez-nous au 1-888-224-8809.`;\n            } \n          },\n        ];\n      } else {\n        AppointmentReasons = [\n          {\n            label: \"Raison du rendez-vous\",\n            value: \"\",\n            isVirtual: false,\n            isSinglePatientService: false,\n            minimumAgeMonths: 6,\n            minimunAgeText: \"\"\n          },\n          {\n            label: \"Consultation Vaccination Voyage\",\n            value: \"Travel Consult\",\n            isVirtual: false,\n            isSinglePatientService: false,\n            minimumAgeMonths: 6,\n            get minimunAgeText() {\n              const ageLabel = getAgeLabel(this.minimumAgeMonths);\n              return `Il est important de noter que nous vaccinons les enfants \u00e2g\u00e9s de ${ageLabel} et plus. Si votre enfant a moins de ${ageLabel}, veuillez choisir une date de rendez-vous ult\u00e9rieure, lorsqu\u2019il ou elle aura plus de ${ageLabel}, ou appelez-nous au 1-888-224-8809.`;\n            }\n          },\n          {\n            label: \"Consultation Vaccination Voyage Virtuel\",\n            value: \"Telehealth Consultation\",\n            isVirtual: true,\n            isSinglePatientService: false,\n            minimumAgeMonths: 6,\n            get minimunAgeText() {\n              const ageLabel = getAgeLabel(this.minimumAgeMonths);\n              return `Il est important de noter que nous vaccinons les enfants \u00e2g\u00e9s de ${ageLabel} et plus. Si votre enfant a moins de ${ageLabel}, veuillez choisir une date de rendez-vous ult\u00e9rieure, lorsqu\u2019il ou elle aura plus de ${ageLabel}, ou appelez-nous au 1-888-224-8809.`;\n            }\n          },\n          {\n            label: \"Vaccin de rappel\",\n            value: \"Booster\",\n            isVirtual: false, \n            isSinglePatientService: false,\n            minimumAgeMonths: 6,\n            get minimunAgeText() {\n              const ageLabel = getAgeLabel(this.minimumAgeMonths);\n              return `Il est important de noter que nous vaccinons les enfants \u00e2g\u00e9s de ${ageLabel} et plus. Si votre enfant a moins de ${ageLabel}, veuillez choisir une date de rendez-vous ult\u00e9rieure, lorsqu\u2019il ou elle aura plus de ${ageLabel}, ou appelez-nous au 1-888-224-8809.`;\n            }\n          },\n          { \n            label: \"Vaccin hors-voyage\", \n            value: \"Private Vaccine\",\n            isVirtual: false, \n            isSinglePatientService: false,\n            minimumAgeMonths: 6,\n            get minimunAgeText() {\n              const ageLabel = getAgeLabel(this.minimumAgeMonths);\n              return `Il est important de noter que nous vaccinons les enfants \u00e2g\u00e9s de ${ageLabel} et plus. Si votre enfant a moins de ${ageLabel}, veuillez choisir une date de rendez-vous ult\u00e9rieure, lorsqu\u2019il ou elle aura plus de ${ageLabel}, ou appelez-nous au 1-888-224-8809.`;\n            } \n          },\n          {\n            label: \"Test cutan\u00e9 TB - Rendez-vous initial\",\n            value: \"TB Skin Test Initial Appointment\",\n            isVirtual: false, \n            isSinglePatientService: false,\n            minimumAgeMonths: 60,\n            get minimunAgeText() {\n              const ageLabel = getAgeLabel(this.minimumAgeMonths);\n              return `Il est important de noter que le Test cutan\u00e9 TB \u2013 Rendez-vous initial et Test cutan\u00e9 TB \u2013 Rendez-vous de lecture \u2013 sont offerts aux enfants \u00e2g\u00e9s de ${ageLabel} et plus. Si votre enfant a moins de ${ageLabel}, veuillez choisir une date de rendez-vous ult\u00e9rieure, lorsqu\u2019il ou elle aura plus de ${ageLabel}, ou appelez-nous au 1-888-224-8809.`;\n            } \n          },\n          {\n            label: \"Test Rapide de Streptocoque\",\n            value: \"Rapid Strep Test\",\n            isVirtual: false, \n            isSinglePatientService: false,\n            minimumAgeMonths: 36,\n            get minimunAgeText() {\n              const ageLabel = getAgeLabel(this.minimumAgeMonths);\n              return `Il est important de noter que le Test Rapide de Streptocoque est offert aux enfants \u00e2g\u00e9s de ${ageLabel} et plus. Si votre enfant a moins de ${ageLabel}, veuillez choisir une date de rendez-vous ult\u00e9rieure, lorsqu\u2019il ou elle aura plus de ${ageLabel}, ou appelez-nous au 1-888-224-8809.`;\n            } \n          },\n          {\n            label: \"Bilan pr\u00e9-biologique\",\n            value: \"Pre-Biological Assessment\",\n            isVirtual: false, \n            isSinglePatientService: false,\n            minimumAgeMonths: 6,\n            get minimunAgeText() {\n              const ageLabel = getAgeLabel(this.minimumAgeMonths);\n              return `Il est important de noter que le Bilan Pr\u00e9-Biologique est offert aux enfants \u00e2g\u00e9s de ${ageLabel} et plus. Si votre enfant a moins de ${ageLabel}, veuillez choisir une date de rendez-vous ult\u00e9rieure, lorsqu\u2019il ou elle aura plus de ${ageLabel}, ou appelez-nous au 1-888-224-8809.`;\n            }  \n          },\n          {\n            label: \"\u00c9valuation Virtuelle de l'Herp\u00e8s Labial\",\n            value: \"Cold Sore\",\n            isVirtual: true, \n            isSinglePatientService: true,\n            minimumAgeMonths: 6,\n            get minimunAgeText() {\n              const ageLabel = getAgeLabel(this.minimumAgeMonths);\n              return `Il est important de noter que les \u00c9valuations Virtuelles de l\u2019Herp\u00e8s Labial sont offertes aux enfants \u00e2g\u00e9s de ${ageLabel} et plus. Si votre enfant a moins de ${ageLabel}, veuillez choisir une date de rendez-vous ult\u00e9rieure, lorsqu\u2019il ou elle aura plus de ${ageLabel}, ou appelez-nous au 1-888-224-8809.`;\n            } \n          },\n\/**\n          {\n            label: \"Test Sanguin\",\n            value: \"Blood Test\",\n            isVirtual: false, \n            isSinglePatientService: true,\n            minimumAgeMonths: 6,\n            get minimunAgeText() {\n              const ageLabel = getAgeLabel(this.minimumAgeMonths);\n              return `Il est important de noter que les Tests Sanguins sont offerts aux enfants \u00e2g\u00e9s de ${ageLabel} et plus. Si votre enfant a moins de ${ageLabel}, veuillez choisir une date de rendez-vous ult\u00e9rieure, lorsqu\u2019il ou elle aura plus de ${ageLabel}, ou appelez-nous au 1-888-224-8809.`;\n            } \n          },\n          **\/\n          {\n            label: \"Consultation Virtuelle pour une Piq\u00fbre de Tique\",\n            value: \"Tick Bite Exposure\",\n            isVirtual: true, \n            isSinglePatientService: true,\n            minimumAgeMonths: 96,\n            get minimunAgeText() {\n              const ageLabel = getAgeLabel(this.minimumAgeMonths);\n              return `Il est important de noter que les Consultations Virtuelles pour une Piq\u00fbre de Tique sont offertes aux enfants \u00e2g\u00e9s de ${ageLabel} et plus. Si votre enfant a moins de ${ageLabel}, veuillez choisir une date de rendez-vous ult\u00e9rieure, lorsqu\u2019il ou elle aura plus de ${ageLabel}, ou appelez-nous au 1-888-224-8809.`;\n            } \n          } \n\n        ];\n      }\n\n      const NumberOfPeople = [\n        { label: \"Nombre de patients\", value: \"\" },\n        { label: \"Un\", value: \"1\" },\n        { label: \"Deux\", value: \"2\" },\n        { label: \"Trois\", value: \"3\" },\n        { label: \"Quatre\", value: \"4\" },\n        { label: \"Cinq\", value: \"5\" },\n      ];\n\n      const LanguageOptions = [\n        \/\/ { label: \"Langue\", value: \"\" },\n        { label: \"Fran\u00e7ais\", value: \"french\" },\n        { label: \"Anglais\", value: \"english\" },\n      ];\n      const STANDARD_PROGRESS_LABELS = [\n        \"S\u00e9lectionnez votre heure\",\n        \"Fournissez vos coordonn\u00e9es\",\n        \"Compl\u00e9tez votre achat\",\n      ];\n\n      const ONLINE_PROGRESS_LABELS = [\n        \"S\u00e9lectionnez votre heure\",\n        \"Fournissez vos coordonn\u00e9es\",\n        \"Compl\u00e9tez votre achat\",\n      ];\n\n      const ErrorView = ({ error, showErrorMessage }) => {\n        if (showErrorMessage) {\n          return <div className=\"d-flex align-self-center\">{error}<\/div>;\n        }\n        const renderErrorMessage = () => {\n          switch (error) {\n            case \"1\":\n              return (\n                <div>\n                  \u00e0\u2030chec du paiement, veuillez utiliser une carte valide.\n                <\/div>\n              );\n            default:\n              return (\n                <div>\n                  Il semble qu'il y ait eu une erreur s'il vous pla\u00eet appelez{\" \"}\n                  <a href={`tel:\/(438) 266-0855`}>(438) 266-0855<\/a>\n                <\/div>\n              );\n          }\n        };\n        return (\n          <div className=\"d-flex align-self-center\">{renderErrorMessage()}<\/div>\n        );\n      };\n      const LocationMap = (props) => {\n        const {\n          location,\n          serviceId,\n          selectedDate,\n          onSelectDate,\n          onSelectSlot,\n          selectedLocationId,\n          selectedTime,\n          refetch,\n          isRemoteService,\n          isTelehealthCovidTest,\n          isTelehealthConsultation,\n          minDate,\n          maxDate,\n          time,\n          isFirstInitialTbConfirmed,\n          setIsFirstInitialTbConfirmed,\n          firstTbInitialAppointment,\n          language,\n          serviceType={serviceType}\n        } = props;\n        \n        const distance = location.geolocation && location.geolocation.distance;\n        const [times, setTimeSlots] = useState([]);\n        const [availableExpert, setAvailableExpert] = useState({});\n        const [allAvailableExperts, setAllAvailableExperts] = useState();\n        const [filteredExperts, setFilteredExperts] = useState({});\n        const [isLoadingSlots, setIsLoadingSlots] = useState({});\n        const [isLoadingAllSlots, setIsLoadingAllSlots] = useState(false);\n        const [showError, setError] = useState(false);\n        const [sortedDates, setSortedDates] = useState([]);\n        const [virtualLocationId, setVirtualLocationId] = useState(null);\n\n        const mainAction = async (date) => {\n          const response = await getAvailabilities({\n            locationId: location.id,\n            serviceId,\n            selectedDate: date,\n          });\n          if (date) {\n            setAvailableExpert(response.content.availableSlots || {});\n          } else {\n            setAllAvailableExperts(response.content.availableSlots);\n          }\n        };\n\n        const virtualAction = async (date) => {\n          console.log('langiuage:',language);\n          console.log('selectedDate:',date);\n          const response = await getVirtualAvailabilities({\n            serviceId,\n            selectedDate: date,\n            language: language,\n          });\n          if (date) {\n            setAvailableExpert(response || {});\n          } else {\n            setAllAvailableExperts(response);\n          }\n          const experts = Object.values(response).filter((val) => val.length);\n          const locationId =\n            experts[0] && experts[0][0] && experts[0][0].locationId;\n          setVirtualLocationId(locationId);\n        };\n\n        const loadCurrentDateAvailabilities = async (date) => {\n          setIsLoadingSlots((prevState) => ({\n            ...prevState,\n            [date]: true,\n          }));\n          setError(false);\n          try {\n            if (\n              isRemoteService ||\n              isTelehealthCovidTest ||\n              isTelehealthConsultation\n            ) {\n              await virtualAction(date);\n            } else {\n              await mainAction(date);\n            }\n          } catch (err) {\n            setError(true);\n          }\n          setIsLoadingSlots((prevState) => ({\n            ...prevState,\n            [date]: false,\n          }));\n        };\n\n        const loadAllAvailabilities = async () => {\n          setIsLoadingAllSlots(true);\n          if (\n            isRemoteService ||\n            isTelehealthCovidTest ||\n            isTelehealthConsultation\n          ) {\n            await virtualAction();\n          } else {\n            await mainAction();\n          }\n          setIsLoadingAllSlots(false);\n        };\n        useEffect(() => {\n          if (!allAvailableExperts) {\n            loadCurrentDateAvailabilities(selectedDate);\n          }\n        }, [location, serviceId, selectedDate, allAvailableExperts, refetch]);\n\n        useEffect(() => {\n          loadAllAvailabilities();\n        }, [location, serviceId, refetch]);\n\n        const sortDates = (dates) => {\n          const sorted = Object.keys(dates).sort(\n            (a, b) =>\n              moment(a, \"D_M_yyyy\").valueOf() - moment(b, \"D_M_yyyy\").valueOf()\n          );\n          setSortedDates(sorted);\n        };\n\n        let mergedDates = useMemo(() => {\n          let dates = {};\n          let experts = {};\n          const preProcessedExpert = allAvailableExperts || availableExpert;\n          for (let key in preProcessedExpert) {\n            let expert = preProcessedExpert[key];\n            expert = removeBookedSlot(expert);\n            experts[key] = expert;\n          }\n          setFilteredExperts(experts);\n          if (preProcessedExpert) {\n            let mergedExperts = _(experts).toArray().flatten().value();\n            mergedExperts.forEach((value) => {\n              const existingSlots = dates[value.strDate]\n                ? dates[value.strDate].slots\n                : {};\n              dates[value.strDate] = {\n                ...value,\n                slots: [...existingSlots, ...value.slots],\n              };\n            });\n          }\n          sortDates(dates);\n          return dates;\n        }, [availableExpert, allAvailableExperts]);\n\n        const getNextAvailableDate = useCallback(() => {\n          let val = sortedDates.find((value) => {\n            if (!mergedDates[value].slots.length) return false;\n            let isSameOrBeforeMaxDate = true;\n            if (maxDate) {\n              isSameOrBeforeMaxDate = moment(value, \"D_M_yyyy\").isSameOrBefore(\n                maxDate\n              );\n            }\n            return (\n              isSameOrBeforeMaxDate &&\n              moment(value, \"D_M_yyyy\").isAfter(\n                moment(selectedDate, \"D_M_yyyy\")\n              )\n            );\n          });\n          const date = moment(val, \"D_M_yyyy\").toDate();\n          return val ? date : null;\n        }, [sortedDates, selectedDate, maxDate]);\n\n        const onSelectParentSlot = (e) => {\n          setParentSlot(e.target.value);\n          setTimeSlots([]);\n        };\n\n        const onSelect = async (time) => {\n          for (let key in filteredExperts) {\n            const selectedDateSlot = filteredExperts[key].find(\n              (val) => val.strDate == selectedDate\n            );\n            const found =\n              selectedDateSlot &&\n              selectedDateSlot.slots.find((slot) => slot.slot === time);\n            if (found) {\n              let loc = location.id || virtualLocationId;\n              let isVirtual = false;\n              if (virtualLocationId) {\n                isVirtual = true;\n              }\n              onSelectSlot(loc, time, key, isVirtual);\n              break;\n            }\n          }\n        };\n\n        const renderMap = () => (\n          <div>\n            <div className=\"pb-1 text-start locationName\">{location.name}<\/div>\n            <div className=\"text-start locationAddress\">\n              <i className=\"fas fa-map-marked-alt\"><\/i> {location.street},{\" \"}\n              {location.city}, {location.province}, {location.postalCode}\n            <\/div>\n            <div className=\"text-start locationPhone\">\n              <i className=\"fas fa-phone\"><\/i>{\" \"}\n              <a href={`tel:\/${location.phone}`}>{location.phone}<\/a>\n            <\/div>\n            {distance && (\n              <div className=\"pb-1 text-start\">\n                <i className=\"fas fa-route\"><\/i> {distance.text} away\n              <\/div>\n            )}\n            <div\n              id=\"map-container-google-2\"\n              className=\"z-depth-1-half map-container mb-3\"\n              style={{ height: `250px` }}\n            >\n              <iframe\n                src={`https:\/\/www.google.com\/maps\/embed\/v1\/place?key=AIzaSyB5DtRtOTmliqRm1yRgblVnEVDTxJTxdV8&#038;q=${location.street}+${location.city}+${location.province}`}\n                frameBorder=\"0\"\n                style={{ border: 0 }}\n                allowFullScreen\n              \/>\n            <\/div>\n          <\/div>\n        );\n\n        const renderRemoteServiceIntro = () => (\n          <div className=\"p-3 py-5\">\n            <Image\n              style={{\n                height: \"135px\",\n                width: \"135px\",\n                marginBottom: \"20px\",\n                display: \"none\",\n              }}\n              src={\"\/step2.png\"}\n            \/>\n            <div className=\"text-start\">\n              Une fois votre rendez-vous pris, nous vous enverrons un lien vers\n              votre salle de consultation virtuelle.\n            <\/div>\n          <\/div>\n        );\n        return (\n          <div className=\"map-cont pb-3\">\n            <Row className=\"row entryRow\">\n              <Col lg={4}>\n                {isRemoteService ? renderRemoteServiceIntro() : renderMap()}\n              <\/Col>\n              <Col lg={8}>\n                {isLoadingSlots[selectedDate] ? (\n                  <LoadingView \/>\n                ) : (\n                  <div className=\"pt-3 h-100 justify-content-center d-flex\">\n                    {!showError ? (\n                      <TimeSlots\n                        slots={\n                          mergedDates &#038;&#038;\n                          mergedDates[selectedDate] &#038;&#038;\n                          mergedDates[selectedDate].slots\n                        }\n                        onSelectTime={onSelect}\n                        locationIsActive={selectedLocationId === location.id}\n                        selectedTime={selectedTime}\n                        nextAvailableDate={getNextAvailableDate()}\n                        onSelectDate={onSelectDate}\n                        isLoadingAllSlots={isLoadingAllSlots}\n                        selectedDate={selectedDate}\n                        minDate={minDate}\n                        maxDate={maxDate}\n                        selectedLocationId={selectedLocationId}\n                        locationId={location.id}\n                        time={time}\n                        isFirstInitialTbConfirmed={isFirstInitialTbConfirmed}\n                        firstTbInitialAppointment={firstTbInitialAppointment}\n                        location={location}\n                        isVirtual={isRemoteService}\n                      \/>\n                    ) : (\n                      <ErrorView \/>\n                    )}\n                  <\/div>\n                )}\n              <\/Col>\n            <\/Row>\n          <\/div>\n        );\n      };\n\n      const TimeSlots = React.memo((props) => {\n        const {\n          slots,\n          onSelectTime,\n          locationIsActive,\n          selectedTime,\n          nextAvailableDate,\n          onSelectDate,\n          isLoadingAllSlots,\n          selectedDate,\n          minDate,\n          maxDate,\n          locationId,\n          selectedLocationId,\n          time,\n          isFirstInitialTbConfirmed,\n          firstTbInitialAppointment,\n          location,\n          isVirtual,\n        } = props;\n\n        \n        const isToday = useMemo(() => {\n          return moment(selectedDate, \"D_M_YYYY\").isSame(moment(), \"day\");\n        }, [selectedDate]);\n\n        const lessThen30MinutesFromNow = (slot) => {\n          const currentTime = moment();\n          const slotTime = moment(slot.name, \"hh:mm A\");\n          return slotTime.subtract(30, \"minutes\").isAfter(currentTime);\n        };\n\n\n        let slotsArray = useMemo(() => {\n          if (selectedLocationId != locationId) {\n            return (\n              (slots &&\n                _(slots)\n                  .uniqBy(\"slot\")\n                  .map((slot) => ({\n                    name: slot.slot.split(\"_\")[0],\n                    value: slot.slot,\n                  }))\n                  .sort(\n                    (a, b) =>\n                      new Date(\"1970\/01\/01 \" + a.name) -\n                      new Date(\"1970\/01\/01 \" + b.name)\n                  ).filter(isToday && isVirtual ? lessThen30MinutesFromNow : _.identity)\n                  .value()) ||\n              []\n            );\n          } else {\n            return (\n              (slots &&\n                _(slots)\n                  .uniqBy(\"slot\")\n                  .map((slot) => ({\n                    name: slot.slot.split(\"_\")[0],\n                    value: slot.slot,\n                  }))\n                  .sort(\n                    (a, b) =>\n                      new Date(\"1970\/01\/01 \" + a.name) -\n                      new Date(\"1970\/01\/01 \" + b.name)\n                  ).filter(isToday && isVirtual ? lessThen30MinutesFromNow : _.identity)\n                  .value()) ||\n              []\n            );\n          }\n        }, [\n          slots,\n          selectedLocationId,\n          locationId,\n          minDate,\n          selectedDate,\n          maxDate,\n        ]);\n\n        const modifiedSlots = useMemo(() => {\n          if (isFirstInitialTbConfirmed) {\n            const referenceTime =\n              firstTbInitialAppointment.slot &&\n              firstTbInitialAppointment.slot.split(\"_\")[0];\n            console.log(referenceTime);\n\n            \/\/ Array of times\n            const times = slotsArray;\n            \/\/ Your time string\n\n            \/\/ Parse input time string\n            const [hours, minutes] = referenceTime\n              .split(\":\")\n              .map((part) => parseInt(part));\n            let inputHour = hours;\n            if (referenceTime.includes(\"PM\") && hours !== 12) {\n              inputHour += 12;\n            } else if (referenceTime.includes(\"AM\") && hours === 12) {\n              inputHour = 0;\n            }\n\n            \/\/ Convert input time to Date object\n            const inputTime = new Date(2000, 0, 1, inputHour, minutes);\n\n            \/\/ Filter the array to get times after the input time\n            const filteredArray = slotsArray.filter((obj) => {\n              \/\/ Parse object's time string\n              const [objHours, objMinutes] = obj.name\n                .split(\":\")\n                .map((part) => parseInt(part));\n              let objHour = objHours;\n              if (obj.name.includes(\"PM\") && objHours !== 12) {\n                objHour += 12;\n              } else if (obj.name.includes(\"AM\") && objHours === 12) {\n                objHour = 0;\n              }\n\n              \/\/ Convert object's time to Date object\n              const objTime = new Date(2000, 0, 1, objHour, objMinutes);\n\n              \/\/ Compare the times\n              return selectedDate == moment(minDate).format(\"D_M_YYYY\")\n                ? objTime >= inputTime\n                : objTime <= inputTime;\n            });\n\n            return filteredArray;\n          }\n          return slotsArray;\n        }, [slotsArray, firstTbInitialAppointment, minDate, selectedDate]);\n\n        return !!modifiedSlots.length ? (\n          <div className=\"d-flex flex-wrap pb-3 align-content-start\">\n            {isLoadingAllSlots ? (\n              <LoadingView \/>\n            ) : (\n              modifiedSlots.map((slot, index) => {\n                const selected =\n                  locationIsActive && selectedTime === slot.value;\n                return (\n                  <Button\n                    onClick={() => onSelectTime(slot.value)}\n                    className={`m-1 p-1 time-slot ${selected && \"selected\"}`}\n                    variant={selected ? \"primary\" : \"outline-primary\"}\n                    key={index + slot.name}\n                  >\n                    {slot.name}\n                  <\/Button>\n                );\n              })\n            )}\n          <\/div>\n        ) : nextAvailableDate ? (\n          <Button\n            onClick={() => onSelectDate(nextAvailableDate)}\n            className={`m-1 mb-3 p-2 px-5 align-self-center`}\n            variant=\"primary\"\n          >\n            La premi\u00e8re date disponible est{\" \"}\n            {moment(nextAvailableDate).format(\"MMM DD\")} {\">>\"}\n          <\/Button>\n        ) : isLoadingAllSlots ? (\n          <div className=\"align-self-center\">\n            <div>Aucun rendez-vous disponible pour cette journ\u00e9e..<\/div>\n            <div>\n              Veuillez patienter pendant que nous trouvons le prochain jour\n              disponible...\n            <\/div>\n            <div className=\"py-3\">\n              <LoadingView \/>\n            <\/div>\n          <\/div>\n        ) : (\n          <div\n            className=\"d-flex align-self-center\"\n            style={{ color: \"#0058a4\" }}\n          >\n            Pas d'horaires \u00e0 venir disponibles.\n          <\/div>\n        );\n      });\n\n      const Step = ({ iconName, title, alt, description }) => (\n        <Col md={6} lg={3} className=\"my-4\">\n          <div className=\"fs-5 book fw-bold mb-3\">\n            <i\n              className={iconName}\n              style={{ marginBottom: \"10px\", fontSize: \"50px\" }}\n            ><\/i>{\" \"}\n            <br \/>\n            {title}\n          <\/div>\n          <div className=\"text-start\">{description}<\/div>\n        <\/Col>\n      );\n\n      const RemoteServiceDescription = () => (\n        <div className=\"mt-5\">\n          <div className=\"fs-4 book fw-bold mb-4\">\n            Comment Fonctionne Le Test Covid Virtuel\n          <\/div>\n          <div className=\"text-start mb-5\">\n            Les test COVID virtuels offrent le moyen le plus s\u00e0\u00bbr et le plus\n            simple de se faire tester. Dans les tests virtuels, des tests\n            rapides d'antig\u00e8ne vous sont envoy\u00e9es et effectu\u00e9s via un \u00c2\u00ab chat\n            vid\u00e9o \u00c2\u00bb avec l'une de nos infirmi\u00e8res autoris\u00e9es.\n          <\/div>\n          <Row>\n            <Step\n              iconName=\"fa-solid fa-cart-shopping\"\n              title=\"Planifiez votre consultation virtuelle\"\n              alt=\"step 1\"\n              description=\"Achetez votre test \u00e0  distance en toute s\u00e9curit\u00e9 en fournissant votre adresse et en prenant un rendez-vous vid\u00e9o avec l'un de nos professionnels de la sant\u00e9.\"\n            \/>\n            <Step\n              iconName=\"fa-solid fa-truck-fast\"\n              title=\"Recevez vos test par la poste\"\n              alt=\"step 2\"\n              description=\"Vos tests arriveront en toute s\u00e9curit\u00e9 par la poste. Nous nous assurons de toujours envoyer deux tests pour nous assurer qu'il n'y a pas de probl\u00e8mes et pour \u00e9viter tout stress inutile avant votre voyage.\"\n            \/>\n            <Step\n              iconName=\"fa-solid fa-video\"\n              title=\"Rejoindre votre appel vid\u00e9o\"\n              alt=\"step 3\"\n              description=\"Pendant votre appel vid\u00e9o, l'un de nos professionnels de la sant\u00e9 vous expliquera comment effectuer votre test en toute s\u00e9curit\u00e9. Une fois termin\u00e9, vous prendrez une photo de votre test et de votre identification pour v\u00e9rifier les r\u00e9sultats.\"\n            \/>\n            <Step\n              iconName=\"fa-solid fa-file-medical\"\n              title=\"Recevez vos r\u00e9sultats par voie \u00e9lectronique\"\n              alt=\"step 4\"\n              description=\"Une fois votre test v\u00e9rifi\u00e9 par notre \u00e9quipe, vos r\u00e9sultats vous seront envoy\u00e9s par voie \u00e9lectronique et pr\u00e0\u00aat \u00e0  voyager.\"\n            \/>\n          <\/Row>\n        <\/div>\n      );\n\n      const RemoteSupervisionServiceDescription = () => (\n        <div className=\"mt-5\">\n          <div className=\"fs-4 book fw-bold mb-4\">\n            Comment Fonctionnent Les Tests Supervis\u00e9s Avec La T\u00e9l\u00e9sant\u00e9.\n          <\/div>\n          <div className=\"text-start mb-5\">\n            Les tests de t\u00e9l\u00e9sant\u00e9 COVID offrent le moyen le plus s\u00e0\u00bbr et le\n            plus simple de se faire tester. En utilisant les tests d\u00e9sign\u00e9s\n            achet\u00e9s aupr\u00e8s de Summit Health. Lors de votre rendez-vous de\n            t\u00e9l\u00e9sant\u00e9, une infirmi\u00e8re autoris\u00e9e vous guidera par\n            vid\u00e9o-conf\u00e9rence pour administrer le test d'antig\u00e8ne. Vos r\u00e9sultats\n            sont valid\u00e9s et une attestation de r\u00e9sultat \u00e9lectronique vous est\n            directement envoy\u00e9e.\n          <\/div>\n          <Row>\n            <Step\n              iconName=\"fa-solid fa-cart-shopping\"\n              title=\"Planifiez votre consultation virtuelle\"\n              alt=\"step 1\"\n              description=\"Achetez vos tests en toute s\u00e9curit\u00e9 dans l'une de nos cliniques ou en ligne via notre formulaire.\"\n            \/>\n            <Step\n              iconName=\"fa-solid fa-truck-fast\"\n              title=\"Recevez vos test par la poste\"\n              alt=\"step 2\"\n              description=\"Lorsque vous avez vos tests et que vous \u00e0\u00aates pr\u00e0\u00aat \u00e0  prendre rendez-vous avec l'infirmi\u00e8re, utilisez le lien unique qui vous a \u00e9t\u00e9 fourni.\"\n            \/>\n            <Step\n              iconName=\"fa-solid fa-video\"\n              title=\"Rejoindre votre appel vid\u00e9o\"\n              alt=\"step 3\"\n              description=\"Au cours de votre appel vid\u00e9o, l'un de nos professionnels de la sant\u00e9 vous expliquera comment effectuer votre test en toute s\u00e9curit\u00e9. Une fois termin\u00e9, vous soumettrez une photo de votre test et une pi\u00e8ce d'identit\u00e9 pour v\u00e9rification.\"\n            \/>\n            <Step\n              iconName=\"fa-solid fa-file-medical\"\n              title=\"Recevez vos r\u00e9sultats par voie \u00e9lectronique\"\n              alt=\"step 4\"\n              description=\"Une fois votre test v\u00e9rifi\u00e9 par notre \u00e9quipe, vos r\u00e9sultats vous seront envoy\u00e9s par voie \u00e9lectronique. Ce document sera une attestation de vos r\u00e9sultats, qui pourra \u00e0\u00aatre utilis\u00e9 pour les voyages o\u00e0\u00b9 les tests antig\u00e9niques sont accept\u00e9s.\"\n            \/>\n          <\/Row>\n        <\/div>\n      );\n\n      const RemoteConsultationDescription = () => (\n        <div className=\"mt-5\">\n          <div className=\"fs-4 book fw-bold mb-4\">\n            Comment Fonctionnent Les Consultations Avec La T\u00e9l\u00e9sant\u00e9\n          <\/div>\n          <div className=\"text-start mb-5\">\n            Connectez-vous avec l'\u00e9quipe m\u00e9dicale de Summit Health via un appel vid\u00e9o s\u00e9curis\u00e9, accessible depuis votre ordinateur ou appareil mobile, o\u00f9 que vous soyez. Notre service de consultation virtuelle garantit une \u00e9valuation approfondie et des conseils personnalis\u00e9s pour vos pr\u00e9occupations de sant\u00e9.\n          <\/div>\n          <Row>\n            <Step\n              iconName=\"fa-regular fa-calendar-check\"\n              title=\"\u00c9tape 1\"\n              alt=\"step 1\"\n              description=\"R\u00e9servez votre consultation en ligne\"\n            \/>\n            <Step\n              iconName=\"fa-regular fa-rectangle-list\"\n              title=\"\u00c9tape 2\"\n              alt=\"step 2\"\n              description=\"Compl\u00e9tez votre questionnaire medical\"\n            \/>\n            <Step\n              iconName=\"fa-solid fa-video\"\n              title=\"\u00c9tape 3\"\n              alt=\"step 3\"\n              description=\"Joignez-vous \u00e0 l'appel vid\u00e9o pour votre consultation\"\n            \/>\n            <Step\n              iconName=\"fa-solid fa-suitcase-rolling\"\n              title=\"\u00c9tape 4\"\n              alt=\"step 4\"\n              description=\"Obtenez Vos Vaccins Ou Votre Prescription.\"\n            \/>\n          <\/Row>\n        <\/div>\n      );\n\n      const Modal = ({\n        message,\n        isOpen,\n        onClose,\n        onCancel,\n        onConfirm,\n        confirmButtonLabel = \"CONFIRMER\",\n        cancelButtonLabel = \"ANNULER\",\n        showCancel = true,\n      }) => {\n        const confirm = () => {\n          const shouldClose = onConfirm();\n          if (shouldClose !== false) {\n            onClose();\n          }\n        };\n        return (\n          <ReactModal\n            isOpen={isOpen}\n            style={{\n              overlay: {\n                backgroundColor: \"rgba(255, 255, 255, 0.75)\",\n                zIndex: 2,\n              },\n              content: {\n                border: \"0px\",\n                background: \"#0000\",\n              },\n            }}\n          >\n            <div className=\"h-100 d-flex justify-content-center align-items-center\">\n              <div\n                style={{\n                  width: \"350px\",\n                  backgroundColor: \"rgba(255,255,255)\",\n                  border: \"1px solid #ccc\",\n                  borderRadius: \"4px\",\n                  zIndex: 100,\n                }}\n                className=\"px-4 py-4\"\n              >\n                <Container fluid style={{ zIndex: 5 }}>\n                  <div className=\"mb-4 text-center\">{message()}<\/div>\n                  <div className=\"d-flex justify-content-center\">\n                    <Button className=\"mx-3 button\" onClick={confirm}>\n                      {confirmButtonLabel}\n                    <\/Button>\n                    {showCancel && (\n                      <Button\n                        variant=\"warning\"\n                        className=\"mx-3\"\n                        onClick={() => {\n                          onCancel();\n                          onClose();\n                        }}\n                      >\n                        {cancelButtonLabel}\n                      <\/Button>\n                    )}\n                  <\/div>\n                <\/Container>\n              <\/div>\n            <\/div>\n          <\/ReactModal>\n        );\n      };\n\n      const CARD_ELEMENT_OPTIONS = {\n        style: {\n          base: {\n            color: \"#32325d\",\n            fontFamily: '\"Helvetica Neue\", Helvetica, sans-serif',\n            fontSmoothing: \"antialiased\",\n            fontSize: \"16px\",\n            \"::placeholder\": {\n              color: \"#6D757D\",\n            },\n          },\n          invalid: {\n            color: \"#fa755a\",\n            iconColor: \"#fa755a\",\n          },\n        },\n      };\n\n      const ProgressCheckMark = () => (\n        <div\n          className=\"d-flex align-items-center justify-content-center\"\n          style={{\n            border: \"1px solid\",\n            height: \"45px\",\n            width: \"45px\",\n            borderRadius: \"25px\",\n            position: \"absolute\",\n            borderColor: \"gray\",\n            borderLeft: \"0px\",\n          }}\n        >\n          <div\n            className=\"d-flex align-items-center justify-content-center\"\n            style={{\n              border: \"1px solid\",\n              height: \"43px\",\n              width: \"43px\",\n              borderRadius: \"30px\",\n              borderColor: \"#D9D9D9\",\n              backgroundColor: \"#59a1ff\",\n              borderLeft: \"0px\",\n            }}\n          >\n            <div\n              className=\"fas fa-check white\"\n              style={{ fontSize: \"26px\", color: \"white\" }}\n            \/>\n          <\/div>\n        <\/div>\n      );\n\n      const StyledProgressBar = ({ progress, labels = [] }) => {\n        const now = (progress * 100) \/ labels.length;\n        return (\n          <div className=\"mt-4\">\n            <div className=\"d-flex flex-row align-items-center justify-content-end\">\n              <div className=\"w-100\">\n                <ProgressBar\n                  now={now}\n                  style={{\n                    height: \"20px\",\n                    borderRadius: \"10px\",\n                    backgroundColor: \"#D9D9D9\",\n                    padding: \"1px 2px\",\n                    border: \"1px solid #969696\",\n                  }}\n                \/>\n              <\/div>\n              {now >= 100 && <ProgressCheckMark \/>}\n            <\/div>\n            <div className=\"flex-row d-flex justify-content-around \">\n              {labels.map((label, index) => (\n                <span\n                  className=\"p-3 progressLabel fw-bold\"\n                  style={{\n                    width: \"220px\",\n                    color: progress > index ? \"#0058a4\" : \"#969696\",\n                  }}\n                  key={label + index}\n                >\n                  {label}\n                <\/span>\n              ))}\n            <\/div>\n          <\/div>\n        );\n      };\n\n      const HeaderUtil = ({ title, renderSubtitle }) => (\n        <div>\n          <h1 className=\"fs-3 book fw-bold mb-4\">{title}<\/h1>\n          {renderSubtitle()}\n        <\/div>\n      );\n\n      const renderDefaultHeaderSubtitle = () => (\n        <span className=\"text-sm-end tip\">\n          Pour d\u00e9buter, svp s\u00e9lectionner le type de rendez-vous et le nombre de\n          personnes. Nous vous montrerons les disponibilit\u00e9s des cliniques les\n          plus proches de votre emplacement. Besoin d'aide ? Contactez nous{\" \"}\n          <a href=\"tel:\/(438) 266-0855\">(438) 266-0855<\/a>.{\" \"}\n          <b>\n            Veuillez noter que les annulations dans les 48 heures avant votre\n            rendez-vous sont{\" \"}\n            <a href=\"\/politique-dannulation\/?lang=fr\">\n              assujetties \u00e0 des frais d'annulation{\" \"}\n            <\/a>\n          <\/b>\n        <\/span>\n      );\n\n      const renderRemoteHeaderSubtitle = () => (\n        <div\n          className=\"pb-4 d-md-flex align-items-center\"\n          style={{ borderBottom: \"1px solid #CCCCCC\" }}\n        >\n          <Image\n            src={\"\/step1.png\"}\n            className=\"mx-3 mb-3 mb-md-0\"\n            style={{ height: \"80px\", width: \"80px\" }}\n          \/>\n          <div className=\"text-start \">\n            <span className=\"text-sm-end tip\">\n              Pour commencer, trouvons d'abord un moment opportun pour r\u00e9server\n              votre appel vid\u00e9o en ligne avec l'un de nos professionnels de la\n              sant\u00e9. Nous vous indiquerons les disponibilit\u00e9s d'heure et de\n              date, Besoin d'aide ? Veuillez appeler le{\" \"}\n              <a href=\"tel:\/(438) 266-0855\">(438) 266-0855<\/a>.{\" \"}\n              <b>\n                Veuillez noter que les consultations virtuelles peuvent \u00e0\u00aatre\n                rec\u00e9dul\u00e9es mais pas annul\u00e9es conform\u00e9ment \u00e0 la{\" \"}\n                <a href=\"\/politique-dannulation\/?lang=fr\">\n                  politique d'annulation{\" \"}\n                <\/a>\n              <\/b>\n            <\/span>\n          <\/div>\n        <\/div>\n      );\n\n      const PlacesForm = ({ onChange, id }) => {\n        const [selectedPlace, setSelectedPlace] = useState(null);\n        const [place, setPlace] = useState(\"\");\n        const [locationInfo, setLocationInfo] = useState({});\n        const [city, setCity] = useState(\"\");\n\n        const validatePostalCode = () => {\n          let postal = document.getElementById(`pos${id}`);\n          if (postal.validity.patternMismatch) {\n            postal.setCustomValidity(\"Please enter valid postal code\");\n          } else {\n            postal.setCustomValidity(\"\");\n          }\n        };\n        const onChangeItem = (e, key) => {\n          validatePostalCode();\n          setLocationInfo({ ...locationInfo, [key]: e.target.value });\n        };\n\n        useEffect(() => {\n          if (selectedPlace) {\n            const streetNumber = getAddressAttribute(\n              selectedPlace,\n              \"street_number\"\n            );\n            const route = getAddressAttribute(\n              selectedPlace,\n              \"route\",\n              \"\",\n              false\n            );\n            const street = streetNumber + (route ? ` ${route}` : \"\");\n            const postCode = getAddressAttribute(selectedPlace, \"postal_code\");\n            const postal_code_suffix =\n              postCode +\n              getAddressAttribute(selectedPlace, \"postal_code_suffix\");\n            const city = getAddressAttribute(selectedPlace, \"locality\");\n            const province = getAddressAttribute(\n              selectedPlace,\n              \"administrative_area_level_1\"\n            );\n            setLocationInfo({\n              street,\n              postCode: postal_code_suffix,\n              city,\n              province,\n            });\n            setPlace(\"\");\n          }\n        }, [selectedPlace]);\n\n        useEffect(() => {\n          const st = locationInfo.street || place;\n          const info = {\n            ...locationInfo,\n            street: st && st.trim(),\n          };\n          onChange(info);\n        }, [locationInfo]);\n\n        const onChangePlaces = (e) => {\n          setLocationInfo({ ...locationInfo, street: \"\" });\n          setPlace(e.target.value);\n        };\n        return (\n          <Row className=\"align-items-center \">\n            <PlacesInput\n              onChange={setSelectedPlace}\n              md={8}\n              id={id}\n              required\n              value={locationInfo.street || place}\n              onChangeValue={onChangePlaces}\n            \/>\n            <Row className=\"mx-0 px-0\">\n              <Input\n                placeholder=\"Apartment, unit, suite, or floor #\"\n                id={\"apt\"}\n                onChange={(e) => onChangeItem(e, \"apartment\")}\n                required={false}\n              \/>\n              <Input\n                placeholder=\"City\"\n                id={\"cit\"}\n                onChange={(e) => onChangeItem(e, \"city\")}\n                value={locationInfo.city}\n              \/>\n            <\/Row>\n            <Input\n              placeholder=\"State\/Province\"\n              id={\"state\"}\n              onChange={(e) => onChangeItem(e, \"province\")}\n              value={locationInfo.province}\n            \/>\n            <Input\n              placeholder=\"Postal Code\"\n              id={\"pos\" + id}\n              onChange={(e) => onChangeItem(e, \"postCode\")}\n              value={locationInfo.postCode}\n              pattern={\n                \"[ABCEGHJ-NPRSTVXYabceghj-nprstvxy][0-9][ABCEGHJ-NPRSTV-Zabceghj-nprstv-z][ -]?[0-9][ABCEGHJ-NPRSTV-Zabceghj-nprstv-z][0-9]\"\n              }\n            \/>\n          <\/Row>\n        );\n      };\n\n      const PaymentInputs = React.memo(\n        ({ setPaymentData, shouldShowErrors, dismissErrors }) => {\n          const [cardNumber, setCardNumber] = useState(\"\");\n          const [expirationDate, setExpirationDate] = useState(\"\");\n          const [cvv, setCvv] = useState(\"\");\n\n          const [cardError, setCardError] = useState(\"\");\n          const [expirationDateError, setExpirationDateError] = useState(\"\");\n\n          const handleChangeCardNumber = useCallback((e) => {\n            const val = e.target.value.replace(\/[^\\dA-Z]\/g, \"\").trim();\n            setCardNumber(val);\n            const isValid = validateCard(val);\n            setCardError(isValid ? \"\" : \"Num\u00e9ro de carte invalide\");\n          }, []);\n\n          const onExpiryKeyDown = useCallback((e) => {\n            const value = e.target.value;\n            if (value.length === 3 && e.key === \"Backspace\") {\n              setExpirationDate(value.slice(0, -1));\n            }\n          }, []);\n\n          const handleChangeExpiry = useCallback((e) => {\n            let date = e.target.value;\n            let parts = date.split(\"\/\");\n            let month = parts[0];\n            let year = parts[1];\n            let current_year = new Date().getFullYear().toString().slice(-2);\n            if (\n              !(month >= 1 && month <= 12) ||\n              !(year >= current_year && year <= parseInt(current_year) + 10)\n            ) {\n              setExpirationDateError(\"Date d'expiration invalide\");\n            } else {\n              setExpirationDateError(\"\");\n            }\n\n            setExpirationDate(\n              date\n                .replace(\/[^\\d]\/g, \"\")\n                .replace(\/(.{2})\/g, \"$1\/\")\n                .slice(0, 5)\n            );\n          }, []);\n\n          const handleChangeCVV = useCallback(\n            (e) => setCvv(e.target.value.replace(\/[^\\d]\/g, \"\")),\n            []\n          );\n          const cardValue = useMemo(() => cardNumber, [cardNumber]);\n\n          useEffect(() => {\n            const isValid =\n              (cardNumber.length === 16 || cardNumber.length === 15) &&\n              expirationDate.length === 5 &&\n              cvv.length > 2 &&\n              !cardError &&\n              !expirationDateError;\n\n            dismissErrors();\n\n            setPaymentData({\n              cardNumber,\n              expirationDate,\n              cvv,\n              isValid,\n            });\n          }, [cardNumber, expirationDate, cvv, cardError, expirationDateError, shouldShowErrors]);\n\n          const shouldHighlightErrors = shouldShowErrors && (!cardNumber || !expirationDate || !cvv);\n\n          return (\n            <Row>\n              <Input\n                placeholder=\"Num\u00e9ro de carte\"\n                id={\"card-number\"}\n                md={6}\n                onChange={handleChangeCardNumber}\n                maxLength={16}\n                value={cardValue}\n                hasError={\n                  (cardNumber.length === 16 || shouldShowErrors) &#038;&#038; cardError\n                }\n                error={cardError || \"Entrez un num\u00e9ro de carte valide\"}\n                style={shouldHighlightErrors &#038;&#038; !cardNumber ? { border: \"2px solid rgb(214, 0, 0)\", borderRadius: \"4px\" } : {}}\n              \/>\n              <Input\n                placeholder=\"MM \/ AA\"\n                id={\"month-year\"}\n                md={3}\n                onKeyDown={onExpiryKeyDown}\n                onChange={handleChangeExpiry}\n                value={expirationDate}\n                maxLength={5}\n                hasError={\n                  (expirationDate.length === 5 || shouldShowErrors) &#038;&#038;\n                  expirationDateError\n                }\n                style={shouldHighlightErrors &#038;&#038; !expirationDate ? { border: \"2px solid rgb(214, 0, 0)\", borderRadius: \"4px\" } : {}}\n              \/>\n              <Input\n                placeholder=\"CVV\"\n                id={\"special-instructions\"}\n                md={3}\n                value={cvv}\n                onChange={handleChangeCVV}\n                maxLength={4}\n                hasError={shouldShowErrors &#038;&#038; cvv.length < 3}\n                style={shouldHighlightErrors &#038;&#038; !cvv ? { border: \"2px solid rgb(214, 0, 0)\", borderRadius: \"4px\" } : {}}\n              \/>\n            <\/Row>\n          );\n        }\n      );\n\n      ReactModal.setAppElement(document.getElementById(\"book-form\"));\n\n      const SummitHealth = (props) => {\n        \/* Input Handling States *\/\n        moment.locale(\"fr\");\n        const [service, setService] = useState({});\n        const [serviceId, setServiceId] = useState(\"\");\n        const [serviceType, setServiceType] = useState(\"\");\n        const [patientCount, setPatientCount] = useState(\"1\");\n        const [countries, setCountries] = useState([\n          { CountryNameFR: \"S\u00e9lectionner des destinations\", Id: \"\" },\n        ]);\n        const [countriesById, setCountriesById] = useState({});\n        const [selectedCountries, setSelectedCountries] = useState([]);\n\n        function getInitialLanguage() {\n          const savedLang = localStorage.getItem('selectedLanguage');\n          return savedLang || 'french';\n        }\n\n        const [language, setLanguage] = useState(getInitialLanguage());\n\n        const [vaccines, setVaccines] = useState([\n          { name: \"S\u00e9lectionnez les vaccins\", Id: \"\" },\n        ]);\n        const [vaccinesById, setVaccinesById] = useState({});\n        const [selectedVaccines, setSelectedVaccines] = useState([]);\n\n        const [existingAppointment, setExistingAppointment] = useState({});\n\n        const [date, setDate] = useState(new Date());\n        const [time, setTime] = useState(\"\");\n\n        const [location, setLocation] = useState(\"\");\n        const [locations, setLocations] = useState([]);\n        const [selectedLocationId, setSelectedLocationId] = useState(\"\");\n        const [selectedExpert, setSelectedExpert] = useState(\"\");\n\n        const [contacts, setContacts] = useState([]);\n        const [userLocation, setUserLocation] = useState({});\n        const [shippingLocation, setShippingLocation] = useState({});\n        const [sameAsContactLocation, setSameAsContactLocation] =\n          useState(true);\n        const [specialInstructions, setSpecialInstructions] = useState(\"\");\n        const [departureDate, setDepartureDate] = useState(\"\");\n        const [returnDate, setReturnDate] = useState(\"\");\n\n        const [promoCode, setPromoCode] = useState(urlParams.get(\"promoCode\") || \"\");\n        const [promoCodeData, setPromoCodeData] = useState({});\n        const [autoValidatePromo, setAutoValidatePromo] = useState(!!urlParams.get(\"promoCode\"));\n\n        const [paymentData, setPaymentData] = useState({});\n        const [shouldShowPaymentErrors, setShouldShowPaymentErrors] =\n          useState(false);\n        const [paymentError, setPaymentError] = useState(\"\");\n        const [bookResponse, setBookResponse] = useState({});\n        const [saveCreditCard, setSaveCreditCard] = useState(true);\n        \/* Error Handling States *\/\n        const [showNoLocationSelectedError, setNoLocationSelectedError] =\n          useState(false);\n        const [error, setError] = useState(\"\");\n        const [promoCodeError, setPromoCodeError] = useState(\"\");\n\n        \/* loading Handling States *\/\n        const [isLoadingLocations, setIsLoadingLocations] = useState(false);\n        const [isLoadingAppointment, setIsLoadingAppointment] = useState(false);\n        const [isSubmitting, setIsSubmitting] = useState(false);\n        const [isValidatingPromoCode, setIsValidatingPromoCode] =\n          useState(false);\n\n        \/* UI *\/\n        const [mainFormTabKey, setMainFormTabKey] = useState(\"main\");\n        const [progress, setProgress] = useState(0);\n\n        const [selectedServiceNote, setSelectedServiceNote] = useState(null);\n        const [isServiceNoteModalOpen, setIsServiceNoteModalOpen] = useState(false);\n        const [serviceNoteCheckboxes, setServiceNoteCheckboxes] = useState([]);\n\n        const [checkboxError, setCheckboxError] = useState(\"\");\n        const [isServiceNoteConfirmed, setIsServiceNoteConfirmed] = useState(false);\n\n        const [isPrivateVaccineNoteModalOpen, setPrivateVaccineNoteModalOpen] =\n          useState(false);\n        const [isSlotModalOpen, setIsSlotModalOpen] = useState(false);\n        const [isRescheduleFeeModalOpen, setIsRescheduleFeeModalOpen] =\n          useState(false);\n        const [isBookingModalOpen, setIsBookingModalOpen] = useState(false);\n        const [slotNotAvailableModalOpen, setSlotNotAvailableModalOpen] =\n          useState(false);\n        const [isDateModalOpen, setIsDateModalOpen] = useState(false);\n        const [showEmail, setShowEmail] = useState(false);\n        const [key, setKey] = useState(\"appointment\");\n\n        const [refetchSlots, setRefetchSlots] = useState(false);\n\n        const [firstTbInitialAppointment, setFirstTbInitialAppointment] =\n          useState(null);\n        const [SecondTbInitialAppointment, setSecondTbInitialAppointment] =\n          useState(null);\n        const [isFirstInitialTbConfirmed, setIsFirstInitialTbConfirmed] =\n          useState(false);\n        const firstTbDate = useRef(null);\n\n        \/* End of States *\/\n\n        \/* Refs *\/\n        const selectSlotRef = useRef();\n        const serviceTypeRef = useRef(serviceType);\n\n        const isRemoteService = serviceType === \"Covid Remote Test\";\n        const isTravelConsult = serviceType === \"Travel Consult\";\n\n        const isBooster = serviceType === \"Booster\";\n        const isPrivateVaccine = serviceType === \"Private Vaccine\";\n        const shouldShowVaccineSection = isBooster || isPrivateVaccine;\n        const [selectedInitialtbTestDate, setSelectedInitialTbTestDate] =\n          useState(null);\n\n        const isTelehealthCovidTest = serviceType === \"Telehealth COVID Test\";\n        const isTelehealthNonTravelConsultation = serviceType === \"Cold Sore\";\n        \n        const selectedReason = AppointmentReasons.find(r => r.value === serviceType) || {};\n        const isTelehealthConsultation = !!selectedReason.isVirtual;\n        const isSinglePatientService = !!selectedReason.isSinglePatientService;\n\n        const urlSearchParams = new URLSearchParams(window.location.search);\n        const params = Object.fromEntries(urlSearchParams.entries());\n        const isEditing = !!params.aid;\n        const passedAppointmentType = !!params.aType;\n\n        const [isRebooking, setIsRebooking] = useState(false);\n\n        const servicePopups = {\n          \"Booster\": {\n            description: () => (\n              <span>Ce rendez\u2011vous est pour un <strong>vaccin de rappel<\/strong>. Veuillez confirmer les points suivants:<\/span>\n            ),\n            checkboxes: [\n              <span>Je comprends qu\u2019il ne s\u2019agit pas d\u2019une consultation voyage.<\/span>,\n              <span>J\u2019ai d\u00e9j\u00e0 effectu\u00e9 une consultation voyage et ceci est un suivi.<\/span>\n            ]\n          },\n          \"Cold Sore\": {\n            description: () => (\n              <span>Ce rendez\u2011vous est pour une <strong>\u00e9valuation virtuelle de l'herp\u00e8s labial<\/strong>. Veuillez confirmer les points suivants:<\/span>\n            ),\n            checkboxes: [\n              <span>J\u2019ai actuellement un feu sauvage qui n\u00e9cessite une \u00e9valuation.<\/span>,\n              <span>Je comprends qu\u2019une ordonnance ne sera \u00e9mise que si cela est jug\u00e9 appropri\u00e9.<\/span>\n            ]\n          },\n          \"Blood Test\": {\n            description: () => (\n              <span>Ce rendez\u2011vous est pour une <strong>prise de sang<\/strong>. Veuillez confirmer les points suivants:<\/span>\n            ),\n            checkboxes: [\n              <span>Je dispose d\u2019une requ\u00eate d\u2019un professionnel de sant\u00e9.<\/span>,\n              <span>Je comprends qu\u2019il ne s\u2019agit pas d\u2019une consultation et qu\u2019aucun diagnostic ne sera pos\u00e9.<\/span>\n            ]\n          },\n          \"Tick Bite Exposure\": {\n            description: () => (\n              <span>\n                Ce rendez-vous s\u2019adresse uniquement aux patients qui r\u00e9pondent \u00e0 <strong>tous<\/strong> les crit\u00e8res ci-dessous.  \n                Si vous pr\u00e9sentez des sympt\u00f4mes de la maladie de Lyme (comme une rougeur, de la fi\u00e8vre ou des douleurs articulaires),  \n                veuillez plut\u00f4t consulter votre m\u00e9decin de famille ou une clinique m\u00e9dicale locale.\n              <\/span>\n            ),\n            checkboxes: [\n              <span>Je ne suis pas enceinte et je ne pense pas l\u2019\u00eatre.<\/span>,\n              <span>La tique est probablement rest\u00e9e accroch\u00e9e pendant 24 heures ou plus, ou je ne suis pas certain de la dur\u00e9e.<\/span>,\n              <span>Je ne pr\u00e9sente pas de sympt\u00f4mes de la maladie de Lyme (comme une rougeur, de la fi\u00e8vre ou des douleurs articulaires).<\/span>,\n              <span>La tique \u00e9tait encore accroch\u00e9e ou je suis certain qu\u2019il s\u2019agissait d\u2019une tique.<\/span>,\n              <span>Je n\u2019ai aucun ant\u00e9c\u00e9dent de r\u00e9action allergique \u00e0 un antibiotique de type t\u00e9tracycline (ex. : doxycycline, minocycline ou t\u00e9tracycline).<\/span>\n            ]\n          },\n          \"Private Vaccine\": {\n            description: () => (\n              <span>\n                Veuillez noter que ce rendez-vous est pour les vaccins non\n                li\u00e9s au voyage tels que le zona (Shingrix) et la pneumonie\n                (Prevnar, Pneumovax). Si vous recherchez un vaccin li\u00e9 au\n                voyage (par exemple: la fi\u00e8vre jaune, la typho\u00efde),{\" \"}\n\n                <span style={{ textDecoration: 'underline', cursor: 'pointer' }} onClick={defaultTravelConsult}>\n                  veuillez cliquer ici pour s\u00e9lectionner une consultation de voyage \u00e0 la place.\n                <\/span>\n\n                {\" \"} Si vous avez des questions, n'h\u00e9sitez pas \u00e0 nous contacter.\n              <\/span>\n            ),\n            checkboxes: []\n          }\n        };\n\n        const handleConfirmServiceNote = () => {\n          const allChecked = serviceNoteCheckboxes.every(Boolean);\n          if (!allChecked) {\n            setCheckboxError(\"Veuillez confirmer tous les \u00e9l\u00e9ments pour continuer.\");\n            return false;\n          }\n\n          setCheckboxError(\"\");\n          setIsServiceNoteConfirmed(true);\n          setIsServiceNoteModalOpen(false);\n          return true; \n        };\n\n        function resetForm() {\n          setServiceType(\"\");\n          setPatientCount(\"\");\n          setLocation(null);\n          setKey(\"appointment\");\n          setProgress(0);\n        }\n\n        function handleCancelServiceNote() {\n          setCheckboxError(\"\");\n          setIsServiceNoteModalOpen(false);\n          setPrivateVaccineNoteModalOpen(false)\n          resetForm(); \n        }\n\n        function handleCloseServiceNote() {\n          setCheckboxError(\"\");\n          setIsServiceNoteModalOpen(false);\n          setPrivateVaccineNoteModalOpen(false)\n        }\n\n        const shouldShowRescheduleFeeOpen =\n          isEditing &&\n          existingAppointment &&\n          !existingAppointment.rescheduledBySupport &&\n          moment(existingAppointment.startTime)\n            .subtract(\"days\", 1)\n            .isSameOrBefore(moment());\n\n        const loadExistingAppointment = async (id) => {\n          setIsLoadingAppointment(true);\n          setKey(\"location\");\n          setProgress(1);\n          let appointment = await getAppointment({ id });\n          const { locationLon, locationLat, serviceId, startTime, locationId } =\n            appointment;\n          setExistingAppointment(appointment);\n          setServiceId(appointment.serviceId);\n          setDate(new Date());\n          setSelectedLocationId(locationId);\n          if (appointment.serviceType.includes(\"Virtual Antigen Test\")) {\n            setServiceType(\"Covid Remote Test\");\n            setLocations([{}]);\n          } else {\n            await fetchLocations(locationLat, locationLon);\n          }\n          setIsLoadingAppointment(false);\n        };\n\n        const loadCountries = async () => {\n          const res = await getCountries();\n          res.countries.sort(function (a, b) {\n            return a.CountryNameFR.localeCompare(b.CountryNameFR);\n          });\n          setCountries((prev) => [...prev, ...res.countries]);\n          setCountriesById(_.keyBy(res.countries, \"Id\"));\n        };\n\n        const loadVaccines = async () => {\n          const res = await getVaccines();\n          setVaccines((prev) => [...prev, ...res.countries]);\n          setVaccinesById(_.keyBy(res.countries, \"Id\"));\n        };\n\n        useEffect(() => {\n          if (isEditing) {\n            loadExistingAppointment(params.aid);\n          }\n        }, [isEditing]);\n\n        useEffect(() => {\n          if (\n            serviceType &&\n            serviceType == \"TB Skin Test Initial Appointment\"\n          ) {\n            Swal.fire({\n              title: \"Test cutan\u00e9 anti-TB une autre fois\",\n              html: `\n                  <hr\/>\n                  <div style=\"text-align:left\">\n                    <p>A <b style=\"color:red\">Test cutan\u00e9 anti-TB une autre fois<\/b> consiste en <span style=\"font-weight:bold;text-decoration:underline\">deux<\/span> rendez-vous: <\/p>\n                    <p> <span style=\"color:red;font-weight: bold;\">Un premier rendez-vous (75$)<\/span><\/p>\n                    <p style=\"color:red;font-weight: bold;\">et un rendez-vous de lecture (40$)<\/p>\n                    <p><span style=\"font-weight:bold;color:red;\">La lecture<\/span> doit \u00eatre r\u00e9serv\u00e9 <span style=\"font-weight:bold;color:red;\">48-72 heures<\/span>apr\u00e8s le <span style=\"color:red;font-weight:bold\">premier rendez-vous<\/span><\/p>\n                    <p style=\"font-weight:bold\">Sur les \u00e9crans suivants, vous s\u00e9lectionnerez les deux rendez-vous<\/p>\n                    <p style=\"font-weight:bold\">Pour plus d'informations, veuillez visiter ce lien : <a href=\"https:\/\/cliniquevoyageur.ca\/tuberculosis-testing\/\" target=\"_blank\">Lien<\/a><\/p>\n                    <p style=\"font-weight:bold;color:blue;text-align:center\">ou appeler 1-888-224-8809<\/p>\n                    <\/div>\n      `,\n              icon: \"warning\",\n            });\n          }\n        }, [serviceType]);\n\n        useEffect(() => {\n          if (passedAppointmentType) {\n            const appointment_type = AppointmentReasons.find(\n              (reason) => reason.value === params.aType\n            );\n            if (appointment_type) {\n              setServiceType(appointment_type.value);\n            }\n          }\n        }, [passedAppointmentType]);\n\n        useEffect(() => {\n          if (serviceType && patientCount) {\n            getServiceForOnlineBooking({ serviceType, patientCount }).then(\n              (res) => {\n                const result = res && res[0];\n                setService(result);\n                setServiceId(result.Id);\n              }\n            );\n            const initialData = new Array(Number(patientCount))\n              .fill()\n              .map(Object);\n            setContacts(initialData);\n          }\n        }, [serviceType, patientCount]);\n\n        \/* Helper Functions *\/\n\n        const onChangeValue = (e, setter) => {\n          setter(e.target.value);\n        };\n\n        const onChangePlacesSearch = (setter, e) => {\n          setter(e);\n        };\n\n        const validateEmails = () =>\n          contacts.forEach((c, index) => {\n            let email = document.getElementById(`email${index}`);\n            if (email.validity.patternMismatch) {\n              email.setCustomValidity(\"Veuillez entrer un courriel valide\");\n            } else {\n              email.setCustomValidity(\"\");\n            }\n          });\n\n        const onChangeContact = (e, param, index) => {\n          validateEmails();\n          let value;\n          if (param == \"newsletter\") {\n            value = e;\n          } else {\n            value = e.target.value;\n          }\n          let currentContacts = [...contacts];\n          currentContacts[index][param] = value;\n          setContacts(currentContacts);\n        };\n\n        const onSubmit = (e, action) => {\n          const form = e.currentTarget;\n          if (form.checkValidity() === false) {\n            e.stopPropagation();\n          } else {\n            action();\n          }\n          e.preventDefault();\n        };\n\n        const verifySlotAvailability = async () => {\n          const formattedDate = moment(date).format(\"D_M_yyyy\");\n          const response = await getAvailabilities({\n            locationId: selectedLocationId,\n            serviceId,\n            selectedDate: formattedDate,\n          });\n          let dates = getMergedDates(response.content.availableSlots);\n          const isSlotStillAvailable = dates[formattedDate].slots.some(\n            (slot) => slot.slot === time && !slot.isBookedSlot\n          );\n          return isSlotStillAvailable;\n        };\n\n        const getPromoParams = () => {\n          if (!promoCodeData.Id) return {};\n\n          const promoCode = promoCodeData.Id;\n          const totalAmount = service.Pre_Payment_Price__c;\n          const discountAmount =\n            promoCodeData.Discount_Type__c === \"Percentage\"\n              ? totalAmount * (promoCodeData.Promo_Amount__c \/ 100)\n              : promoCodeData.Promo_Amount__c;\n          const totalPaidAmount = Number(\n            (totalAmount - discountAmount).toFixed(2)\n          );\n          window.dataLayer = window.dataLayer || [];\n          window.dataLayer.push({\n            appointmentTotal: totalPaidAmount,\n          });\n          \/\/window.dataLayer.push({'event': 'appointmentBooked'});\n          console.log(\n            \"finished pushing total paid amount to the datalayer\" +\n              totalPaidAmount\n          );\n          return {\n            promoCode,\n            totalPaidAmount,\n            discountAmount,\n          };\n        };\n\n        const getShippingLocationParams = () => {\n          if (!isRemoteService) return {};\n          const loc = sameAsContactLocation ? userLocation : shippingLocation;\n\n          return {\n            shippingStreet: loc.street,\n            shippingApartment: loc.apartment,\n            shippingCity: loc.city,\n            shippingState: loc.province,\n            shippingPostalCode: loc.postCode,\n          };\n        };\n\n        const validatePromo = async () => {\n          setIsValidatingPromoCode(true);\n          setPromoCodeData({});\n          setPromoCodeError(\"\");\n          try {\n            const promoData = await validatePromoCode({\n              code: promoCode,\n              serviceId: serviceId,\n              locationId: selectedLocationId,\n            });\n            console.log(\"validatePromo params:\", promoData);\n\n            if (!promoData[0].Id) {\n              setPromoCodeError(promoData.message || \"err\");\n            } else {\n              setPromoCodeData(promoData[0]);\n            }\n          } catch (err) {\n            setPromoCodeError(\"err\");\n          }\n          setIsValidatingPromoCode(false);\n        };\n\n        useEffect(() => {\n          const promoApplicableServices = [\n            \"Covid Remote Test\",\n            \"Telehealth COVID Test\",\n            \"Telehealth Consultation\",\n            \"Travel Consult\",\n            \"Booster\",\n            \"Private Vaccine\",\n            \"TB Skin Test Initial Appointment\",\n            \"TB Skin Test Reading\",\n            \"Rapid Strep Test\",\n            \"Pre-Biological Assessment\",\n            \"Cold Sore\",\n            \"Blood Test\",\n            \"Tick Bite Exposure\"\n          ];\n\n          const isPromoApplicable = promoApplicableServices.includes(serviceType);\n\n          if (autoValidatePromo && promoCode && serviceId && isPromoApplicable) {\n            validatePromo();\n            setAutoValidatePromo(false);\n          }\n        }, [promoCode, serviceId, serviceType, autoValidatePromo]);\n\n        const getPaymentParams = () => {\n          const { cardNumber, expirationDate, cvv, isValid } = paymentData;\n          return {\n            cardNumber,\n            exp: expirationDate,\n            cvv,\n            billingFirstName: contacts[0] && contacts[0].firstName,\n            billingLastName: contacts[0] && contacts[0].lastName,\n          };\n        };\n\n        const onSelectDate = (date) => {\n          setDate(date);\n          setTime(\"\");\n        };\n\n        const onSelectSlot = async (location, time, expertId, isVirtual) => {\n          setTime(time);\n          setIsSlotModalOpen(true);\n          if (isVirtual) {\n            console.log(\n              \"should call the API to get the proper location based on the key\/expert as this is virtual\",\n              expertId\n            );\n            console.log(\"old loc: \", location);\n            let result = await post(\"appointment\/getLocationFromExpert\", {\n              expertId: expertId,\n            });\n            console.log(result);\n            location = result.locationId;\n            console.log(\"new loc: \", location);\n          }\n          setSelectedLocationId(location);\n          setSelectedExpert(expertId);\n        };\n\n        const countryList = useMemo(\n          () =>\n            countries.filter(\n              (country) => !selectedCountries.includes(country.Id)\n            ),\n          [selectedCountries, countries]\n        );\n\n        const handleSelectCountry = (newCountryId) => {\n          if (newCountryId) {\n            let newSelectedCountries = [...selectedCountries];\n            if (newSelectedCountries.includes(newCountryId)) {\n              newSelectedCountries = newSelectedCountries.filter(\n                (id) => id !== newCountryId\n              );\n            } else {\n              newSelectedCountries.push(newCountryId);\n            }\n            setSelectedCountries(newSelectedCountries);\n          }\n        };\n\n        const vaccineList = useMemo(\n          () =>\n            vaccines.filter(\n              (vaccine) => !selectedVaccines.includes(vaccine.Id)\n            ),\n          [selectedVaccines, vaccines]\n        );\n\n        const handleSelectVaccine = (newVaccineId) => {\n          if (newVaccineId) {\n            let newSelectedVaccines = [...selectedVaccines];\n            if (newSelectedVaccines.includes(newVaccineId)) {\n              newSelectedVaccines = newSelectedVaccines.filter(\n                (id) => id !== newVaccineId\n              );\n            } else {\n              newSelectedVaccines.push(newVaccineId);\n            }\n            setSelectedVaccines(newSelectedVaccines);\n          }\n        };\n\n        useEffect(() => {\n          console.log(\"isEditing:\", isEditing);\n          console.log(\"existingAppointment:\", existingAppointment);\n          \n          if (\n            isEditing &&\n            existingAppointment &&\n            existingAppointment.serviceType === \"TB Skin Test Reading\" &&\n            initialTBDateTime\n          ) {\n            const newInitialAppointment = {\n              Id: existingAppointment.Id,\n              patientName: existingAppointment.patientName,\n              serviceType: \"TB Skin Test Initial\",\n              startTime: initialTBDateTime,\n              endTime: null,\n              locationId: existingAppointment.locationId,\n              serviceId: existingAppointment.serviceId,\n              isBooster: existingAppointment.isBooster,\n              patientId: existingAppointment.patientId,\n              locationName: existingAppointment.locationName,\n            };\n\n            setFirstTbInitialAppointment(newInitialAppointment);\n            setSelectedInitialTbTestDate(moment(initialTBDateTime));\n            console.log(\"initialTBDateTime:\", initialTBDateTime);\n          }\n          }, [isEditing, existingAppointment, initialTBDateTime]);\n\n        useEffect(() => {\n          console.log(\"firstTbInitialAppointment:\", firstTbInitialAppointment);\n        }, [firstTbInitialAppointment]);\n\n        const datePickerIntervals = useMemo(() => {\n          let datePickerMinDate, datePickerMaxDate;\n          \n          if (\n            isRemoteService ||\n            isTelehealthCovidTest ||\n            isTelehealthConsultation\n          ) {\n            const dateInstance = new Date();\n            const now = new Date(\n              dateInstance.getFullYear(),\n              dateInstance.getMonth(),\n              dateInstance.getDate()\n            );\n\n            datePickerMinDate = moment(now).add(NO_BYPASSED_DAYS, \"days\");\n          } else {\n            const [minBookingInterval, maxBookingInterval] =\n              params.bookingInterval ? params.bookingInterval.split(\":\") : [];\n\n            const minInterval =\n              minBookingInterval || service.Minimum_Booking_Interval__c;\n\n            const maxInterval =\n              maxBookingInterval || service.Maximum_Booking_Interval__c;\n\n            const bookingDate = params.bookingDate\n              ? moment(params.bookingDate, \"D\/M\/YYYY-HH:mm\")\n              : moment();\n            datePickerMinDate = minInterval\n              ? moment(bookingDate).add(Number(minInterval), \"h\")\n              : null;\n            datePickerMaxDate = maxInterval\n              ? moment(bookingDate).add(Number(maxInterval), \"h\")\n              : null;\n          }\n\n          if (firstTbInitialAppointment && selectedInitialtbTestDate) {\n            datePickerMinDate = moment(selectedInitialtbTestDate).add(48, \"h\");\n            datePickerMaxDate = moment(selectedInitialtbTestDate).add(72, \"h\");\n          }\n\n          \/\/ console.log(\"datePickerMinDate:\", datePickerMinDate && datePickerMinDate.format());\n          \/\/ console.log(\"datePickerMaxDate:\", datePickerMaxDate && datePickerMaxDate.format());\n          \n          if (minDate && maxDate) {\n            return {\n              datePickerMinDate: moment(minDate),\n              datePickerMaxDate: moment(maxDate)\n            };\n          }\n\n          return { datePickerMinDate, datePickerMaxDate };\n        }, [\n          isRemoteService,\n          isTelehealthCovidTest,\n          isTelehealthConsultation,\n          service,\n          firstTbInitialAppointment,\n          selectedInitialtbTestDate,\n          serviceType,\n          minDate, \n          maxDate\n        ]);\n\n        const { datePickerMinDate, datePickerMaxDate } = datePickerIntervals;\n\n        \/* End Helper Functions *\/\n        useEffect(() => {\n          if (serviceTypeRef.current !== serviceType) {\n            if (\n              (isTravelConsult || isTelehealthConsultation) &&\n              countries.length < 2\n            ) {\n              loadCountries();\n            } else if (shouldShowVaccineSection &#038;&#038; vaccines.length < 2) {\n              loadVaccines();\n            }\n\n            if (servicePopups[serviceType]) {\n              setSelectedServiceNote(serviceType);\n              setServiceNoteCheckboxes(Array(servicePopups[serviceType].checkboxes.length).fill(false));\n              if (serviceType === \"Private Vaccine\") {\n                setPrivateVaccineNoteModalOpen(true);\n              } else {\n                setIsServiceNoteModalOpen(true);\n              }\n            }\n            \n            serviceTypeRef.current = serviceType;\n          }\n\n          if (datePickerIntervals.datePickerMinDate) {\n            setDate(datePickerIntervals.datePickerMinDate.toDate());\n          } else {\n            setDate(new Date());\n          }\n        }, [serviceType, datePickerIntervals]);\n\n        \/* Main Functions *\/\n\n        const logLocation = async () => {\n          const street = getAddressAttribute(\n            location,\n            \"route\",\n            \"pas disponible\"\n          );\n          const city = getAddressAttribute(\n            location,\n            \"locality\",\n            \"pas disponible\"\n          );\n          const state = getAddressAttribute(\n            location,\n            \"administrative_area_level_1\",\n            \"pas disponible\"\n          );\n          const postalCode = getAddressAttribute(\n            location,\n            \"postal_code\",\n            \"pas disponible\"\n          );\n          const lat = String(location.geometry.location.lat());\n          const lon = String(location.geometry.location.lng());\n          await addLocationSearch({\n            street,\n            city,\n            state,\n            postalCode,\n            lat,\n            lon,\n            serviceId,\n            serviceName: service.Name,\n            urlParams: window.location.search.substr(1),\n          });\n        };\n\n        const onSearchRemoteService = () => {\n          setBookResponse({});\n          setTime(\"\");\n          setIsSubmitting(false);\n          setSelectedLocationId(null);\n          setLocations([{}]);\n          setKey(\"location\");\n          setProgress(1);\n        };\n\n        const onSearchLocation = async () => {\n          setBookResponse({});\n          setTime(\"\");\n          setIsSubmitting(false);\n          setSelectedLocationId(null);\n          if (!location) {\n            setNoLocationSelectedError(true);\n          } else {\n            setNoLocationSelectedError(false);\n            const lat = location.geometry.location.lat();\n            const lon = location.geometry.location.lng();\n            logLocation();\n            await fetchLocations(lat, lon);\n          }\n        };\n\n        const fetchLocations = async (lat, lon) => {\n          setIsLoadingLocations(true);\n          setError(\"\");\n          try {\n            const response = await getLocations({ lat, lon });\n            setLocations(response);\n            if (!response.length) setError(\"e\");\n            else {\n              setKey(\"location\");\n              setProgress(1);\n            }\n          } catch (e) {\n            setError(\"e\");\n          }\n          setIsLoadingLocations(false);\n        };\n\n        const onBook = async (serviceId, appointment) => {\n          return new Promise(async (resolve) => {\n            setIsSubmitting(true);\n            setBookResponse({});\n            setShowEmail(true);\n            try {\n              let bookingReference = urlParams.get(\"bookingReference\");\n\n              const stillAvailable = await verifySlotAvailability();\n              if (stillAvailable) {\n                let totalPaidAmount;\n                try {\n                  window.dataLayer.push({ event: \"appointmentBooked\" });\n                } catch (e) {}\n                if (!promoCodeData.Do_Not_Require_Prepayment__c) {\n                  totalPaidAmount = appointment\n                    ? appointment.amount\n                    : service.Pre_Payment_Price__c;\n                }\n                if (getPromoParams().discountAmount > 0) {\n                  totalPaidAmount = Number(\n                    (totalPaidAmount - getPromoParams().discountAmount).toFixed(\n                      2\n                    )\n                  );\n                }\n                var googleClickBooking;\n                try {\n                  var gclidRecord;\n                  var gclid =\n                    gclidRecord || JSON.parse(localStorage.getItem(\"gclid\"));\n                  var isGclidValid =\n                    gclid && new Date().getTime() < gclid.expiryDate;\n                  if (isGclidValid) {\n                    googleClickBooking = gclid.value;\n                  }\n                } catch (e) {}\n                var microsoftClickBooking;\n                try {\n                  var msclidRecord;\n                  var msclid =\n                    msclidRecord || JSON.parse(localStorage.getItem(\"mscklid\"));\n                  var isMsclidValid =\n                    msclid &#038;&#038; new Date().getTime() < msclid.expiryDate;\n                  if (isMsclidValid) {\n                    microsoftClickBooking = msclid.value;\n                  }\n                } catch (e) {}\n                let bookingParams = {\n                  locationId: appointment\n                    ? appointment.locationId\n                    : selectedLocationId,\n                  serviceId: appointment ? appointment.serviceId : serviceId,\n                  slot: appointment ? appointment.slot : time,\n                  expertId: appointment ? appointment.expertId : selectedExpert,\n                  date: appointment\n                    ? appointment.date\n                    : moment(date).format(\"D_M_yyyy\"),\n                  contacts,\n                  language: language.charAt(0).toUpperCase() + language.slice(1), \/\/doing this because virtual availabilities uses a lowercase but we need uppercase for appointment booking\n                  departureDate,\n                  returnDate,\n                  countries: selectedCountries,\n                  vaccines: selectedVaccines,\n                  totalPaidAmount,\n                  ...getPromoParams(),\n                  ...getShippingLocationParams(),\n                  ...getPaymentParams(),\n                  additionalInformation: specialInstructions,\n                  gclid: googleClickBooking,\n                  mscklid: microsoftClickBooking,\n                  saveCreditCard,\n                  bookingReference: bookingReference,\n                  domain: window.location.hostname,\n                };\n                const response = await useRecaptcha(book, bookingParams);\n                if (response.errorMessage) {\n                  Swal.fire({\n                    icon: \"erreur\",\n                    title: \"Oops...\",\n                    text: response.errorMessage,\n                  });\n                  setPaymentError(response.errorMessage);\n                } else {\n                  setBookResponse(response);\n                  setKey(\"complete\");\n                  setProgress(3);\n                }\n              } else {\n                setSlotNotAvailableModalOpen(true);\n              }\n            } catch (err) {\n              if (err.errorMessage) {\n                setPaymentError(err.errorMessage);\n                Swal.fire({\n                  icon: \"erreur\",\n                  title: \"Oops...\",\n                  text: err.errorMessage,\n                });\n              } else {\n                setError(err.errorCode || \"e\");\n                Swal.fire({\n                  icon: \"erreur\",\n                  title: \"Oops...\",\n                  text: err.errorCode,\n                });\n              }\n            }\n            setIsSubmitting(false);\n            resolve();\n          });\n        };\n\n        const onBeginBook = async () => {\n          setPaymentError(\"\");\n          setError(\"\");\n          if (\n            !promoCodeData.Do_Not_Require_Prepayment__c &&\n            !paymentData.isValid\n          ) {\n            setShouldShowPaymentErrors(true);\n            Swal.fire({\n              icon: \"error\",\n              title: \"Oops...\",\n              text: \"Les entr\u00e9es de carte fournies ne sont pas valides\",\n            });\n            return;\n          }\n          setIsSubmitting(true);\n          try {\n            let token;\n            const response = await checkDuplicateAppointments({\n              email: contacts[0].email,\n              serviceId,\n            });\n            if (response.appointmentCount) {\n              setIsBookingModalOpen(true);\n            } else {\n              if (!firstTbInitialAppointment && !SecondTbInitialAppointment) {\n                await onBook(serviceId);\n              } else {\n                try {\n                  await onBook(\n                    firstTbInitialAppointment.serviceId,\n                    firstTbInitialAppointment\n                  );\n                  await onBook(\n                    SecondTbInitialAppointment.serviceId,\n                    SecondTbInitialAppointment\n                  );\n                } catch (err) {\n                  setError(err);\n                }\n              }\n            }\n          } catch (err) {\n            setError(\"e\");\n          }\n          setIsSubmitting(false);\n        };\n\n        const onReschedule = async () => {\n          setIsSubmitting(true);\n          setError(\"\");\n          try {\n            const response = await rescheduleAppointment({\n              id: params.aid,\n              location: selectedLocationId,\n              slot: time,\n              room: selectedExpert,\n              strDate: moment(date).format(\"D_M_yyyy\"),\n            });\n            setKey(\"complete\");\n            setProgress(3);\n          } catch (err) {\n            setError(\"e\");\n          }\n          setIsSubmitting(false);\n        };\n\n        \/* End Main Functions *\/\n\n        const renderMainForm = () => (\n          <Form\n            onSubmit={(e) => {\n              isRemoteService ||\n              isTelehealthCovidTest ||\n              isTelehealthConsultation\n                ? onSubmit(e, () => setMainFormTabKey(\"remoteDescription\"))\n                : onSubmit(e, onSearchLocation);\n            }}\n          >\n            <Row className=\"p-0\">\n              <DropDown\n                options={AppointmentReasons}\n                onChange={(e) => onChangeValue(e, setServiceType)}\n                value={serviceType}\n                Id=\"appointmentDropdown\"\n              \/>\n              {!isSinglePatientService && (\n                <DropDown\n                  options={NumberOfPeople}\n                  onChange={(e) => onChangeValue(e, setPatientCount)}\n                \/>\n              )}\n              {(isRemoteService || isTelehealthCovidTest || isTelehealthConsultation) && (\n                <DropDown\n                  options={LanguageOptions}\n                  value={language}\n                  onChange={(e) => {\n                    onChangeValue(e, setLanguage);\n                    localStorage.setItem('selectedLanguage', e.target.value);\n                  }}\n                \/>\n              )}\n              {!isRemoteService &&\n                !isTelehealthCovidTest &&\n                !isTelehealthConsultation && (\n                  <Col className=\"py-2\" md={4}>\n                    <PlacesInput\n                      onChange={(e) => onChangePlacesSearch(setLocation, e)}\n                      id=\"service-location\"\n                      required\n                      md={12}\n                    \/>\n                  <\/Col>\n                )}\n            <\/Row>\n            <div className=\"d-flex justify-content-end my-5\">\n              <Button\n                type=\"submit\"\n                className=\"button\"\n                id=\"searchLocationsButton\"\n              >\n                Suivant\n              <\/Button>\n            <\/div>\n            {showNoLocationSelectedError && (\n              <div className=\"text-start pr-2 text-danger h6\">\n                Veuillez choisir l'emplacement appropri\u00e9 dans l'option de\n                recherche.\n              <\/div>\n            )}\n            {isServiceNoteModalOpen && (\n              <Modal\n                isOpen={isServiceNoteModalOpen}\n                onClose={handleCloseServiceNote}\n                onCancel={handleCancelServiceNote}\n                onConfirm={handleConfirmServiceNote}\n                message={() => (\n                  <div>\n                    <div className=\"text-center mb-3\">\n                      <p>{servicePopups[selectedServiceNote].description()}<\/p>\n                    <\/div>\n\n                    <div className=\"text-start ps-3 pe-2\">\n                      {servicePopups[selectedServiceNote].checkboxes.map((label, idx) => (\n                        <Form.Check\n                          key={idx}\n                          type=\"checkbox\"\n                          label={label}\n                          checked={serviceNoteCheckboxes[idx]}\n                          onChange={e => {\n                            const upd = [...serviceNoteCheckboxes];\n                            upd[idx] = e.target.checked;\n                            setServiceNoteCheckboxes(upd);\n                          }}\n                          className=\"mb-2\"\n                        \/>\n                      ))}\n                    <\/div>\n\n                    {checkboxError && (\n                      <div className=\"text-danger mt-2\">\n                        {checkboxError}\n                      <\/div>\n                    )}\n                  <\/div>\n                )}\n                confirmButtonLabel=\"Confirmer\"\n                cancelButtonLabel=\"Annuler\"\n              \/>\n            )}\n            {isPrivateVaccineNoteModalOpen && (\n              <Modal\n                isOpen={isPrivateVaccineNoteModalOpen}\n                onClose={handleCloseServiceNote}\n                onCancel={handleCancelServiceNote}\n                onConfirm={handleConfirmServiceNote}\n                confirmButtonLabel=\"Ok\"\n                cancelButtonLabel=\"Cancel\"\n                message={() => servicePopups[\"Private Vaccine\"].description()}\n                showCancel={true}\n              \/>\n            )}\n          <\/Form>\n        );\n\n        function defaultTravelConsult() {\n          console.log(\"sending user to travel consult\");\n          setServiceType(\"Travel Consult\");\n          setPrivateVaccineNoteModalOpen(false);\n        }\n\n        const renderRemoteServiceDescription = () => (\n          <Form onSubmit={(e) => onSubmit(e, onSearchRemoteService)}>\n            <Row>\n              <DropDown\n                options={AppointmentReasons}\n                value={_.find(AppointmentReasons, { value: serviceType }).value}\n                disabled\n              \/>\n              <DropDown\n                options={NumberOfPeople}\n                value={\n                  _.find(NumberOfPeople, {\n                    value: patientCount,\n                  }).value\n                }\n                disabled\n              \/>\n              <DropDown\n                options={LanguageOptions}\n                value={language}\n                onChange={(e) => {\n                  setLanguage(e.target.value);\n                  localStorage.setItem(\"selectedLanguage\", e.target.value);\n                }}\n              \/>\n              <Col className=\"d-flex justify-content-end\">\n                <Button\n                  onClick={() => {\n                    setMainFormTabKey(\"main\");\n                  }}\n                  style={{\n                    backgroundColor: \"white\",\n                    color: \"#1e73be\",\n                    border: \"0px solid white\",\n                  }}\n                >\n                  S\u00e9lectionnez un autre test\n                <\/Button>\n              <\/Col>\n            <\/Row>\n            {isRemoteService && <RemoteServiceDescription \/>}\n            {isTelehealthCovidTest && <RemoteSupervisionServiceDescription \/>}\n            {isTelehealthConsultation && <RemoteConsultationDescription \/>}\n            <div className=\"d-flex justify-content-end my-5\">\n              <Button\n                className=\"button light mx-3\"\n                onClick={() => {\n                  setMainFormTabKey(\"main\");\n                }}\n              >\n                Retour\n              <\/Button>\n              <Button type=\"submit\" className=\"button\" disabled={!serviceId}>\n                R\u00e9servez maintenant\n              <\/Button>\n            <\/div>\n          <\/Form>\n        );\n\n        const renderMainFormTabs = () => (\n          <Tabs\n            id=\"controlled-tab3\"\n            activeKey={mainFormTabKey}\n            onSelect={(k) => setMainFormTabKey(k)}\n            className=\"border-0\"\n          >\n            <Tab eventKey=\"main\" title=\"Book\" disabled tabClassName=\"d-none\">\n              {renderMainForm()}\n            <\/Tab>\n            <Tab\n              eventKey=\"remoteDescription\"\n              title=\"Remote Service Description\"\n              disabled\n              tabClassName=\"d-none\"\n            >\n              {renderRemoteServiceDescription()}\n            <\/Tab>\n          <\/Tabs>\n        );\n\n        useEffect(() => {\n          async function checkRebookingStatus() {\n            if (contacts[0] && contacts[0].email && serviceId) {\n              try {\n                const duplicateResponse = await checkDuplicateAppointments({\n                  email: contacts[0].email,\n                  serviceId,\n                });\n\n                if (duplicateResponse.appointmentCount > 0) {\n                  console.log(\"Rendez-vous dupliqu\u00e9 existant :\", duplicateResponse);\n                  setIsRebooking(true);\n                }\n              } catch (err) {\n                console.error(\"Erreur lors de la v\u00e9rification des doublons :\", err);\n              }\n            }\n          }\n          checkRebookingStatus();\n        }, [contacts, serviceId]);\n\n        const renderLocationForm = () => {\n          const formattedDate = moment(date).format(\"dddd, MMM D\") || \"\";\n          const t = time.split(\"_\")[0] || \"\";\n\n          return (\n            <Container fluid>\n              {service && !isEditing && <ServiceInfo \/>}\n              {isEditing && <AppointmentInfo tab={\"location\"} \/>}\n              <div\n                className={\"sticky-top\"}\n                style={{\n                  zIndex:\n                    isSlotModalOpen ||\n                    isDateModalOpen ||\n                    isRescheduleFeeModalOpen\n                      ? 2\n                      : 10,\n                }}\n              >\n                <DatePicker\n                  selectedDate={date}\n                  onChange={onSelectDate}\n                  showDateModal={() => setIsDateModalOpen(true)}\n                  minDate={\n                    minDate\n                      ? minDate\n                      : datePickerMinDate\n                        ? datePickerMinDate.toDate()\n                        : null\n                  }\n                  maxDate={\n                    maxDate\n                      ? maxDate\n                      : datePickerMaxDate\n                        ? datePickerMaxDate.toDate()\n                        : null\n                  }\n                  disableNavigation={serviceType === \"TB Skin Test Reading\" || existingAppointment.serviceType === \"TB Skin Test Reading\" }\n                \/>\n              <\/div>\n              <Row className=\"py-3\">\n                <Col lg={12}>\n                  {locations.map((loc) => (\n                    <LocationMap\n                      location={loc}\n                      serviceId={serviceId}\n                      serviceType={serviceType}\n                      selectedDate={moment(date).format(\"D_M_yyyy\")}\n                      onSelectDate={setDate}\n                      onSelectSlot={onSelectSlot}\n                      selectedLocationId={selectedLocationId}\n                      selectedTime={time}\n                      key={loc.id}\n                      refetch={refetchSlots}\n                      isRemoteService={\n                        isRemoteService ||\n                        isTelehealthCovidTest ||\n                        isTelehealthConsultation\n                      }\n                      minDate={datePickerMinDate}\n                      maxDate={datePickerMaxDate}\n                      time={time}\n                      setIsFirstInitialTbConfirmed={\n                        setIsFirstInitialTbConfirmed\n                      }\n                      isFirstInitialTbConfirmed={isFirstInitialTbConfirmed}\n                      firstTbInitialAppointment={firstTbInitialAppointment}\n                      language={language} \n                    \/>\n                  ))}\n                <\/Col>\n              <\/Row>\n              <div className=\"d-flex justify-content-end my-4\">\n                {!params.aid && (\n                  <Button\n                    className=\"button mx-3\"\n                    onClick={() => {\n                      setKey(\"appointment\");\n                      setProgress(0);\n                      if (\n                        serviceId == \"a0X7V00000JljfjUAB\" ||\n                        serviceId == \"a0X7V00000JloBxUAJ\" ||\n                        serviceId == \"a0XOJ000002Ys6T2AS\"\n                      ) {\n                        setIsFirstInitialTbConfirmed(false);\n                        setSelectedInitialTbTestDate(null);\n                        setFirstTbInitialAppointment(null);\n                        setSecondTbInitialAppointment(null);\n                        setServiceType(\"TB Skin Test Initial Appointment\");\n                        AppointmentReasons = AppointmentReasons.filter(\n                          (appointment) =>\n                            appointment.value != \"TB Skin Test Reading\"\n                        );\n                      }\n                    }}\n                  >\n                    S\u00e9lectionnez un Autre Type de Rendez-vous\n                  <\/Button>\n                )}\n              <\/div>\n              <Modal\n                isOpen={isSlotModalOpen}\n                onConfirm={() => {\n                  if (\n                    serviceId == \"a0X7V00000JljfeUAB\" ||\n                    serviceId == \"a0X7V00000JljfjUAB\" ||\n                    serviceId == \"a0X7V00000JloC2UAJ\" ||\n                    serviceId == \"a0X7V00000JloBxUAJ\" ||\n                    serviceId == \"a0XOJ000002Ys1d2AC\" ||\n                    serviceId == \"a0XOJ000002Ys6T2AS\"\n                  ) {\n                    if (isEditing && existingAppointment && existingAppointment.serviceType === \"TB Skin Test Reading\") {\n                      setKey(\"confirm\");\n                      setProgress(2);\n                      window.scroll({ top: 0, left: 0, behavior: \"instant\" });\n                      return;\n                    }\n\n                    if (!firstTbInitialAppointment) {\n                      setSelectedInitialTbTestDate(moment(date));\n                      const currentService =\n                        serviceType &&\n                        _.find(AppointmentReasons, [\"value\", serviceType])\n                          .label;\n                      const loc = _.find(locations, [\"id\", selectedLocationId]);\n                      setFirstTbInitialAppointment({\n                        locationId: selectedLocationId,\n                        serviceId,\n                        slot: time,\n                        expertId: selectedExpert,\n                        date: moment(date).format(\"D_M_yyyy\"),\n                        language: \"French\",\n                        saveCreditCard,\n                        service: currentService,\n                        location: loc,\n                        amount: service.Pre_Payment_Price__c,\n                        discountAmount: getPromoParams().discountAmount,\n                      });\n                      setIsFirstInitialTbConfirmed(true);\n                      AppointmentReasons.push({\n                        label: \"TB Skin Test Reading\",\n                        value: \"TB Skin Test Reading\",\n                      });\n                      setServiceType(\"TB Skin Test Reading\");\n                      return;\n                    }\n                    if (!SecondTbInitialAppointment) {\n                      const currentService =\n                        serviceType &&\n                        _.find(AppointmentReasons, [\"value\", serviceType])\n                          .label;\n                      const loc = _.find(locations, [\"id\", selectedLocationId]);\n\n                      setSecondTbInitialAppointment({\n                        locationId: selectedLocationId,\n                        serviceId,\n                        slot: time,\n                        expertId: selectedExpert,\n                        date: moment(date).format(\"D_M_yyyy\"),\n                        language: \"French\",\n                        saveCreditCard,\n                        service: currentService,\n                        location: loc,\n                        amount: service.Pre_Payment_Price__c,\n                        discountAmount: getPromoParams().discountAmount,\n                      });\n                    }\n                    setKey(isEditing ? \"confirm\" : \"contact\");\n                    setProgress(2);\n                    window.scroll({ top: 0, left: 0, behavior: \"instant\" });\n                  } else {\n                    if (shouldShowRescheduleFeeOpen) {\n                      setIsRescheduleFeeModalOpen(true);\n                    } else {\n                      if (time) {\n                        setKey(isEditing ? \"confirm\" : \"contact\");\n                        setProgress(2);\n                        window.scroll({ top: 0, left: 0, behavior: \"instant\" });\n                      }\n                    }\n                  }\n                }}\n                onCancel={() => setIsSlotModalOpen(false)}  \n                onClose={() => setIsSlotModalOpen(false)}\n                message={() => {\n                  if (\n                    serviceType &&\n                    (serviceType == \"TB Skin Test Initial Appointment\" ||\n                      serviceType == \"TB Skin Test Reading\")\n                  ) {\n                    return (\n                      <span>\n                        Vous \u00eates maintenant sur le point de r\u00e9server votre{\" \"}\n                        <span style={{ fontWeight: \"bold\" }}>rendez-vous<\/span>{\" \"}\n                        <span className=\"text-danger\">{`${formattedDate} @ ${t}`}<\/span>{\" \"}\n                        as your{\" \"}\n                        {serviceType == \"TB Skin Test Initial Appointment\" ? (\n                          \"Initial TB Test Appointment Time\"\n                        ) : (\n                          <span>\n                            <span style={{ fontWeight: \"bold\" }}>\n                              Heure du rendez-vous de lecture TB\n                            <\/span>{\" \"}\n                            si vous ne trouvez aucune disponibilit\u00e9, veuillez\n                            cliquer{\" \"}\n                            <span style={{ fontWeight: \"bold\" }}>\"back\"<\/span>{\" \"}\n                            au bas de la page\n                          <\/span>\n                        )}\n                      <\/span>\n                    );\n                  } else {\n                    return (\n                      <span>\n                        Please confirm{\" \"}\n                        <span className=\"text-danger\">{`${formattedDate} @ ${t}`}<\/span>{\" \"}\n                        as your appointment time.\n                      <\/span>\n                    );\n                  }\n                }}\n              \/>\n              <Modal\n                isOpen={isDateModalOpen}\n                onConfirm={() => {\n                  setIsDateModalOpen(false);\n                }}\n                confirmButtonLabel=\"Ok\"\n                onCancel={() => setIsSlotModalOpen(false)}\n                onClose={() => setIsSlotModalOpen(false)}\n                message={() => (\n                  <span>\n                    Vous ne pouvez prendre rendez-vous que{\" \"}\n                    {datePickerMinDate &&\n                      datePickerMinDate.diff(moment(), \"days\") + 1}{\" \"}\n                    jours \u00e0 l'avance\n                  <\/span>\n                )}\n                showCancel={false}\n              \/>\n              <Modal\n                isOpen={isRescheduleFeeModalOpen}\n                onConfirm={() => {\n                  setKey(isEditing ? \"confirm\" : \"contact\");\n                  setProgress(2);\n                  window.scroll({ top: 0, left: 0, behavior: \"instant\" });\n                }}\n                confirmButtonLabel=\"Ok\"\n                onCancel={() => setIsRescheduleFeeModalOpen(false)}\n                onClose={() => setIsRescheduleFeeModalOpen(false)}\n                message={() => (\n                  <span>\n                    Veuillez noter que des frais seront appliqu\u00e9s pour reporter\n                    ce rendez-vous conform\u00e9ment \u00e0 notre politique de\n                    r\u00e9\u00e9chelonnement.\n                  <\/span>\n                )}\n                showCancel={false}\n              \/>\n            <\/Container>\n          );\n        };\n\n        const [tripErrors, setTripErrors] = useState({\n          selectedCountries: false,\n          departureDate: false,\n          returnDate: false,\n        });\n\n        const validateTripDetails = () => {\n          if (serviceType === \"TB Skin Test Reading\" ||\n            serviceType === \"TB Skin Test Initial Appointment\" ||\n            serviceType === \"Private Vaccine\" ||\n            serviceType === \"Booster\" ||\n            serviceType === \"Rapid Strep Test\" ||\n            serviceType === \"Cold Sore\" ||\n            serviceType === \"Blood Test\" ||\n            serviceType === \"Tick Bite Exposure\"  ) {\n            return true;\n          }\n\n          const errors = {\n            selectedCountries: selectedCountries.length === 0,\n            departureDate: !departureDate,\n            returnDate: !returnDate,\n          };\n\n          setTripErrors(errors);\n          return !Object.values(errors).includes(true);\n        };\n\n        const renderTripDetails = () => (\n          <div\n            className=\"text-start px-0 mx-0\"\n            style={{\n              borderTop: \"1px solid #CCCCCC\",\n              padding: \"20px 0\",\n            }}\n          >\n            <div className=\"fw-bold tip text-start\">\n              Entrez les d\u00e9tails du voyage\n            <\/div>\n            <DropDown\n              options={countryList}\n              onChange={(e) => {\n                handleSelectCountry(e.target.value);\n                setTripErrors((prevErrors) => ({ ...prevErrors, selectedCountries: false }));\n              }}\n              value={\"\"}\n              required={!selectedCountries.length}\n              labelparam=\"CountryNameFR\"\n              selectparam=\"Id\"\n              className={`my-3 ${tripErrors.selectedCountries ? \"error-border\" : \"\"}`}\n            \/>\n\n            {selectedCountries.map((id, index) => {\n              return (\n                <span\n                  className=\"chip\"\n                  style={{ border: \"1px solid #eeeeee \" }}\n                  key={index + id}\n                >\n                  {countriesById[id].CountryNameFR}\n                  <span\n                    className=\"closebtn\"\n                    onClick={() => handleSelectCountry(id)}\n                  >\n                    &times;\n                  <\/span>\n                <\/span>\n              );\n            })}\n            <Row className=\"pt-3\">\n              <DateInput\n                label=\"Date de d\u00e9part\"\n                id={\"date-leaving\"}\n                onChange={(e, { value }) => {\n                  setDepartureDate(value);\n                  setTripErrors((prevErrors) => ({ ...prevErrors, departureDate: false }));\n                }}\n                required\n                min={moment().format(\"YYYY-MM-DD\")}\n                md={5}\n                value={departureDate}\n                style={tripErrors.departureDate ? { border: \"2px solid rgb(214, 0, 0)\" } : {}}\n              \/>\n              <DateInput\n                label=\"Date de retour\"\n                id={\"date-returning\"}\n                onChange={(e, { value }) => {\n                  setReturnDate(value);\n                  setTripErrors((prevErrors) => ({ ...prevErrors, returnDate: false }));\n                }}\n                required\n                min={departureDate || moment().format(\"YYYY-MM-DD\")}\n                md={5}\n                value={returnDate}\n                style={tripErrors.returnDate ? { border: \"2px solid rgb(214, 0, 0)\" } : {}}\n              \/>\n            <\/Row>\n          <\/div>\n        );\n\n        const renderRequestedVaccines = () => (\n          <div\n            className=\"text-start px-0 mx-0\"\n            style={{\n              borderTop: \"1px solid #CCCCCC\",\n              padding: \"20px 0\",\n            }}\n          >\n            <div className=\"fw-bold tip text-start\">Vaccins demand\u00e9s<\/div>\n            <DropDown\n              options={vaccineList}\n              onChange={(e) => handleSelectVaccine(e.target.value)}\n              value={\"\"}\n              required={!selectedVaccines.length}\n              labelparam=\"name\"\n              selectparam=\"Id\"\n              className=\"my-3\"\n            \/>\n\n            {selectedVaccines.map((id, index) => {\n              return (\n                <span\n                  className=\"chip\"\n                  style={{ border: \"1px solid #eeeeee \" }}\n                  key={index + id}\n                >\n                  {vaccinesById[id].name}\n                  <span\n                    className=\"closebtn\"\n                    onClick={() => handleSelectVaccine(id)}\n                  >\n                    &times;\n                  <\/span>\n                <\/span>\n              );\n            })}\n          <\/div>\n        );\n\n        const renderShippingInfoSection = () => (\n          <div\n            className=\"text-start px-0 mx-0\"\n            style={{\n              borderTop: \"1px solid #CCCCCC\",\n              padding: \"20px 0\",\n            }}\n          >\n            <div className=\"fw-bold tip text-start\">\n              Enter Shipping Information\n            <\/div>\n            <Checkbox\n              label=\"Same as contact information\"\n              value={sameAsContactLocation}\n              onClick={(e) => setSameAsContactLocation(e.target.checked)}\n              defaultChecked\n            \/>\n            {!sameAsContactLocation && (\n              <PlacesForm\n                onChange={setShippingLocation}\n                id=\"shipping-location\"\n              \/>\n            )}\n            <Input\n              as=\"textarea\"\n              placeholder=\"Ajouter des instructions sp\u00e9ciales\"\n              id={\"specialInstructions\"}\n              md={8}\n              style={{ minHeight: \"140px\", maxHeight: \"180px\" }}\n              onChange={(e) => onChangeValue(e, setSpecialInstructions)}\n              required={false}\n            \/>\n          <\/div>\n        );\n\n        const renderPaymentSection = () => (\n          <div\n            className=\"text-start\"\n            style={{\n              borderTop: \"1px solid #CCCCCC\",\n              borderBottom: \"1px solid #CCCCCC\",\n              maxWidth: \"460px\",\n            }}\n          >\n            <div className=\"fw-bold pb-4 tip text-start\">\n              Saisir les informations de paiement\n            <\/div>\n            <div\n              className=\"fw-bold\"\n              style={{ fontSize: \"13px\", color: \"black\" }}\n            >\n              Utiliser un code\n            <\/div>\n            <div style={{ fontSize: \"13px\", color: \"grey\" }}>\n              Les codes peuvent \u00eatre fournis par une organisation ou offrir des r\u00e9ductions pour les rendez-vous\n            <\/div>\n            <div className=\"d-flex\">\n              <div style={{ width: \"250px\" }}>\n                <Input\n                  placeholder=\"Code\"\n                  id={\"promoCode\"}\n                  onChange={(e) => {\n                    const value = e.target.value;\n                    setPromoCode(value);\n                    if (value.trim() === \"\") {\n                      setPromoCodeError(\"\");\n                    }\n                  }}\n                  md={12}\n                  required={false}\n                  value={promoCode}\n                \/>\n              <\/div>\n              <Button\n                className=\"button align-self-center mx-3\"\n                onClick={validatePromo}\n                disabled={isValidatingPromoCode}\n              >\n                {isValidatingPromoCode ? \"Checking\" : \"Appliquer\"}\n              <\/Button>\n            <\/div>\n            {promoCodeError && promoCode.trim() !== \"\" && (\n              <div className=\"text-danger mb-3\">\n                Le code n'est pas valide\n              <\/div>\n            )}\n            {promoCodeData.Id && (\n              <div className=\"text-success mb-3\">\n                Promo de $\n                {(getPromoParams().discountAmount || 0).toFixed(2) || 0}{\" \"}\n                appliqu\u00e9e\n              <\/div>\n            )}\n            {!promoCodeData.Do_Not_Require_Prepayment__c && service.Pre_Payment_Price__c > 0 && (\n              <PaymentInputs\n                setPaymentData={setPaymentData}\n                shouldShowErrors={shouldShowPaymentErrors || shouldShowErrors}\n                dismissErrors={() => setShouldShowPaymentErrors(false)}\n              \/>\n            )}\n            {!promoCodeData.Do_Not_Require_Prepayment__c && service.Pre_Payment_Price__c > 0 && (\n              <Checkbox\n                label=\"Conservez en toute s\u00e9curit\u00e9 votre carte dans votre dossier patient. Important \u00e0 savoir: votre carte ne sera jamais d\u00e9bit\u00e9e sans votre autorisation\"\n                defaultChecked={true}\n                id={\"saveCreditCard\"}\n                onClick={(e) => {\n                  console.log(\n                    \"updating the saveCredit card with: \",\n                    e.target.checked\n                  );\n                  setSaveCreditCard(e.target.checked);\n                }}\n              \/>\n            )}\n          <\/div>\n        );\n\n        function isBelowMinAge(birthdate, appointmentDate, minMonths) {\n          if (typeof minMonths !== 'number') return false;\n          if (!birthdate || birthdate.length !== 10) return false; \/\/ Expect full date\n          \n          const birthMoment = moment(birthdate, \"YYYY-MM-DD\", true);\n          const appointmentMoment = moment(appointmentDate, \"YYYY-MM-DD\", true);\n        \n          if (!birthMoment.isValid() || !appointmentMoment.isValid()) {\n            return false; \/\/ Can't validate if dates aren't valid\n          }\n        \n          const requiredMinimumDate = birthMoment.clone().add(minMonths, 'months');\n        \n          \/\/ Appointment must be on or after required minimum date\n          return appointmentMoment.isBefore(requiredMinimumDate);\n        }\n\n        const isBelowSix = (birthdate, appointmentDate) => {\n          const birthDate = moment(birthdate);\n          const appointDate = moment(appointmentDate);\n          const diff = appointDate.diff(birthDate, \"months\");\n          return diff < 6;\n        };\n\n        const patientIsBelowSixMonths = (contacts) => {\n          return contacts.some((contact) => isBelowSix(contact.birthdate));\n        };\n\n        const [errorFields, setErrorFields] = useState([]);\n        const [validationErrors, setValidationErrors] = useState([]);\n        const [emptyFields, setEmptyFields] = useState([]);\n\n        const handleDateChange = (e, { value }, index) => {\n          const appointmentDate = moment(date).format('YYYY-MM-DD');\n          const minMonths = selectedReason.minimumAgeMonths || 6; \n          const belowMinAge = isBelowMinAge(value, date, minMonths);\n          \/\/ console.log(`[handleDateChange] patient #${index} \u2014 birthdate=${value}, appointmentDate=${appointmentDate}, isBelowSix=${minMonths}, isBelowMinAge(minMonths=${selectedReason.minimumAgeMonths})=${belowMinAge}`);\n  \n          const ageLabel =\n            minMonths >= 12\n              ? `${minMonths \/ 12} ans`\n              : `${minMonths} mois`;\n          \n              const reasonObj = AppointmentReasons.find(\n            r => r.value === serviceType\n          );\n\n          const errorText = reasonObj.minimunAgeText\n            || `Veuillez noter que nous n'acceptons pas de patients de moins de ${getAgeLabel(minMonths)} au moment du rendez-vous. Veuillez selectionner une date ult\u00e9rieure ou appeller le 1-888-224-8809 pour plus d'aide.`;\n\n          setEmptyFields((prev) => prev.filter((error) => !(error.index === index && error.field === \"birthdate\")));\n\n          setErrorFields((prevErrors) => {\n            if (value && belowMinAge) {\n              if (!prevErrors.includes(index)) {\n                Swal.fire({\n                  icon: \"error\",\n                  title: \"Oops...\",\n                  text: errorText,\n                  \/\/ text: `Veuillez noter que nous n'acceptons pas de patients de moins de ${ageLabel} au moment du rendez-vous. Veuillez selectionner une date ult\u00e9rieure ou appeller le 1-888-224-8809 pour plus d'aide.`,\n                });\n                return [...prevErrors, index];\n              }\n            } else {\n              return prevErrors.filter((i) => i !== index);\n            }\n            return prevErrors;\n          });\n\n          \/\/setErrorFields(newErrorFields);\n          onChangeContact({ target: { value } }, \"birthdate\", index);\n        };\n\n        const BirthDateDropdown = ({\n          value,\n          onChange,\n          minYear = 1900,\n          maxYear = new Date().getFullYear(),\n          required = true,\n          style = {},\n          hasError, \n        }) => {\n          const [day, setDay] = useState(\"\");\n          const [month, setMonth] = useState(\"\");\n          const [year, setYear] = useState(\"\");\n\n          useEffect(() => {\n            if (value) {\n              const [y, m, d] = value.split(\"-\");\n              setYear(y);\n              setMonth(m);\n              setDay(d);\n            }\n          }, [value]);\n\n          const generateDays = () => {\n            if (!year || !month) {\n              return Array.from({ length: 31 }, (_, i) =>\n                (i + 1).toString().padStart(2, \"0\")\n              );\n            }\n            const nbDays = new Date(year, month, 0).getDate();\n            return Array.from({ length: nbDays }, (_, i) =>\n              (i + 1).toString().padStart(2, \"0\")\n            );\n          };\n\n          const days = generateDays();\n          const months = Array.from({ length: 12 }, (_, i) =>\n            (i + 1).toString().padStart(2, \"0\")\n          );\n          const years = Array.from({ length: maxYear - minYear + 1 }, (_, i) =>\n            (maxYear - i).toString()\n          );\n\n          const handleChange = (newYear, newMonth, newDay) => {\n            const updatedValue = `${newYear}-${newMonth}-${newDay}`;\n            onChange(updatedValue);\n          };\n\n          const errorStyle = hasError ? { border: \"2px solid rgb(214, 0, 0)\" } : {};\n\n          return (\n            <div\n              className={`date-input-container ${hasError ? 'error-border' : ''}`}\n              style={{\n                display: \"flex\",\n                alignItems: \"center\",\n                gap: \"2px\",\n                margin: \"1rem 0\"\n              }}\n            >\n              <div className=\"birthdate-col-dd\" style={{flex: \"0 0 40%\"}}>\n                <Form.Select\n                  value={year}\n                  onChange={(e) => {\n                    setYear(e.target.value);\n                    handleChange(e.target.value, month, day);\n                  }}\n                  required={required}\n                  style={{\n                    height: \"47px\",\n                    borderRadius: \"2px\",\n                    backgroundColor: \"#FAFAFA\",\n                    width: \"100%\"\n                  }}\n                >\n                  <option value=\"\">AAAA<\/option>\n                  {years.map((y) => (\n                    <option key={y} value={y}>\n                      {y}\n                    <\/option>\n                  ))}\n                <\/Form.Select>\n              <\/div>\n              <div className=\"birthdate-col\" style={{flex: \"0 0 35%\" }}>\n                <Form.Select\n                  value={month}\n                  onChange={(e) => {\n                    setMonth(e.target.value);\n                    handleChange(year, e.target.value, day);\n                  }}\n                  required={required}\n                  style={{\n                    height: \"47px\",\n                    borderRadius: \"2px\",\n                    backgroundColor: \"#FAFAFA\",\n                    width: \"100%\"\n                  }}\n                >\n                  <option value=\"\">MM<\/option>\n                  {months.map((m) => (\n                    <option key={m} value={m}>\n                      {m}\n                    <\/option>\n                  ))}\n                <\/Form.Select>\n              <\/div>\n              <div className=\"birthdate-col\" style={{flex: \"0 0 35%\" }}>\n                <Form.Select\n                  value={day}\n                  onChange={(e) => {\n                    setDay(e.target.value);\n                    handleChange(year, month, e.target.value);\n                  }}\n                  required={required}\n                  style={{\n                    height: \"47px\",\n                    borderRadius: \"2px\",\n                    backgroundColor: \"#FAFAFA\",\n                    width: \"100%\"\n                  }}\n                >\n                  <option value=\"\">JJ<\/option>\n                  {days.map((d) => (\n                    <option key={d} value={d}>\n                      {d}\n                    <\/option>\n                  ))}\n                <\/Form.Select>\n              <\/div>\n            <\/div>\n          );\n        };\n\n        const validateForm = () => {\n          let errors = [];\n          let empty = [];\n\n          contacts.forEach((patient, index) => {\n            if (!patient.firstName) empty.push({ field: \"firstName\", index });\n            if (!patient.lastName) empty.push({ field: \"lastName\", index });\n            if (!patient.phone) empty.push({ field: \"phone\", index });\n            if (!patient.email) empty.push({ field: \"email\", index });\n            if (!patient.birthdate) empty.push({ field: \"birthdate\", index });\n            \/\/ if (patient.birthdate && isBelowSix(patient.birthdate, date)) errors.push(index);\n            if (patient.birthdate && isBelowMinAge(patient.birthdate, date, selectedReason.minimumAgeMonths)) errors.push(index);\n          });\n\n          setValidationErrors(errors);\n          setEmptyFields(empty);\n\n          if (errors.length > 0 || empty.length > 0) {\n            Swal.fire({\n              icon: \"warning\",\n              title: \"Erreur de validation\",\n              text: \"Veuillez remplir tous les champs obligatoires et corriger les erreurs avant de soumettre.\",\n            });\n            return false;\n          }\n          return true;\n        };\n\n        const [shouldShowErrors, setShouldShowErrors] = useState(false);\n\n        const handleSubmit = (e) => {\n          e.preventDefault();\n\n          setShouldShowErrors(true);\n\n          const isFormValid = validateForm(); \n          const isTripValid = validateTripDetails(); \n\n          if (validateForm() && isFormValid && isTripValid) {\n            onSubmit(e, onBeginBook);\n          }\n        };\n\n        const isFieldEmpty = (index, field) => {\n          return emptyFields.some((error) => error.index === index && error.field === field);\n        };\n\n        const getFieldStyle = (index, field) => {\n          if (errorFields.includes(index) && field === \"birthdate\") {\n            return { border: \"2px solid rgb(214, 0, 0)\" };\n          }\n          if (isFieldEmpty(index, field)) {\n            return { border: \"2px solid rgb(214, 0, 0)\" };\n          }\n          return {};\n        };\n\n        useEffect(() => {\n          const minMonths = selectedReason.minimumAgeMonths || 6;\n          const ageLabel =\n            minMonths >= 12\n              ? `${minMonths \/ 12} ans`\n              : `${minMonths} mois`;\n          const errors = contacts\n            .map((p, i) =>\n              p.birthdate && isBelowMinAge(p.birthdate, date, minMonths) ? i : null\n            )\n            .filter(i => i !== null);\n          setErrorFields(errors);\n        }, [contacts, date, selectedReason.minimumAgeMonths]);\n\n        const renderUsersForm = () => {\n          const minMonths = selectedReason.minimumAgeMonths || 6;\n          const ageLabel =\n            minMonths >= 12\n              ? `${minMonths \/ 12} ans`\n              : `${minMonths} mois`;\n          return (\n            <Form\n              onSubmit={handleSubmit}\n              className=\"pt-3\"\n            >\n              {contacts.map((patient, index) => (\n                <div className=\"pb-2\" key={index}>\n                  <div className=\"fw-bold pb-2 tip text-start\">\n                    Entrer les d\u00e9tails du patient {index + 1}:\n                  <\/div>\n                  <Row>\n                    <Input\n                      placeholder=\"Pr\u00e9nom\"\n                      id={\"firstName\" + index}\n                      onChange={(e) => {\n                        setEmptyFields((prev) => prev.filter((error) => !(error.index === index && error.field === \"firstName\")));\n                        onChangeContact(true, \"newsletter\", index);\n                        onChangeContact(e, \"firstName\", index);\n                      }}\n                      style={getFieldStyle(index, \"firstName\")}\n                    \/>\n                    <Input\n                      placeholder=\"Nom\"\n                      id={\"lastName\" + index}\n                      onChange={(e) => {\n                        setEmptyFields((prev) => prev.filter((error) => !(error.index === index && error.field === \"lastName\")));\n                        onChangeContact(e, \"lastName\", index)\n                      }}\n                      style={getFieldStyle(index, \"lastName\")}\n                    \/>\n                    <Input\n                      placeholder=\"Num\u00e9ro de t\u00e9l\u00e9phone\"\n                      id={\"phone-number\" + index}\n                      onChange={(e) => {\n                        setEmptyFields((prev) => prev.filter((error) => !(error.index === index && error.field === \"phone\")));\n                        onChangeContact(e, \"phone\", index)\n                      }}\n                      minLength={10}\n                      style={getFieldStyle(index, \"phone\")}\n                    \/>\n                    <Input\n                      placeholder=\"Courriel\"\n                      id={\"email\" + index}\n                      onChange={(e) => {\n                        setEmptyFields((prev) => prev.filter((error) => !(error.index === index && error.field === \"email\")));\n                        onChangeContact(e, \"email\", index)\n                      }}\n                      pattern=\"^[a-zA-Z0-9._%+\\-]+@(gmail\\.com|hotmail\\.(com|ca)|(?!gmail\\.|hotmail\\.)[a-zA-Z0-9.\\-]+\\.[a-zA-Z]{2,})$\"\n                      md={12}\n                      style={getFieldStyle(index, \"email\")}\n                    \/>\n                    {\/* <Input\n                        placeholder=\"Passport\"\n                        id={\"passport\" + index}\n                        onChange={(e) => onChangeContact(e, \"passport\", index)}\n                        required={false}\n                      *\/}\n                    <div className=\"input-container\">\n                      <div className=\"input-wrapper\">\n                        <Col md={4} className=\"my-3 text-start\">\n                          <label>Date de naissance<\/label>\n                          <div style={{ position: \"relative\" }}>\n                            <BirthDateDropdown\n                              value={contacts[index].birthdate}\n                              onChange={(newDateValue) => {\n                                handleDateChange(\n                                  { target: { value: newDateValue } },\n                                  { value: newDateValue },\n                                  index\n                                );\n\n                                onChangeContact({ target: { value: newDateValue } }, \"birthdate\", index);\n                              }}\n                              hasError={\n                                errorFields.includes(index) ||\n                                isFieldEmpty(index, \"birthdate\")\n                              }\n                            \/>\n                          <\/div>\n                          {errorFields.includes(index) && (\n                            <span className=\"error-message\">\n                              La date de naissance entr\u00e9e indique que le patient est \u00e2g\u00e9 de moins de {ageLabel}.\n                            <\/span>\n                          )}\n                        <\/Col>\n                      <\/div>\n                    <\/div>\n                    <Checkbox\n                      label=\"Abonnez-vous \u00e0  notre infolettre pour recevoir des promotions, des rabais et des nouvelles de Summit Health\"\n                      defaultChecked={false}\n                      id={\"newsletter\" + index}\n                      onClick={(e) => {\n                        onChangeContact(e.target.checked, \"newsletter\", index);\n                      }}\n                    \/>\n                    {isRemoteService && !index && (\n                      <PlacesForm onChange={setUserLocation} id=\"user-location\" \/>\n                    )}\n                  <\/Row>\n                <\/div>\n              ))}\n              {(isTravelConsult || (isTelehealthConsultation && !isTelehealthNonTravelConsultation && serviceType !== 'Tick Bite Exposure')) &&\n                renderTripDetails()}\n              {shouldShowVaccineSection && renderRequestedVaccines()}\n              {isRemoteService && renderShippingInfoSection()}\n              {renderPaymentSection()}\n              <TermsConditions \/>\n              <div className=\"d-flex justify-content-end my-4\">\n                <Button\n                  className=\"button light mx-3\"\n                  onClick={() => {\n                    setKey(\"location\");\n                    setProgress(1);\n                  }}\n                >\n                  Retour\n                <\/Button>\n                <Button\n                  type=\"submit\"\n                  className=\"button\"\n                  id=\"stripeButton\"\n                  disabled={isSubmitting}\n                  onClick={handleSubmit}\n                >\n                  Terminer la r\u00e9servation\n                <\/Button>\n              <\/div>\n              <Modal\n                isOpen={isBookingModalOpen}\n                onConfirm={onBook}\n                confirmButtonLabel={\n                  !promoCodeData.Do_Not_Require_Prepayment__c\n                    ? \"Suivant\"\n                    : \"Reserve\"\n                }\n                onCancel={() => setIsBookingModalOpen(false)}\n                onClose={() => setIsBookingModalOpen(false)}\n                message={() => (\n                  <span>\n                    Vous avez des rendez-vous incomplets. Vous pouvez compl\u00e9ter\n                    ceci r\u00e9servation ou contactez notre centre d'appels pour plus\n                    d'informations..\n                  <\/span>\n                )}\n              \/>\n            <\/Form>\n          );\n        };\n\n        const renderUserTab = (count) => {\n          const t = time.split(\"_\")[0];\n          const currentService =\n            serviceType &&\n            _.find(AppointmentReasons, [\"value\", serviceType]).label;\n          const countLabel = `${contacts.length} Person${\n            contacts.length > 1 ? \"s\" : \"\"\n          }`;\n          const loc = _.find(locations, [\"id\", selectedLocationId]);\n          const discountAmount = getPromoParams().discountAmount;\n          let servicePrepaymentPrice = discountAmount\n            ? Number(service.Pre_Payment_Price__c - discountAmount).toFixed(2)\n            : service.Pre_Payment_Price__c;\n          if (servicePrepaymentPrice < 0) {\n            servicePrepaymentPrice = 0;\n          }\n          return (\n            <Row>\n              <Col lg={4} className={`${isSubmitting &#038;&#038; \"d-none\"} order-lg-1`}>\n                {serviceId == \"a0X7V00000JljfeUAB\" ||\n                serviceId == \"a0X7V00000JljfjUAB\" ||\n                serviceId == \"a0X7V00000JloC2UAJ\" ||\n                serviceId == \"a0X7V00000JloBxUAJ\" ||\n                serviceId == \"a0XOJ000002Ys1d2AC\" ||\n                serviceId == \"a0XOJ000002Ys6T2AS\" ? (\n                  <div className=\"d-flex flex-column gap-3\">\n                    <Card className=\"text-start px-2 px-md-5 py-3 py-md-4\">\n                      <div className=\"fw-bold tip\">\n                        <i className=\"fas fa-calendar-alt\"><\/i> Informations sur\n                        le rendez-vous\n                      <\/div>\n                      <span>{`${\n                        firstTbInitialAppointment &&\n                        moment(\n                          firstTbInitialAppointment.slot,\n                          \"hh:mm A\"\n                        ).format(\"h:mm A\")\n                      }\n                                        ${\n                                          firstTbInitialAppointment &&\n                                          moment(\n                                            firstTbInitialAppointment.date,\n                                            \"D_M_YYYY\"\n                                          ).format(\"dddd, MMM D\")\n                                        }`}<\/span>\n                      <div>\n                        {firstTbInitialAppointment &&\n                          firstTbInitialAppointment.service}\n                      <\/div>\n                      <div>{countLabel}<\/div>\n                      <div className=\"fw-bold tip mt-3\">\n                        {\" \"}\n                        <i className=\"fas fa-map-marked-alt\"><\/i> Emplacement\n                      <\/div>\n                      {isRemoteService ||\n                      isTelehealthCovidTest ||\n                      isTelehealthConsultation ? (\n                        <div>Rendez-vous virtuel<\/div>\n                      ) : (\n                        <div>\n                          {firstTbInitialAppointment &&\n                            firstTbInitialAppointment.location &&\n                            firstTbInitialAppointment.location.name}\n                          <br><\/br>\n                          {firstTbInitialAppointment &&\n                            firstTbInitialAppointment.location &&\n                            firstTbInitialAppointment.location.street}\n                          ,{\" \"}\n                          {firstTbInitialAppointment &&\n                            firstTbInitialAppointment.location &&\n                            firstTbInitialAppointment.location.city}\n                          ,{\" \"}\n                          {firstTbInitialAppointment &&\n                            firstTbInitialAppointment.location &&\n                            firstTbInitialAppointment.location.province}\n                          ,{\" \"}\n                          {firstTbInitialAppointment &&\n                            firstTbInitialAppointment.location &&\n                            firstTbInitialAppointment.location.postalCode}\n                        <\/div>\n                      )}\n                      {!promoCodeData.Do_Not_Require_Prepayment__c && service.Pre_Payment_Price__c > 0 && (\n                        <div>\n                          <div className=\"fw-bold tip mt-3\">\n                            {\" \"}\n                            <i className=\"fas fa-dollar\"><\/i>Prix \u200b\u200bdes services\n                          <\/div>\n                          {firstTbInitialAppointment &&\n                            firstTbInitialAppointment.discountAmount > 0 && (\n                              <del>\n                                ${firstTbInitialAppointment.discountAmount}\n                              <\/del>\n                            )}{\" \"}\n                          <span\n                            style={{\n                              color:\n                                firstTbInitialAppointment &#038;&#038;\n                                firstTbInitialAppointment.discountAmount > 0\n                                  ? \"#1e73be\"\n                                  : \"#000\",\n                            }}\n                          >\n                            $\n                            {(firstTbInitialAppointment &&\n                              firstTbInitialAppointment.amount) ||\n                              0}\n                          <\/span>\n                        <\/div>\n                      )}\n                      {showEmail && (\n                        <div>\n                          <div className=\"fw-bold tip mt-3\">\n                            {\" \"}\n                            <i className=\"fas fa-at\"><\/i> E-mail\n                          <\/div>\n                          {contacts[0].email}\n                        <\/div>\n                      )}\n                      <div>\n                        <div className=\"fw-bold tip mt-3\">\n                          {\" \"}\n                          <i className=\"fas fa-envelope-open\"><\/i> Confirmation\n                        <\/div>\n                        Un email de confirmation sera envoy\u00e9 lorsque le\n                        rendez-vous sera pris\n                      <\/div>\n                    <\/Card>\n                    <Card className=\"text-start px-2 px-md-5 py-3 py-md-4\">\n                      <div className=\"fw-bold tip\">\n                        <i className=\"fas fa-calendar-alt\"><\/i> Informations sur\n                        le rendez-vous\n                      <\/div>\n                      <span>{`${\n                        SecondTbInitialAppointment &&\n                        moment(\n                          SecondTbInitialAppointment.slot,\n                          \"hh:mm A\"\n                        ).format(\"h:mm A\")\n                      }\n                                        ${\n                                          SecondTbInitialAppointment &&\n                                          moment(\n                                            SecondTbInitialAppointment.date,\n                                            \"D_M_YYYY\"\n                                          ).format(\"dddd, MMM D\")\n                                        }`}<\/span>\n                      <div>\n                        {SecondTbInitialAppointment &&\n                          SecondTbInitialAppointment.service}\n                      <\/div>\n                      <div>{countLabel}<\/div>\n                      <div className=\"fw-bold tip mt-3\">\n                        {\" \"}\n                        <i className=\"fas fa-map-marked-alt\"><\/i> Emplacement\n                      <\/div>\n                      {isRemoteService ||\n                      isTelehealthCovidTest ||\n                      isTelehealthConsultation ? (\n                        <div>Rendez-vous virtuel<\/div>\n                      ) : (\n                        <div>\n                          {SecondTbInitialAppointment &&\n                            SecondTbInitialAppointment.location &&\n                            SecondTbInitialAppointment.location.name}\n                          <br><\/br>\n                          {SecondTbInitialAppointment &&\n                            SecondTbInitialAppointment.location &&\n                            SecondTbInitialAppointment.location.street}\n                          ,{\" \"}\n                          {SecondTbInitialAppointment &&\n                            SecondTbInitialAppointment.location &&\n                            SecondTbInitialAppointment.location.city}\n                          ,{\" \"}\n                          {SecondTbInitialAppointment &&\n                            SecondTbInitialAppointment.location &&\n                            SecondTbInitialAppointment.location.province}\n                          ,{\" \"}\n                          {SecondTbInitialAppointment &&\n                            SecondTbInitialAppointment.location &&\n                            SecondTbInitialAppointment.location.postalCode}\n                        <\/div>\n                      )}\n                      {!promoCodeData.Do_Not_Require_Prepayment__c && service.Pre_Payment_Price__c > 0 && (\n                        <div>\n                          <div className=\"fw-bold tip mt-3\">\n                            {\" \"}\n                            <i className=\"fas fa-dollar\"><\/i>Prix \u200b\u200bdes services\n                          <\/div>\n                          {SecondTbInitialAppointment &&\n                            SecondTbInitialAppointment.discountAmount > 0 && (\n                              <del>\n                                ${SecondTbInitialAppointment.discountAmount}\n                              <\/del>\n                            )}{\" \"}\n                          <span\n                            style={{\n                              color:\n                                SecondTbInitialAppointment &#038;&#038;\n                                SecondTbInitialAppointment.discountAmount > 0\n                                  ? \"#1e73be\"\n                                  : \"#000\",\n                            }}\n                          >\n                            $\n                            {(SecondTbInitialAppointment &&\n                              SecondTbInitialAppointment.amount) ||\n                              0}\n                          <\/span>\n                        <\/div>\n                      )}\n                      {showEmail && (\n                        <div>\n                          <div className=\"fw-bold tip mt-3\">\n                            {\" \"}\n                            <i className=\"fas fa-at\"><\/i> E-mail\n                          <\/div>\n                          {contacts[0].email}\n                        <\/div>\n                      )}\n                      <div>\n                        <div className=\"fw-bold tip mt-3\">\n                          {\" \"}\n                          <i className=\"fas fa-envelope-open\"><\/i> Confirmation\n                        <\/div>\n                        Un email de confirmation sera envoy\u00e9 lorsque le\n                        rendez-vous sera pris\n                      <\/div>\n                    <\/Card>\n                  <\/div>\n                ) : (\n                  <Card className=\"text-start px-2 px-md-5 py-3 py-md-4\">\n                    <div className=\"fw-bold tip\">\n                      <i className=\"fas fa-calendar-alt\"><\/i> Informations sur\n                      le rendez-vous\n                    <\/div>\n                    <span>{`${moment(t, \"hh:mm A\").format(\"h:mm A\")}\n                                        ${moment(date).format(\n                                          \"dddd, MMM D\"\n                                        )}`}<\/span>\n                    <div>{currentService}<\/div>\n                    <div>{countLabel}<\/div>\n                    <div className=\"fw-bold tip mt-3\">\n                      {\" \"}\n                      <i className=\"fas fa-map-marked-alt\"><\/i> Emplacement\n                    <\/div>\n                    {isRemoteService ||\n                    isTelehealthCovidTest ||\n                    isTelehealthConsultation ? (\n                      <div>Rendez-vous virtuel\n                        <br \/>\n                        <div>Langue: {language === \"english\" ? \"Anglais\" : \"Fran\u00e7ais\"}<\/div>\n                      <\/div>\n                    ) : (\n                      <div>\n                        {loc && loc.name}\n                        <br><\/br>\n                        {loc && loc.street}, {loc && loc.city},{\" \"}\n                        {loc && loc.province}, {loc && loc.postalCode}\n                      <\/div>\n                    )}\n                    {!promoCodeData.Do_Not_Require_Prepayment__c && service.Pre_Payment_Price__c > 0 && (\n                      <div>\n                        <div className=\"fw-bold tip mt-3\">\n                          {\" \"}\n                          <i className=\"fas fa-dollar\"><\/i>Prix \u200b\u200bdes services\n                        <\/div>\n                        {discountAmount > 0 && (\n                          <del>${service.Pre_Payment_Price__c}<\/del>\n                        )}{\" \"}\n                        <span\n                          style={{\n                            color: discountAmount > 0 ? \"#1e73be\" : \"#000\",\n                          }}\n                        >\n                          ${servicePrepaymentPrice || 0}\n                        <\/span>\n                      <\/div>\n                    )}\n                    {showEmail && (\n                      <div>\n                        <div className=\"fw-bold tip mt-3\">\n                          {\" \"}\n                          <i className=\"fas fa-at\"><\/i> E-mail\n                        <\/div>\n                        {contacts[0].email}\n                      <\/div>\n                    )}\n                    <div>\n                      <div className=\"fw-bold tip mt-3\">\n                        {\" \"}\n                        <i className=\"fas fa-envelope-open\"><\/i> Confirmation\n                      <\/div>\n                      Un email de confirmation sera envoy\u00e9 lorsque le\n                      rendez-vous sera pris\n                    <\/div>\n                  <\/Card>\n                )}\n              <\/Col>\n              <Col lg={8} className={`${isSubmitting &#038;&#038; \"d-none\"}`}>\n                {renderUsersForm(Number(patientCount))}\n              <\/Col>\n              {isSubmitting && (\n                <div className=\"py-5 my-3\">\n                  <LoadingView \/>\n                <\/div>\n              )}\n              <Modal\n                isOpen={slotNotAvailableModalOpen}\n                onConfirm={() => {\n                  setKey(\"location\");\n                  setProgress(1);\n                  setRefetchSlots(!refetchSlots);\n                  window.scroll({ top: 0, left: 0, behavior: \"instant\" });\n                }}\n                confirmButtonLabel=\"Ok\"\n                onCancel={() => setSlotNotAvailableModalOpen(false)}\n                onClose={() => setSlotNotAvailableModalOpen(false)}\n                message={() => (\n                  <span>\n                    cette heure de rendez-vous est d\u00e9j\u00e0 prise, veuillez\n                    s\u00e9lectionner une autre fois\n                  <\/span>\n                )}\n                showCancel={false}\n              \/>\n            <\/Row>\n          );\n        };\n\n        const ServiceInfo = () => {\n          return (\n            <Card\n              className=\"text-start mb-3 rescheduleDiv\"\n              style={{ padding: \"50px 40px\" }}\n            >\n              <Row>\n                <Col md={9} className=\"service-info\">\n                  <div className=\"book\">Nom du service<\/div>\n                  <div className=\"rescheduleText\">{service.Name_French__c}<\/div>\n                  <div className=\"book pt-3\">Description du service<\/div>\n                  <div className=\"rescheduleText\">\n                    {service.Description_French__c}\n                  <\/div>\n                <\/Col>\n                <Col md={3} className=\"px-lg-5 px-md-3 pt-3 pt-md-0\">\n                  <div>\n                    <div className=\"book\">Prix des services<\/div>\n                    <div className=\"rescheduleText\">\n                      ${service.Service_Price__c || 0}\n                    <\/div>\n                  <\/div>\n                  {!promoCodeData.Do_Not_Require_Prepayment__c && service.Pre_Payment_Price__c > 0 && (\n                    <div>\n                      <div className=\"book pt-3\">Prix de pr\u00e9paiement<\/div>\n                      <div className=\"rescheduleText\">\n                        ${service.Pre_Payment_Price__c || 0}\n                      <\/div>\n                    <\/div>\n                  )}\n                <\/Col>\n              <\/Row>\n            <\/Card>\n          );\n        };\n\n        const AppointmentInfo = ({ tab }) => {\n          const t = time.split(\"_\")[0];\n          const loc = _.find(locations, [\"id\", selectedLocationId]);\n          const isConfirm = tab === \"confirm\";\n          return (\n            <Card className=\"text-start px-2 pb-3 mb-3 rescheduleDiv\">\n              {isConfirm ? (\n                <div className=\"book\">\n                  Confirmez vos nouvelles informations de rendez-vous{\" \"}\n                <\/div>\n              ) : (\n                <div>\n                  <div className=\"book\">\n                    Reprogrammez votre rendez-vous existant\n                  <\/div>\n                  <div className=\"rescheduleText\">\n                    Veuillez s\u00e9lectionner un cr\u00e9neau horaire ci-dessous pour\n                    modifier l'heure ou le lieu de votre rendez-vous\n                  <\/div>\n                <\/div>\n              )}\n              <Row>\n                <Col sm={6}>\n                  <div className=\"fw-bold tip mt-3\">\n                    {\" \"}\n                    <i className=\"fas fa-calendar-alt\"><\/i> Informations sur le\n                    rendez-vous\n                  <\/div>\n                  {isConfirm ? (\n                    <span>{`${moment(t, \"hh:mm A\").format(\"h:mm A\")}\n                                  ${moment(date).format(\"dddd, MMM D\")}`}<\/span>\n                  ) : (\n                    <span>\n                      {moment(existingAppointment.startTime).format(\n                        \"h:mm A dddd, MMM D\"\n                      )}\n                    <\/span>\n                  )}\n                  <div>{existingAppointment.serviceType}<\/div>\n                <\/Col>\n                {!isRemoteService &&\n                  !isTelehealthCovidTest &&\n                  !isTelehealthConsultation && (\n                    <Col sm={6}>\n                      <div className=\"fw-bold tip mt-3\">\n                        <i className=\"fas fa-map-marked-alt\"><\/i> Location\n                      <\/div>\n                      <div>\n                        {isConfirm\n                          ? loc && loc.name\n                          : existingAppointment.locationName}\n                      <\/div>\n                    <\/Col>\n                  )}\n              <\/Row>\n            <\/Card>\n          );\n        };\n\n        const renderConfirmScheduling = () => {\n          return (\n            <Form\n              onSubmit={(e) => {\n                onSubmit(e, onReschedule);\n              }}\n              className=\"pt-3\"\n            >\n              <AppointmentInfo tab=\"confirm\" \/>\n              <div className=\"d-flex justify-content-end my-4\">\n                <Button\n                  className=\"button light mx-3\"\n                  onClick={() => {\n                    setKey(\"location\");\n                    setProgress(1);\n                  }}\n                >\n                  Retour\n                <\/Button>\n                <Button\n                  type=\"submit\"\n                  className=\"button\"\n                  disabled={isSubmitting}\n                >\n                  Confirmer\n                <\/Button>\n              <\/div>\n            <\/Form>\n          );\n        };\n\n        const renderAppointmentName = () => (\n          <div>\n            {bookResponse.Id && (\n              <ReactBootstrap.Card className=\"text-start px-2 py-3 mb-3\">\n                <div className=\"fw-bold tip mb-3\" id=\"appointmentSuccessDiv\">\n                  Votre rendez-vous a \u00e9t\u00e9 pris avec succ\u00e8s !\n                <\/div>\n                {\/**<div className=\"text-sm tip text-start\">\n                      Id: {bookResponse.Id}\n                    <\/div>\n                    **\/}\n                <div className=\"text-sm tip text-start\">\n                  Num\u00e9ro de rendez-vous: {bookResponse.appointmentName}\n                <\/div>\n                <div className=\"text-sm tip text-start\">\n                  Courriel: {bookResponse.appointmentEmail}\n                <\/div>\n              <\/ReactBootstrap.Card>\n            )}\n            {params.aid && (\n              <div className=\"text-sm tip text-start mb-3\">\n                Votre r\u00e9servation a \u00e9t\u00e9 mise \u00e0 jour.\n              <\/div>\n            )}\n          <\/div>\n        );\n        const renderAppointmentCompleteCard = () => {\n          const t = time.split(\"_\")[0] || \"\";\n          const userAddress = userLocation && getFormattedAddress(userLocation);\n          const shippingAddress = sameAsContactLocation\n            ? userAddress\n            : shippingLocation && getFormattedAddress(shippingLocation);\n          const { discountAmount, totalPaidAmount } = getPromoParams();\n          let tagManagerValue =\n            totalPaidAmount || service.Service_Price__c || 0;\n          window.dataLayer = window.dataLayer || [];\n          window.dataLayer.push({\n            appointmentTotal: tagManagerValue,\n          });\n          console.log(\n            \"finished pushing total paid amount to the datalayer\" +\n              tagManagerValue\n          );\n          return isRemoteService && !isEditing ? (\n            <Card className=\"text-start mb-3\" style={{ padding: \"25px 35px\" }}>\n              <div\n                className=\"fs-3 book fw-bold\"\n                id=\"remoteAppointmentConfirmation\"\n              >\n                Rendez-vous confirm\u00e9\n              <\/div>\n              <div className=\"py-3\">\n                Votre kit de test virtuel a \u00e9t\u00e9 command\u00e9. Vous recevrez un\n                notification par e-mail une fois qu'il a \u00e9t\u00e9 exp\u00e9di\u00e9 \u00e0 l'adresse\n                au dessous de. Nous vous enverrons \u00e9galement un e-mail de\n                confirmation avec votre informations de rendez-vous, y compris\n                le lien de chat vid\u00e9o.\n              <\/div>\n              <Row>\n                <Col md={3} className=\"py-3\">\n                  <div className=\"book fw-bold\">Coordonn\u00e9es<\/div>\n                  <div>\n                    {contacts[0].firstName} {contacts[0].lastName}\n                  <\/div>\n                  <div>{userAddress}<\/div>\n                  <div className=\"pt-3\">{contacts[0].email}<\/div>\n                <\/Col>\n                <Col md={3} className=\"py-3\">\n                  <div className=\"book fw-bold\">\n                    Informations sur la livraison\n                  <\/div>\n                  <div>\n                    {contacts[0].firstName} {contacts[0].lastName}\n                  <\/div>\n                  <div>{shippingAddress}<\/div>\n                  <div className=\"pt-3\">{contacts[0].email}<\/div>\n                <\/Col>\n                <Col md={3} className=\"py-3\">\n                  <div className=\"book fw-bold\">Rendez-Vous<\/div>\n                  <span>{`${moment(t, \"hh:mm A\").format(\"h:mm A\")}\n                                  ${moment(date).format(\"dddd, MMM D\")}`}<\/span>\n                  <div style={{ fontSize: \"13px\" }}>\n                    Les informations sur la visioconf\u00e9rence vous seront envoy\u00e9es\n                    par e-mail\n                  <\/div>\n                <\/Col>\n                <Col md={3} className=\"py-3\">\n                  <div className=\"book fw-bold\">Prix Service<\/div>\n                  <div>${service.Service_Price__c || 0}<\/div>\n                  {discountAmount > 0 && (\n                    <div className=\"pt-3\">\n                      <div className=\"book fw-bold\">montant de la remise <\/div>\n                      <div>${discountAmount}<\/div>\n                    <\/div>\n                  )}\n                  <div className=\"book fw-bold pt-3\">Prix Total<\/div>\n                  <div>${totalPaidAmount || service.Service_Price__c || 0}<\/div>\n                <\/Col>\n              <\/Row>\n            <\/Card>\n          ) : (\n            <div>\n              {bookResponse.Id && (\n                <Card className=\"text-start px-2 py-3 mb-3\">\n                  <div className=\"fw-bold tip mb-3\" id=\"appointmentSuccessDiv\">\n                    Votre rendez-vous a \u00e9t\u00e9 pris avec succ\u00e8s !\n                  <\/div>\n                  {\/**<div className=\"text-sm tip text-start\">\n                            Id: {bookResponse.Id}\n                          <\/div>\n                          **\/}\n                  <div className=\"text-sm tip text-start\">\n                    Numero Confirmation: {bookResponse.appointmentName}\n                  <\/div>\n                  <div className=\"text-sm tip text-start\">\n                    Courriel: {bookResponse.appointmentEmail}\n                  <\/div>\n                  <div className=\"my-2\">\n                    <Button\n                      className=\"button\"\n                      href={bookResponse.questionnaireURL}\n                      target=\"_self\"\n                    >\n                      Veuillez remplir votre questionnaire\n                    <\/Button>\n                  <\/div>\n                <\/Card>\n              )}\n              {params.aid && (\n                <div className=\"text-sm tip text-start mb-3\">\n                  Votre r\u00e9servation a \u00e9t\u00e9 mise \u00e0 jour.\n                <\/div>\n              )}\n            <\/div>\n          );\n        };\n        const showError = error || paymentError;\n\n        const renderPageHeader = () =>\n          isRemoteService && key !== \"appointment\" ? (\n            <HeaderUtil\n              title={\"Achetez Votre Test Virtuel\"}\n              renderSubtitle={renderRemoteHeaderSubtitle}\n            \/>\n          ) : (\n            <HeaderUtil\n              title={\"Prenez rendez-vous en ligne\"}\n              renderSubtitle={() => (\n                <div>\n                  <div\n                    className=\"mt-4 text-start border-1 pb-3\"\n                    style={{ borderBottom: \"1px solid #CCCCCC\" }}\n                  >\n                    {isEditing ? (\n                      <span className=\"text-sm-end tip\">\n                        Informations sur le rendez-vous:\n                      <\/span>\n                    ) : (\n                      renderDefaultHeaderSubtitle()\n                    )}\n                  <\/div>\n                <\/div>\n              )}\n            \/>\n          );\n        return (\n          <Container fluid className=\"container-sm text-center App\">\n            {isLoadingAppointment ? (\n              <LoadingView \/>\n            ) : (\n              <div>\n                {renderPageHeader()}\n                <div>\n                  {key !== \"appointment\" && !isEditing && (\n                    <StyledProgressBar\n                      labels={\n                        isRemoteService\n                          ? ONLINE_PROGRESS_LABELS\n                          : STANDARD_PROGRESS_LABELS\n                      }\n                      progress={progress}\n                    \/>\n                  )}\n                  <Tabs\n                    id=\"controlled-tab-example\"\n                    activeKey={key}\n                    onSelect={(k) => setKey(k)}\n                    className=\"mb-3 border-0\"\n                  >\n                    <Tab\n                      eventKey=\"appointment\"\n                      title=\"Appointment\"\n                      disabled\n                      tabClassName=\"d-none\"\n                    >\n                      {renderMainFormTabs()}\n                      {isLoadingLocations && <LoadingView \/>}\n                    <\/Tab>\n                    <Tab\n                      eventKey=\"location\"\n                      title=\"Location\"\n                      disabled\n                      tabClassName=\"d-none\"\n                    >\n                      {!!locations.length && renderLocationForm()}\n                    <\/Tab>\n                    {isEditing ? (\n                      <Tab\n                        eventKey={\"confirm\"}\n                        title=\"confirm\"\n                        disabled\n                        tabClassName=\"d-none\"\n                      >\n                        {renderConfirmScheduling()}\n                        {isSubmitting && <LoadingView \/>}\n                      <\/Tab>\n                    ) : (\n                      <Tab\n                        eventKey={\"contact\"}\n                        title=\"Contact\"\n                        disabled\n                        tabClassName=\"d-none\"\n                      >\n                        {renderUserTab()}\n                      <\/Tab>\n                    )}\n                    <Tab\n                      eventKey=\"complete\"\n                      title=\"Complete\"\n                      disabled\n                      tabClassName=\"d-none\"\n                    >\n                      {key === \"complete\" ? (\n                        <div>\n                          {renderAppointmentCompleteCard()}\n                          {!isEditing && (\n                            <div className=\"d-flex justify-content-end my-4\">\n                              <Button\n                                className=\"button\"\n                                onClick={() => window.location.reload()}\n                              >\n                                R\u00e9server un autre test\n                              <\/Button>\n                            <\/div>\n                          )}\n                        <\/div>\n                      ) : (\n                        <div \/>\n                      )}\n                    <\/Tab>\n                  <\/Tabs>\n                <\/div>\n              <\/div>\n            )}\n            {showError && (\n              <ErrorView\n                error={paymentError || error}\n                showErrorMessage={paymentError}\n              \/>\n            )}\n          <\/Container>\n        );\n      };\n      const App = () => <SummitHealth \/>;\n\n      ReactDOM.render(<App \/>, document.getElementById(\"book-form\"));\n    <\/script>\n  <\/body>\n<\/html>\n\n\n\n\n<script>\ndocument.addEventListener(\"DOMContentLoaded\", function () {\nconsole.log(\"page loaded, setting root var\");\n    \/\/ Access the root element\n    const root = document.documentElement;\n    \n    \/\/ Set the --base-3 variable to white (#FFFFFF)\n    root.style.setProperty(\"--base-3\", \"#FFFFFF\");\n});\n<\/script>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-1654","page","type-page","status-publish"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Prendre rendez-vous - Summit Health<\/title>\n<meta name=\"description\" content=\"Prenez rendez-vous dans une clinique Summit Health au Qu\u00e9bec ou en Ontario pour des services de sant\u00e9 rapides et pratiques.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/summithealth.ca\/fr\/prendre-rendez-vous\/\" \/>\n<meta property=\"og:locale\" content=\"fr_FR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Prendre rendez-vous - Summit Health\" \/>\n<meta property=\"og:description\" content=\"Prenez rendez-vous dans une clinique Summit Health au Qu\u00e9bec ou en Ontario pour des services de sant\u00e9 rapides et pratiques.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/summithealth.ca\/fr\/prendre-rendez-vous\/\" \/>\n<meta property=\"og:site_name\" content=\"Summit Health\" \/>\n<meta property=\"article:modified_time\" content=\"2025-04-29T13:03:18+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/summithealth.ca\\\/fr\\\/prendre-rendez-vous\\\/\",\"url\":\"https:\\\/\\\/summithealth.ca\\\/fr\\\/prendre-rendez-vous\\\/\",\"name\":\"Prendre rendez-vous - Summit Health\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/summithealth.ca\\\/fr\\\/#website\"},\"datePublished\":\"2024-08-01T15:19:18+00:00\",\"dateModified\":\"2025-04-29T13:03:18+00:00\",\"description\":\"Prenez rendez-vous dans une clinique Summit Health au Qu\u00e9bec ou en Ontario pour des services de sant\u00e9 rapides et pratiques.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/summithealth.ca\\\/fr\\\/prendre-rendez-vous\\\/#breadcrumb\"},\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/summithealth.ca\\\/fr\\\/prendre-rendez-vous\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/summithealth.ca\\\/fr\\\/prendre-rendez-vous\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/summithealth.ca\\\/fr\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Prendre rendez-vous\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/summithealth.ca\\\/fr\\\/#website\",\"url\":\"https:\\\/\\\/summithealth.ca\\\/fr\\\/\",\"name\":\"Summit Health\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/summithealth.ca\\\/fr\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/summithealth.ca\\\/fr\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"fr-FR\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/summithealth.ca\\\/fr\\\/#organization\",\"name\":\"Summit Health\",\"url\":\"https:\\\/\\\/summithealth.ca\\\/fr\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"https:\\\/\\\/summithealth.ca\\\/fr\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/summithealth.ca\\\/wp-content\\\/uploads\\\/2024\\\/07\\\/logo_trimmed.png\",\"contentUrl\":\"https:\\\/\\\/summithealth.ca\\\/wp-content\\\/uploads\\\/2024\\\/07\\\/logo_trimmed.png\",\"width\":312,\"height\":312,\"caption\":\"Summit Health\"},\"image\":{\"@id\":\"https:\\\/\\\/summithealth.ca\\\/fr\\\/#\\\/schema\\\/logo\\\/image\\\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Prendre rendez-vous - Summit Health","description":"Prenez rendez-vous dans une clinique Summit Health au Qu\u00e9bec ou en Ontario pour des services de sant\u00e9 rapides et pratiques.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/summithealth.ca\/fr\/prendre-rendez-vous\/","og_locale":"fr_FR","og_type":"article","og_title":"Prendre rendez-vous - Summit Health","og_description":"Prenez rendez-vous dans une clinique Summit Health au Qu\u00e9bec ou en Ontario pour des services de sant\u00e9 rapides et pratiques.","og_url":"https:\/\/summithealth.ca\/fr\/prendre-rendez-vous\/","og_site_name":"Summit Health","article_modified_time":"2025-04-29T13:03:18+00:00","twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/summithealth.ca\/fr\/prendre-rendez-vous\/","url":"https:\/\/summithealth.ca\/fr\/prendre-rendez-vous\/","name":"Prendre rendez-vous - Summit Health","isPartOf":{"@id":"https:\/\/summithealth.ca\/fr\/#website"},"datePublished":"2024-08-01T15:19:18+00:00","dateModified":"2025-04-29T13:03:18+00:00","description":"Prenez rendez-vous dans une clinique Summit Health au Qu\u00e9bec ou en Ontario pour des services de sant\u00e9 rapides et pratiques.","breadcrumb":{"@id":"https:\/\/summithealth.ca\/fr\/prendre-rendez-vous\/#breadcrumb"},"inLanguage":"fr-FR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/summithealth.ca\/fr\/prendre-rendez-vous\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/summithealth.ca\/fr\/prendre-rendez-vous\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/summithealth.ca\/fr\/"},{"@type":"ListItem","position":2,"name":"Prendre rendez-vous"}]},{"@type":"WebSite","@id":"https:\/\/summithealth.ca\/fr\/#website","url":"https:\/\/summithealth.ca\/fr\/","name":"Summit Health","description":"","publisher":{"@id":"https:\/\/summithealth.ca\/fr\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/summithealth.ca\/fr\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"fr-FR"},{"@type":"Organization","@id":"https:\/\/summithealth.ca\/fr\/#organization","name":"Summit Health","url":"https:\/\/summithealth.ca\/fr\/","logo":{"@type":"ImageObject","inLanguage":"fr-FR","@id":"https:\/\/summithealth.ca\/fr\/#\/schema\/logo\/image\/","url":"https:\/\/summithealth.ca\/wp-content\/uploads\/2024\/07\/logo_trimmed.png","contentUrl":"https:\/\/summithealth.ca\/wp-content\/uploads\/2024\/07\/logo_trimmed.png","width":312,"height":312,"caption":"Summit Health"},"image":{"@id":"https:\/\/summithealth.ca\/fr\/#\/schema\/logo\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/summithealth.ca\/fr\/wp-json\/wp\/v2\/pages\/1654","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/summithealth.ca\/fr\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/summithealth.ca\/fr\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/summithealth.ca\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/summithealth.ca\/fr\/wp-json\/wp\/v2\/comments?post=1654"}],"version-history":[{"count":8,"href":"https:\/\/summithealth.ca\/fr\/wp-json\/wp\/v2\/pages\/1654\/revisions"}],"predecessor-version":[{"id":1988,"href":"https:\/\/summithealth.ca\/fr\/wp-json\/wp\/v2\/pages\/1654\/revisions\/1988"}],"wp:attachment":[{"href":"https:\/\/summithealth.ca\/fr\/wp-json\/wp\/v2\/media?parent=1654"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}